Skip to content

Commit 2cb157c

Browse files
author
Cruz Monrreal
authored
Merge pull request #10324 from jarvte/more_info_from_stm
Cellular: new state machine state and better info from stm
2 parents fba8156 + 8234f00 commit 2cb157c

File tree

9 files changed

+103
-53
lines changed

9 files changed

+103
-53
lines changed

UNITTESTS/features/cellular/framework/device/cellulardevice/cellulardevicetest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ TEST_F(TestCellularDevice, test_set_sim_ready)
118118
CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK;
119119
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_OK);
120120

121-
CellularStateMachine_stub::get_current_current_state = STATE_MANUAL_REGISTERING_NETWORK;
121+
CellularStateMachine_stub::get_current_current_state = STATE_REGISTERING_NETWORK;
122122
CellularStateMachine_stub::nsapi_error_value = NSAPI_ERROR_OK;
123123
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_ALREADY);
124124

125125
CellularStateMachine_stub::bool_value = true;
126-
CellularStateMachine_stub::get_current_target_state = STATE_MANUAL_REGISTERING_NETWORK;
126+
CellularStateMachine_stub::get_current_target_state = STATE_REGISTERING_NETWORK;
127127
CellularStateMachine_stub::get_current_current_state = STATE_POWER_ON;
128128
ASSERT_EQ(dev->set_sim_ready(), NSAPI_ERROR_IN_PROGRESS);
129129
delete dev;

UNITTESTS/features/cellular/framework/device/cellularstatemachine/cellularstatemachinetest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ enum UT_CellularState {
3333
UT_STATE_POWER_ON,
3434
UT_STATE_DEVICE_READY,
3535
UT_STATE_SIM_PIN,
36+
UT_STATE_SIGNAL_QUALITY,
3637
UT_STATE_REGISTERING_NETWORK,
3738
UT_STATE_ATTACHING_NETWORK,
3839
UT_STATE_MAX_FSM_STATE

UNITTESTS/stubs/CellularStateMachine_stub.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ enum CellularStubState {
2424
STATE_POWER_ON,
2525
STATE_DEVICE_READY,
2626
STATE_SIM_PIN,
27+
STATE_SIGNAL_QUALITY,
2728
STATE_REGISTERING_NETWORK,
28-
STATE_MANUAL_REGISTERING_NETWORK,
2929
STATE_ATTACHING_NETWORK,
3030
STATE_MAX_FSM_STATE
3131
};

UNITTESTS/target_h/myCellularDevice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class myCellularDevice : public CellularDevice {
7272

7373
virtual CellularNetwork *open_network(FileHandle *fh = NULL)
7474
{
75+
if (_network) {
76+
return _network;
77+
}
7578
EventQueue que;
7679
FileHandle_stub fh1;
7780
ATHandler at(&fh1, que, 0, ",");

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOper
196196
tr_warning("No cellular connection");
197197
return NSAPI_ERROR_TIMEOUT;
198198
}
199-
return NSAPI_ERROR_OK;
199+
return _cb_data.error;// callback might have been completed with an error, must return that error here
200200
}
201201
}
202202

@@ -932,11 +932,11 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
932932
}
933933
#endif // USE_APN_LOOKUP
934934

935-
if (!_nw && st == CellularDeviceReady && data->error == NSAPI_ERROR_OK) {
935+
if (!_nw && st == CellularDeviceReady && _cb_data.error == NSAPI_ERROR_OK) {
936936
_nw = _device->open_network(_fh);
937937
}
938938

939-
if (_cp_req && !_cp_in_use && (data->error == NSAPI_ERROR_OK) &&
939+
if (_cp_req && !_cp_in_use && (_cb_data.error == NSAPI_ERROR_OK) &&
940940
(st == CellularSIMStatusChanged && data->status_data == CellularDevice::SimStateReady)) {
941941
if (setup_control_plane_opt() != NSAPI_ERROR_OK) {
942942
tr_error("Control plane SETUP failed!");
@@ -946,7 +946,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
946946
}
947947

948948
if (_is_blocking) {
949-
if (data->error != NSAPI_ERROR_OK) {
949+
if (_cb_data.error != NSAPI_ERROR_OK) {
950950
// operation failed, release semaphore
951951
_current_op = OP_INVALID;
952952
_semaphore.release();
@@ -971,7 +971,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
971971
}
972972
} else {
973973
// non blocking
974-
if (st == CellularAttachNetwork && _current_op == OP_CONNECT && data->error == NSAPI_ERROR_OK &&
974+
if (st == CellularAttachNetwork && _current_op == OP_CONNECT && _cb_data.error == NSAPI_ERROR_OK &&
975975
data->status_data == CellularNetwork::Attached) {
976976
_current_op = OP_INVALID;
977977
// forward to application

features/cellular/framework/common/CellularCommon.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,23 @@ struct cell_callback_data_t {
2727
nsapi_error_t error; /* possible error code */
2828
int status_data; /* cellular_event_status related enum or other info in int format. Check cellular_event_status comments.*/
2929
bool final_try; /* This flag is true if state machine is used and this was the last try. State machine does goes to idle. */
30-
30+
const void *data; /* possible extra data in any form. Format specified in cellular_connection_status_t per event if any. */
3131
cell_callback_data_t()
3232
{
3333
error = NSAPI_ERROR_OK;
3434
status_data = -1;
3535
final_try = false;
36+
data = NULL;
37+
}
38+
};
39+
40+
struct cell_signal_quality_t {
41+
int rssi; /* received signal strength */
42+
int ber; /* channel bit error rate */
43+
cell_signal_quality_t()
44+
{
45+
rssi = -1;
46+
ber = -1;
3647
}
3748
};
3849

@@ -51,6 +62,9 @@ typedef enum cellular_event_status {
5162
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*/
5263
CellularAttachNetwork = NSAPI_EVENT_CELLULAR_STATUS_BASE + 6, /* cell_callback_data_t.status_data will be enum AttachStatus. See enum AttachStatus in ../API/CellularNetwork.h */
5364
CellularActivatePDPContext = NSAPI_EVENT_CELLULAR_STATUS_BASE + 7, /* NSAPI_ERROR_OK in cell_callback_data_t.error on successfully PDP Context activated or negative error */
65+
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*/
66+
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.
67+
cellular_event_status.data contains current retrycount */
5468
} cellular_connection_status_t;
5569

5670
#endif // CELLULAR_COMMON_

features/cellular/framework/device/CellularDevice.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,13 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularC
182182
{
183183
if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) {
184184
cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr;
185-
tr_debug("callback: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
186185
cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev;
186+
if (cell_ev == CellularStateRetryEvent) {
187+
tr_debug("callback: CellularStateRetryEvent, err: %d, data: %d, retrycount: %d", ptr_data->error, ptr_data->status_data, *(const int *)ptr_data->data);
188+
} else {
189+
tr_debug("callback: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
190+
}
191+
187192
if (cell_ev == CellularRegistrationStatusChanged && _state_machine) {
188193
// broadcast only network registration changes to state machine
189194
_state_machine->cellular_event_changed(ev, ptr);

features/cellular/framework/device/CellularStateMachine.cpp

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event
4747
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
4848
_event_status_cb(0), _network(nw), _queue(queue), _queue_thread(0), _sim_pin(0),
4949
_retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
50-
_is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE), _status(0)
50+
_is_retry(false), _cb_data(), _current_event(CellularDeviceReady), _status(0)
5151
{
5252
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
5353
_start_time = 0;
@@ -133,10 +133,8 @@ bool CellularStateMachine::open_sim()
133133
}
134134

135135
// report current state so callback can set sim pin if needed
136-
if (_event_status_cb) {
137-
_cb_data.status_data = state;
138-
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&_cb_data);
139-
}
136+
_cb_data.status_data = state;
137+
send_event_cb(CellularSIMStatusChanged);
140138

141139
if (state == CellularDevice::SimStatePinNeeded) {
142140
if (_sim_pin) {
@@ -156,13 +154,10 @@ bool CellularStateMachine::open_sim()
156154
bool sim_ready = state == CellularDevice::SimStateReady;
157155

158156
if (sim_ready) {
159-
// If plmn is set, we should it right after sim is opened so that registration is forced to correct network.
160-
if (_plmn && strlen(_plmn)) {
161-
_cb_data.error = _network.set_registration(_plmn);
162-
tr_debug("STM: manual set_registration: %d, plmn: %s", _cb_data.error, _plmn);
163-
if (_cb_data.error) {
164-
return false;
165-
}
157+
_cb_data.error = _network.set_registration(_plmn);
158+
tr_debug("STM: set_registration: %d, plmn: %s", _cb_data.error, _plmn);
159+
if (_cb_data.error) {
160+
return false;
166161
}
167162
}
168163

@@ -250,18 +245,16 @@ void CellularStateMachine::report_failure(const char *msg)
250245
tr_error("CellularStateMachine failure: %s", msg);
251246

252247
_event_id = -1;
253-
if (_event_status_cb) {
254-
_cb_data.final_try = true;
255-
_event_status_cb(_current_event, (intptr_t)&_cb_data);
256-
}
248+
_cb_data.final_try = true;
249+
send_event_cb(_current_event);
257250

258251
tr_error("CellularStateMachine target state %s, current state %s", get_state_string(_target_state), get_state_string(_state));
259252
}
260253

261254
const char *CellularStateMachine::get_state_string(CellularState state) const
262255
{
263256
#if MBED_CONF_MBED_TRACE_ENABLE
264-
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network"};
257+
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Signal quality", "Registering network", "Attaching network"};
265258
return strings[state];
266259
#else
267260
return NULL;
@@ -282,12 +275,17 @@ void CellularStateMachine::retry_state_or_fail()
282275
{
283276
if (++_retry_count < CELLULAR_RETRY_ARRAY_SIZE) {
284277
tr_debug("%s: retry %d/%d", get_state_string(_state), _retry_count, CELLULAR_RETRY_ARRAY_SIZE);
278+
// send info to application/driver about error logic so it can implement proper error logic
279+
_cb_data.status_data = _current_event;
280+
_cb_data.data = &_retry_count;
281+
_cb_data.error = NSAPI_ERROR_OK;
282+
send_event_cb(CellularStateRetryEvent);
283+
285284
_event_timeout = _retry_timeout_array[_retry_count];
286285
_is_retry = true;
287286
_cb_data.error = NSAPI_ERROR_OK;
288287
} else {
289288
report_failure(get_state_string(_state));
290-
return;
291289
}
292290
}
293291

@@ -334,9 +332,7 @@ bool CellularStateMachine::device_ready()
334332
}
335333
#endif // MBED_CONF_CELLULAR_DEBUG_AT
336334

337-
if (_event_status_cb) {
338-
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t)&_cb_data);
339-
}
335+
send_event_cb(CellularDeviceReady);
340336
_cellularDevice.set_ready_cb(0);
341337

342338
return true;
@@ -402,12 +398,25 @@ void CellularStateMachine::state_sim_pin()
402398
} else if (_cb_data.error) {
403399
tr_warning("Packet domain event reporting set failed!");
404400
}
405-
enter_to_state(STATE_REGISTERING_NETWORK);
401+
enter_to_state(STATE_SIGNAL_QUALITY);
406402
} else {
407403
retry_state_or_fail();
408404
}
409405
}
410406

407+
void CellularStateMachine::state_signal_quality()
408+
{
409+
_cb_data.error = _network.get_signal_quality(_signal_quality.rssi, &_signal_quality.ber);
410+
411+
if (_cb_data.error != NSAPI_ERROR_OK) {
412+
retry_state_or_fail();
413+
} else {
414+
_cb_data.data = &_signal_quality;
415+
send_event_cb(_current_event);
416+
enter_to_state(STATE_REGISTERING_NETWORK);
417+
}
418+
}
419+
411420
void CellularStateMachine::state_registering()
412421
{
413422
_cellularDevice.set_timeout(TIMEOUT_NETWORK);
@@ -419,7 +428,7 @@ void CellularStateMachine::state_registering()
419428
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
420429
}
421430
_cb_data.error = NSAPI_ERROR_OK;
422-
_event_status_cb(_current_event, (intptr_t)&_cb_data);
431+
send_event_cb(_current_event);
423432
// we are already registered, go to attach
424433
enter_to_state(STATE_ATTACHING_NETWORK);
425434
} else {
@@ -440,10 +449,8 @@ void CellularStateMachine::state_attaching()
440449
_cb_data.error = _network.set_attach();
441450
}
442451
if (_cb_data.error == NSAPI_ERROR_OK) {
443-
if (_event_status_cb) {
444-
_cb_data.status_data = CellularNetwork::Attached;
445-
_event_status_cb(_current_event, (intptr_t)&_cb_data);
446-
}
452+
_cb_data.status_data = CellularNetwork::Attached;
453+
send_event_cb(_current_event);
447454
} else {
448455
retry_state_or_fail();
449456
}
@@ -524,43 +531,51 @@ bool CellularStateMachine::get_current_status(CellularStateMachine::CellularStat
524531

525532
void CellularStateMachine::event()
526533
{
527-
#if MBED_CONF_MBED_TRACE_ENABLE
528-
int rssi;
529-
if (_network.get_signal_quality(rssi) == NSAPI_ERROR_OK) {
530-
if (rssi == CellularNetwork::SignalQualityUnknown) {
531-
tr_info("RSSI unknown");
532-
} else {
533-
tr_info("RSSI %d dBm", rssi);
534+
// Don't send Signal quality when in signal quality state or it can confuse callback functions when running retry logic
535+
if (_state != STATE_SIGNAL_QUALITY) {
536+
_cb_data.error = _network.get_signal_quality(_signal_quality.rssi, &_signal_quality.ber);
537+
_cb_data.data = &_signal_quality;
538+
539+
if (_cb_data.error == NSAPI_ERROR_OK) {
540+
send_event_cb(CellularSignalQuality);
541+
if (_signal_quality.rssi == CellularNetwork::SignalQualityUnknown) {
542+
tr_info("RSSI unknown");
543+
} else {
544+
tr_info("RSSI %d dBm", _signal_quality.rssi);
545+
}
534546
}
535547
}
536-
#endif
537548

538549
_event_timeout = -1;
539550
_is_retry = false;
540551

541552
switch (_state) {
542553
case STATE_INIT:
543-
_current_event = (nsapi_event_t)CellularDeviceReady;
554+
_current_event = CellularDeviceReady;
544555
state_init();
545556
break;
546557
case STATE_POWER_ON:
547-
_current_event = (nsapi_event_t)CellularDeviceReady;
558+
_current_event = CellularDeviceReady;
548559
state_power_on();
549560
break;
550561
case STATE_DEVICE_READY:
551-
_current_event = (nsapi_event_t)CellularDeviceReady;
562+
_current_event = CellularDeviceReady;
552563
state_device_ready();
553564
break;
554565
case STATE_SIM_PIN:
555-
_current_event = (nsapi_event_t)CellularSIMStatusChanged;
566+
_current_event = CellularSIMStatusChanged;
556567
state_sim_pin();
557568
break;
569+
case STATE_SIGNAL_QUALITY:
570+
_current_event = CellularSignalQuality;
571+
state_signal_quality();
572+
break;
558573
case STATE_REGISTERING_NETWORK:
559-
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged;
574+
_current_event = CellularRegistrationStatusChanged;
560575
state_registering();
561576
break;
562577
case STATE_ATTACHING_NETWORK:
563-
_current_event = (nsapi_event_t)CellularAttachNetwork;
578+
_current_event = CellularAttachNetwork;
564579
state_attaching();
565580
break;
566581
default:
@@ -612,6 +627,13 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
612627
_event_status_cb = status_cb;
613628
}
614629

630+
void CellularStateMachine::send_event_cb(cellular_connection_status_t status)
631+
{
632+
if (_event_status_cb) {
633+
_event_status_cb((nsapi_event_t)status, (intptr_t)&_cb_data);
634+
}
635+
}
636+
615637
bool CellularStateMachine::check_is_target_reached()
616638
{
617639
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()
629651
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
630652
{
631653
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
632-
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) {
654+
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && (
655+
_state == STATE_REGISTERING_NETWORK || _state == STATE_SIGNAL_QUALITY)) {
633656
// expect packet data so only these states are valid
634657
CellularNetwork::registration_params_t reg_params;
635658
nsapi_error_t err = _network.get_registration_params(reg_params);

0 commit comments

Comments
 (0)