Merge pull request #10324 from jarvte/more_info_from_stm

Cellular: new state machine state and better info from stm
pull/10019/head
Cruz Monrreal 2019-04-09 11:05:48 -05:00 committed by GitHub
commit 2cb157c949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 103 additions and 53 deletions

View File

@ -118,12 +118,12 @@ TEST_F(TestCellularDevice, test_set_sim_ready)
CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK; CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK;
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_OK); ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_OK);
CellularStateMachine_stub::get_current_current_state = STATE_MANUAL_REGISTERING_NETWORK; CellularStateMachine_stub::get_current_current_state = STATE_REGISTERING_NETWORK;
CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK; CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK;
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_ALREADY); ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_ALREADY);
CellularStateMachine_stub::bool_value = true; CellularStateMachine_stub::bool_value = true;
CellularStateMachine_stub::get_current_target_state = STATE_MANUAL_REGISTERING_NETWORK; CellularStateMachine_stub::get_current_target_state = STATE_REGISTERING_NETWORK;
CellularStateMachine_stub::get_current_current_state = STATE_POWER_ON; CellularStateMachine_stub::get_current_current_state = STATE_POWER_ON;
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_IN_PROGRESS); ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_IN_PROGRESS);
delete dev; delete dev;

View File

@ -33,6 +33,7 @@ enum UT_CellularState {
UT_STATE_POWER_ON, UT_STATE_POWER_ON,
UT_STATE_DEVICE_READY, UT_STATE_DEVICE_READY,
UT_STATE_SIM_PIN, UT_STATE_SIM_PIN,
UT_STATE_SIGNAL_QUALITY,
UT_STATE_REGISTERING_NETWORK, UT_STATE_REGISTERING_NETWORK,
UT_STATE_ATTACHING_NETWORK, UT_STATE_ATTACHING_NETWORK,
UT_STATE_MAX_FSM_STATE UT_STATE_MAX_FSM_STATE

View File

@ -24,8 +24,8 @@ enum CellularStubState {
STATE_POWER_ON, STATE_POWER_ON,
STATE_DEVICE_READY, STATE_DEVICE_READY,
STATE_SIM_PIN, STATE_SIM_PIN,
STATE_SIGNAL_QUALITY,
STATE_REGISTERING_NETWORK, STATE_REGISTERING_NETWORK,
STATE_MANUAL_REGISTERING_NETWORK,
STATE_ATTACHING_NETWORK, STATE_ATTACHING_NETWORK,
STATE_MAX_FSM_STATE STATE_MAX_FSM_STATE
}; };

View File

@ -72,6 +72,9 @@ public:
virtual CellularNetwork *open_network(FileHandle *fh = NULL) virtual CellularNetwork *open_network(FileHandle *fh = NULL)
{ {
if (_network) {
return _network;
}
EventQueue que; EventQueue que;
FileHandle_stub fh1; FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ","); ATHandler at(&fh1, que, 0, ",");

View File

@ -196,7 +196,7 @@ nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOper
tr_warning("No cellular connection"); tr_warning("No cellular connection");
return NSAPI_ERROR_TIMEOUT; return NSAPI_ERROR_TIMEOUT;
} }
return NSAPI_ERROR_OK; return _cb_data.error;// callback might have been completed with an error, must return that error here
} }
} }
@ -932,11 +932,11 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
} }
#endif // USE_APN_LOOKUP #endif // USE_APN_LOOKUP
if (!_nw && st == CellularDeviceReady && data->error == NSAPI_ERROR_OK) { if (!_nw && st == CellularDeviceReady && _cb_data.error == NSAPI_ERROR_OK) {
_nw = _device->open_network(_fh); _nw = _device->open_network(_fh);
} }
if (_cp_req && !_cp_in_use && (data->error == NSAPI_ERROR_OK) && if (_cp_req && !_cp_in_use && (_cb_data.error == NSAPI_ERROR_OK) &&
(st == CellularSIMStatusChanged && data->status_data == CellularDevice::SimStateReady)) { (st == CellularSIMStatusChanged && data->status_data == CellularDevice::SimStateReady)) {
if (setup_control_plane_opt() != NSAPI_ERROR_OK) { if (setup_control_plane_opt() != NSAPI_ERROR_OK) {
tr_error("Control plane SETUP failed!"); tr_error("Control plane SETUP failed!");
@ -946,7 +946,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
} }
if (_is_blocking) { if (_is_blocking) {
if (data->error != NSAPI_ERROR_OK) { if (_cb_data.error != NSAPI_ERROR_OK) {
// operation failed, release semaphore // operation failed, release semaphore
_current_op = OP_INVALID; _current_op = OP_INVALID;
_semaphore.release(); _semaphore.release();
@ -971,7 +971,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
} }
} else { } else {
// non blocking // non blocking
if (st == CellularAttachNetwork && _current_op == OP_CONNECT && data->error == NSAPI_ERROR_OK && if (st == CellularAttachNetwork && _current_op == OP_CONNECT && _cb_data.error == NSAPI_ERROR_OK &&
data->status_data == CellularNetwork::Attached) { data->status_data == CellularNetwork::Attached) {
_current_op = OP_INVALID; _current_op = OP_INVALID;
// forward to application // forward to application

View File

@ -27,12 +27,23 @@ struct cell_callback_data_t {
nsapi_error_t error; /* possible error code */ nsapi_error_t error; /* possible error code */
int status_data; /* cellular_event_status related enum or other info in int format. Check cellular_event_status comments.*/ int status_data; /* cellular_event_status related enum or other info in int format. Check cellular_event_status comments.*/
bool final_try; /* This flag is true if state machine is used and this was the last try. State machine does goes to idle. */ bool final_try; /* This flag is true if state machine is used and this was the last try. State machine does goes to idle. */
const void *data; /* possible extra data in any form. Format specified in cellular_connection_status_t per event if any. */
cell_callback_data_t() cell_callback_data_t()
{ {
error = NSAPI_ERROR_OK; error = NSAPI_ERROR_OK;
status_data = -1; status_data = -1;
final_try = false; final_try = false;
data = NULL;
}
};
struct cell_signal_quality_t {
int rssi; /* received signal strength */
int ber; /* channel bit error rate */
cell_signal_quality_t()
{
rssi = -1;
ber = -1;
} }
}; };
@ -51,6 +62,9 @@ typedef enum cellular_event_status {
CellularRadioAccessTechnologyChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 5, /* Network roaming status have changed. cell_callback_data_t.status_data will be enum RadioAccessTechnology See enum RadioAccessTechnology in ../API/CellularNetwork.h*/ CellularRadioAccessTechnologyChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 5, /* Network roaming status have changed. cell_callback_data_t.status_data will be enum RadioAccessTechnology See enum RadioAccessTechnology in ../API/CellularNetwork.h*/
CellularAttachNetwork = NSAPI_EVENT_CELLULAR_STATUS_BASE + 6, /* cell_callback_data_t.status_data will be enum AttachStatus. See enum AttachStatus in ../API/CellularNetwork.h */ CellularAttachNetwork = NSAPI_EVENT_CELLULAR_STATUS_BASE + 6, /* cell_callback_data_t.status_data will be enum AttachStatus. See enum AttachStatus in ../API/CellularNetwork.h */
CellularActivatePDPContext = NSAPI_EVENT_CELLULAR_STATUS_BASE + 7, /* NSAPI_ERROR_OK in cell_callback_data_t.error on successfully PDP Context activated or negative error */ CellularActivatePDPContext = NSAPI_EVENT_CELLULAR_STATUS_BASE + 7, /* NSAPI_ERROR_OK in cell_callback_data_t.error on successfully PDP Context activated or negative error */
CellularSignalQuality = NSAPI_EVENT_CELLULAR_STATUS_BASE + 8, /* cell_callback_data_t.error will contains return value when signal quality was queried. data will hold the pointer to cell_signal_quality struct. See possible values from ../API/CellularNetwork.h*/
CellularStateRetryEvent = NSAPI_EVENT_CELLULAR_STATUS_BASE + 9, /* cell_callback_data_t.error contain an error if any. cell_callback_data_t.status_data contains cellular_event_status and it specifies the operation which is retried.
cellular_event_status.data contains current retrycount */
} cellular_connection_status_t; } cellular_connection_status_t;
#endif // CELLULAR_COMMON_ #endif // CELLULAR_COMMON_

View File

@ -182,8 +182,13 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularC
{ {
if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) { if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) {
cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr; cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr;
tr_debug("callback: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev; cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev;
if (cell_ev == CellularStateRetryEvent) {
tr_debug("callback: CellularStateRetryEvent, err: %d, data: %d, retrycount: %d", ptr_data->error, ptr_data->status_data, *(const int *)ptr_data->data);
} else {
tr_debug("callback: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
}
if (cell_ev == CellularRegistrationStatusChanged && _state_machine) { if (cell_ev == CellularRegistrationStatusChanged && _state_machine) {
// broadcast only network registration changes to state machine // broadcast only network registration changes to state machine
_state_machine->cellular_event_changed(ev, ptr); _state_machine->cellular_event_changed(ev, ptr);

View File

@ -47,7 +47,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state), _cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
_event_status_cb(0), _network(nw), _queue(queue), _queue_thread(0), _sim_pin(0), _event_status_cb(0), _network(nw), _queue(queue), _queue_thread(0), _sim_pin(0),
_retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false), _retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
_is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE), _status(0) _is_retry(false), _cb_data(), _current_event(CellularDeviceReady), _status(0)
{ {
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0 #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
_start_time = 0; _start_time = 0;
@ -133,10 +133,8 @@ bool CellularStateMachine::open_sim()
} }
// report current state so callback can set sim pin if needed // report current state so callback can set sim pin if needed
if (_event_status_cb) { _cb_data.status_data = state;
_cb_data.status_data = state; send_event_cb(CellularSIMStatusChanged);
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&_cb_data);
}
if (state == CellularDevice::SimStatePinNeeded) { if (state == CellularDevice::SimStatePinNeeded) {
if (_sim_pin) { if (_sim_pin) {
@ -156,13 +154,10 @@ bool CellularStateMachine::open_sim()
bool sim_ready = state == CellularDevice::SimStateReady; bool sim_ready = state == CellularDevice::SimStateReady;
if (sim_ready) { if (sim_ready) {
// If plmn is set, we should it right after sim is opened so that registration is forced to correct network. _cb_data.error = _network.set_registration(_plmn);
if (_plmn && strlen(_plmn)) { tr_debug("STM: set_registration: %d, plmn: %s", _cb_data.error, _plmn);
_cb_data.error = _network.set_registration(_plmn); if (_cb_data.error) {
tr_debug("STM: manual set_registration: %d, plmn: %s", _cb_data.error, _plmn); return false;
if (_cb_data.error) {
return false;
}
} }
} }
@ -250,10 +245,8 @@ void CellularStateMachine::report_failure(const char *msg)
tr_error("CellularStateMachine failure: %s", msg); tr_error("CellularStateMachine failure: %s", msg);
_event_id = -1; _event_id = -1;
if (_event_status_cb) { _cb_data.final_try = true;
_cb_data.final_try = true; send_event_cb(_current_event);
_event_status_cb(_current_event, (intptr_t)&_cb_data);
}
tr_error("CellularStateMachine target state %s, current state %s", get_state_string(_target_state), get_state_string(_state)); tr_error("CellularStateMachine target state %s, current state %s", get_state_string(_target_state), get_state_string(_state));
} }
@ -261,7 +254,7 @@ void CellularStateMachine::report_failure(const char *msg)
const char *CellularStateMachine::get_state_string(CellularState state) const const char *CellularStateMachine::get_state_string(CellularState state) const
{ {
#if MBED_CONF_MBED_TRACE_ENABLE #if MBED_CONF_MBED_TRACE_ENABLE
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network"}; static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Signal quality", "Registering network", "Attaching network"};
return strings[state]; return strings[state];
#else #else
return NULL; return NULL;
@ -282,12 +275,17 @@ void CellularStateMachine::retry_state_or_fail()
{ {
if (++_retry_count < CELLULAR_RETRY_ARRAY_SIZE) { if (++_retry_count < CELLULAR_RETRY_ARRAY_SIZE) {
tr_debug("%s: retry %d/%d", get_state_string(_state), _retry_count, CELLULAR_RETRY_ARRAY_SIZE); tr_debug("%s: retry %d/%d", get_state_string(_state), _retry_count, CELLULAR_RETRY_ARRAY_SIZE);
// send info to application/driver about error logic so it can implement proper error logic
_cb_data.status_data = _current_event;
_cb_data.data = &_retry_count;
_cb_data.error = NSAPI_ERROR_OK;
send_event_cb(CellularStateRetryEvent);
_event_timeout = _retry_timeout_array[_retry_count]; _event_timeout = _retry_timeout_array[_retry_count];
_is_retry = true; _is_retry = true;
_cb_data.error = NSAPI_ERROR_OK; _cb_data.error = NSAPI_ERROR_OK;
} else { } else {
report_failure(get_state_string(_state)); report_failure(get_state_string(_state));
return;
} }
} }
@ -334,9 +332,7 @@ bool CellularStateMachine::device_ready()
} }
#endif // MBED_CONF_CELLULAR_DEBUG_AT #endif // MBED_CONF_CELLULAR_DEBUG_AT
if (_event_status_cb) { send_event_cb(CellularDeviceReady);
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t)&_cb_data);
}
_cellularDevice.set_ready_cb(0); _cellularDevice.set_ready_cb(0);
return true; return true;
@ -402,12 +398,25 @@ void CellularStateMachine::state_sim_pin()
} else if (_cb_data.error) { } else if (_cb_data.error) {
tr_warning("Packet domain event reporting set failed!"); tr_warning("Packet domain event reporting set failed!");
} }
enter_to_state(STATE_REGISTERING_NETWORK); enter_to_state(STATE_SIGNAL_QUALITY);
} else { } else {
retry_state_or_fail(); retry_state_or_fail();
} }
} }
void CellularStateMachine::state_signal_quality()
{
_cb_data.error = _network.get_signal_quality(_signal_quality.rssi, &_signal_quality.ber);
if (_cb_data.error != NSAPI_ERROR_OK) {
retry_state_or_fail();
} else {
_cb_data.data = &_signal_quality;
send_event_cb(_current_event);
enter_to_state(STATE_REGISTERING_NETWORK);
}
}
void CellularStateMachine::state_registering() void CellularStateMachine::state_registering()
{ {
_cellularDevice.set_timeout(TIMEOUT_NETWORK); _cellularDevice.set_timeout(TIMEOUT_NETWORK);
@ -419,7 +428,7 @@ void CellularStateMachine::state_registering()
_cb_data.status_data = CellularNetwork::AlreadyRegistered; _cb_data.status_data = CellularNetwork::AlreadyRegistered;
} }
_cb_data.error = NSAPI_ERROR_OK; _cb_data.error = NSAPI_ERROR_OK;
_event_status_cb(_current_event, (intptr_t)&_cb_data); send_event_cb(_current_event);
// we are already registered, go to attach // we are already registered, go to attach
enter_to_state(STATE_ATTACHING_NETWORK); enter_to_state(STATE_ATTACHING_NETWORK);
} else { } else {
@ -440,10 +449,8 @@ void CellularStateMachine::state_attaching()
_cb_data.error = _network.set_attach(); _cb_data.error = _network.set_attach();
} }
if (_cb_data.error == NSAPI_ERROR_OK) { if (_cb_data.error == NSAPI_ERROR_OK) {
if (_event_status_cb) { _cb_data.status_data = CellularNetwork::Attached;
_cb_data.status_data = CellularNetwork::Attached; send_event_cb(_current_event);
_event_status_cb(_current_event, (intptr_t)&_cb_data);
}
} else { } else {
retry_state_or_fail(); retry_state_or_fail();
} }
@ -524,43 +531,51 @@ bool CellularStateMachine::get_current_status(CellularStateMachine::CellularStat
void CellularStateMachine::event() void CellularStateMachine::event()
{ {
#if MBED_CONF_MBED_TRACE_ENABLE // Don't send Signal quality when in signal quality state or it can confuse callback functions when running retry logic
int rssi; if (_state != STATE_SIGNAL_QUALITY) {
if (_network.get_signal_quality(rssi) == NSAPI_ERROR_OK) { _cb_data.error = _network.get_signal_quality(_signal_quality.rssi, &_signal_quality.ber);
if (rssi == CellularNetwork::SignalQualityUnknown) { _cb_data.data = &_signal_quality;
tr_info("RSSI unknown");
} else { if (_cb_data.error == NSAPI_ERROR_OK) {
tr_info("RSSI %d dBm", rssi); send_event_cb(CellularSignalQuality);
if (_signal_quality.rssi == CellularNetwork::SignalQualityUnknown) {
tr_info("RSSI unknown");
} else {
tr_info("RSSI %d dBm", _signal_quality.rssi);
}
} }
} }
#endif
_event_timeout = -1; _event_timeout = -1;
_is_retry = false; _is_retry = false;
switch (_state) { switch (_state) {
case STATE_INIT: case STATE_INIT:
_current_event = (nsapi_event_t)CellularDeviceReady; _current_event = CellularDeviceReady;
state_init(); state_init();
break; break;
case STATE_POWER_ON: case STATE_POWER_ON:
_current_event = (nsapi_event_t)CellularDeviceReady; _current_event = CellularDeviceReady;
state_power_on(); state_power_on();
break; break;
case STATE_DEVICE_READY: case STATE_DEVICE_READY:
_current_event = (nsapi_event_t)CellularDeviceReady; _current_event = CellularDeviceReady;
state_device_ready(); state_device_ready();
break; break;
case STATE_SIM_PIN: case STATE_SIM_PIN:
_current_event = (nsapi_event_t)CellularSIMStatusChanged; _current_event = CellularSIMStatusChanged;
state_sim_pin(); state_sim_pin();
break; break;
case STATE_SIGNAL_QUALITY:
_current_event = CellularSignalQuality;
state_signal_quality();
break;
case STATE_REGISTERING_NETWORK: case STATE_REGISTERING_NETWORK:
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged; _current_event = CellularRegistrationStatusChanged;
state_registering(); state_registering();
break; break;
case STATE_ATTACHING_NETWORK: case STATE_ATTACHING_NETWORK:
_current_event = (nsapi_event_t)CellularAttachNetwork; _current_event = CellularAttachNetwork;
state_attaching(); state_attaching();
break; break;
default: default:
@ -612,6 +627,13 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
_event_status_cb = status_cb; _event_status_cb = status_cb;
} }
void CellularStateMachine::send_event_cb(cellular_connection_status_t status)
{
if (_event_status_cb) {
_event_status_cb((nsapi_event_t)status, (intptr_t)&_cb_data);
}
}
bool CellularStateMachine::check_is_target_reached() bool CellularStateMachine::check_is_target_reached()
{ {
if (((_target_state == _state || _target_state < _next_state) && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || if (((_target_state == _state || _target_state < _next_state) && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) ||
@ -629,7 +651,8 @@ bool CellularStateMachine::check_is_target_reached()
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr) void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
{ {
cell_callback_data_t *data = (cell_callback_data_t *)ptr; cell_callback_data_t *data = (cell_callback_data_t *)ptr;
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) { if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && (
_state == STATE_REGISTERING_NETWORK || _state == STATE_SIGNAL_QUALITY)) {
// expect packet data so only these states are valid // expect packet data so only these states are valid
CellularNetwork::registration_params_t reg_params; CellularNetwork::registration_params_t reg_params;
nsapi_error_t err = _network.get_registration_params(reg_params); nsapi_error_t err = _network.get_registration_params(reg_params);

View File

@ -56,6 +56,7 @@ private:
STATE_POWER_ON, STATE_POWER_ON,
STATE_DEVICE_READY, STATE_DEVICE_READY,
STATE_SIM_PIN, STATE_SIM_PIN,
STATE_SIGNAL_QUALITY,
STATE_REGISTERING_NETWORK, STATE_REGISTERING_NETWORK,
STATE_ATTACHING_NETWORK, STATE_ATTACHING_NETWORK,
STATE_MAX_FSM_STATE STATE_MAX_FSM_STATE
@ -144,6 +145,7 @@ private:
void state_power_on(); void state_power_on();
void state_device_ready(); void state_device_ready();
void state_sim_pin(); void state_sim_pin();
void state_signal_quality();
void state_registering(); void state_registering();
void state_attaching(); void state_attaching();
void enter_to_state(CellularState state); void enter_to_state(CellularState state);
@ -154,6 +156,7 @@ private:
void device_ready_cb(); void device_ready_cb();
void pre_event(CellularState state); void pre_event(CellularState state);
bool check_is_target_reached(); bool check_is_target_reached();
void send_event_cb(cellular_connection_status_t status);
CellularDevice &_cellularDevice; CellularDevice &_cellularDevice;
CellularState _state; CellularState _state;
@ -178,9 +181,10 @@ private:
bool _command_success; bool _command_success;
bool _is_retry; bool _is_retry;
cell_callback_data_t _cb_data; cell_callback_data_t _cb_data;
nsapi_event_t _current_event; cellular_connection_status_t _current_event;
int _status; int _status;
PlatformMutex _mutex; PlatformMutex _mutex;
cell_signal_quality_t _signal_quality;
}; };
} // namespace } // namespace