Skip to content

Commit a830dbf

Browse files
author
Teppo Järvelin
committed
Cellular: removed manual registering state.
Simplified state machine by removing manual registering state. This was done as some modems did not have all the needed at commands for checking the registered network. Some modem run out of memory as when checking correct network there might be so many networks available. Manual registration still works but it does not do any checks to which network it's registered. Moved manual registering at command earlier in state machine so it forces registering to a correct network. Internal refactor/fix, does not affect applications.
1 parent 5c24ffe commit a830dbf

File tree

4 files changed

+55
-123
lines changed

4 files changed

+55
-123
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ enum UT_CellularState {
3434
UT_STATE_DEVICE_READY,
3535
UT_STATE_SIM_PIN,
3636
UT_STATE_REGISTERING_NETWORK,
37-
UT_STATE_MANUAL_REGISTERING_NETWORK,
3837
UT_STATE_ATTACHING_NETWORK,
3938
UT_STATE_MAX_FSM_STATE
4039
};
@@ -392,8 +391,8 @@ TEST_F(TestCellularStateMachine, test_run_to_state)
392391
ut.set_plmn("12345");
393392
ASSERT_EQ(NSAPI_ERROR_OK, ut.run_to_device_registered());
394393
(void)ut.get_current_status(current_state, target_state);
395-
ASSERT_EQ(UT_STATE_MANUAL_REGISTERING_NETWORK, current_state);
396-
ASSERT_EQ(UT_STATE_MANUAL_REGISTERING_NETWORK, target_state);
394+
ASSERT_EQ(UT_STATE_REGISTERING_NETWORK, current_state);
395+
ASSERT_EQ(UT_STATE_REGISTERING_NETWORK, target_state);
397396
ut.cellular_event_changed((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data);
398397
ut.reset();
399398

features/cellular/framework/AT/AT_CellularNetwork.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
171171
reg_params._status == RegisteredRoaming)) {
172172
if (previous_registration_status == RegisteredHomeNetwork ||
173173
previous_registration_status == RegisteredRoaming) {
174-
call_network_cb(NSAPI_STATUS_DISCONNECTED);
174+
if (type != C_REG) {// we are interested only if we drop from packet network
175+
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
176+
}
175177
}
176178
}
177179
}
@@ -267,6 +269,9 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
267269
tr_debug("Manual network registration to %s", plmn);
268270
_at.cmd_start("AT+COPS=1,2,");
269271
_at.write_string(plmn);
272+
if (_op_act != RAT_UNKNOWN) {
273+
_at.write_int(_op_act);
274+
}
270275
_at.cmd_stop_read_resp();
271276
}
272277

features/cellular/framework/device/CellularStateMachine.cpp

Lines changed: 47 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event
4848
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
4949
_event_status_cb(0), _network(0), _queue(queue), _queue_thread(0), _sim_pin(0),
5050
_retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
51-
_plmn_network_found(false), _is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE),
52-
_status(0)
51+
_is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE), _status(0)
5352
{
5453
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
5554
_start_time = 0;
@@ -83,7 +82,6 @@ void CellularStateMachine::reset()
8382
_state = STATE_INIT;
8483
_event_timeout = -1;
8584
_event_id = -1;
86-
_plmn_network_found = false;
8785
_is_retry = false;
8886
_status = 0;
8987
_target_state = STATE_INIT;
@@ -161,15 +159,30 @@ bool CellularStateMachine::open_sim()
161159
}
162160
}
163161

164-
return state == CellularDevice::SimStateReady;
162+
bool sim_ready = state == CellularDevice::SimStateReady;
163+
164+
if (sim_ready) {
165+
// If plmn is set, we should it right after sim is opened so that registration is forced to correct network.
166+
if (_plmn && strlen(_plmn)) {
167+
_cb_data.error = _network->set_registration(_plmn);
168+
tr_debug("STM: manual set_registration: %d, plmn: %s", _cb_data.error, _plmn);
169+
if (_cb_data.error) {
170+
return false;
171+
}
172+
}
173+
}
174+
175+
return sim_ready;
165176
}
166177

167178
bool CellularStateMachine::is_registered()
168179
{
169180
CellularNetwork::RegistrationStatus status;
170181
bool is_registered = false;
171182

172-
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
183+
// accept only CGREG/CEREG. CREG is for circuit switch network changed. If we accept CREG attach will fail if also
184+
// CGREG/CEREG is not registered.
185+
for (int type = 0; type < CellularNetwork::C_REG; type++) {
173186
if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) {
174187
if (is_registered) {
175188
break;
@@ -178,6 +191,11 @@ bool CellularStateMachine::is_registered()
178191
}
179192

180193
_cb_data.status_data = status;
194+
// in manual registering we are forcing registration to certain network so we don't accept active context or attached
195+
// as indication that device is registered to correct network.
196+
if (_plmn && strlen(_plmn)) {
197+
return is_registered;
198+
}
181199
return is_registered || _status;
182200
}
183201

@@ -249,61 +267,13 @@ void CellularStateMachine::report_failure(const char *msg)
249267
const char *CellularStateMachine::get_state_string(CellularState state) const
250268
{
251269
#if MBED_CONF_MBED_TRACE_ENABLE
252-
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Manual registering", "Attaching network"};
270+
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network"};
253271
return strings[state];
254272
#else
255273
return NULL;
256274
#endif // #if MBED_CONF_MBED_TRACE_ENABLE
257275
}
258276

259-
bool CellularStateMachine::is_registered_to_plmn()
260-
{
261-
int format;
262-
CellularNetwork::operator_t op;
263-
264-
_cb_data.error = _network->get_operator_params(format, op);
265-
if (_cb_data.error == NSAPI_ERROR_OK) {
266-
if (format == 2) {
267-
// great, numeric format we can do comparison for that
268-
if (strcmp(op.op_num, _plmn) == 0) {
269-
return true;
270-
}
271-
return false;
272-
}
273-
274-
// format was alpha, get operator names to do the comparing
275-
CellularNetwork::operator_names_list names_list;
276-
_cb_data.error = _network->get_operator_names(names_list);
277-
if (_cb_data.error == NSAPI_ERROR_OK) {
278-
CellularNetwork::operator_names_t *op_names = names_list.get_head();
279-
bool found_match = false;
280-
while (op_names) {
281-
if (format == 0) {
282-
if (strcmp(op.op_long, op_names->alpha) == 0) {
283-
found_match = true;
284-
}
285-
} else if (format == 1) {
286-
if (strcmp(op.op_short, op_names->alpha) == 0) {
287-
found_match = true;
288-
}
289-
}
290-
291-
if (found_match) {
292-
if (strcmp(_plmn, op_names->numeric)) {
293-
names_list.delete_all();
294-
return true;
295-
}
296-
names_list.delete_all();
297-
return false;
298-
}
299-
}
300-
}
301-
names_list.delete_all();
302-
}
303-
304-
return false;
305-
}
306-
307277
void CellularStateMachine::enter_to_state(CellularState state)
308278
{
309279
_next_state = state;
@@ -378,6 +348,7 @@ bool CellularStateMachine::device_ready()
378348
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t)&_cb_data);
379349
}
380350
_cellularDevice.set_ready_cb(0);
351+
381352
return true;
382353
}
383354

@@ -410,16 +381,15 @@ void CellularStateMachine::state_sim_pin()
410381
_cellularDevice.set_timeout(TIMEOUT_SIM_PIN);
411382
tr_info("Setup SIM (timeout %d s)", TIMEOUT_SIM_PIN / 1000);
412383
if (open_sim()) {
413-
414384
bool success = false;
415385
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
416386
_cb_data.error = _network->set_registration_urc((CellularNetwork::RegistrationType)type, true);
417-
if (!_cb_data.error) {
387+
if (!_cb_data.error && (type == CellularNetwork::C_EREG || type == CellularNetwork::C_GREG)) {
418388
success = true;
419389
}
420390
}
421391
if (!success) {
422-
tr_warn("Failed to set any URC's for registration");
392+
tr_error("Failed to set CEREG/CGREG URC's for registration");
423393
retry_state_or_fail();
424394
return;
425395
}
@@ -428,16 +398,13 @@ void CellularStateMachine::state_sim_pin()
428398
tr_debug("Active context found.");
429399
_status |= ACTIVE_PDP_CONTEXT;
430400
}
431-
CellularNetwork::AttachStatus status; // check if modem is already attached to a network
401+
CellularNetwork::AttachStatus status = CellularNetwork::Detached; // check if modem is already attached to a network
432402
if (_network->get_attach(status) == NSAPI_ERROR_OK && status == CellularNetwork::Attached) {
433403
_status |= ATTACHED_TO_NETWORK;
434404
tr_debug("Cellular already attached.");
435405
}
436-
if (_plmn) {
437-
enter_to_state(STATE_MANUAL_REGISTERING_NETWORK);
438-
} else {
439-
enter_to_state(STATE_REGISTERING_NETWORK);
440-
}
406+
407+
enter_to_state(STATE_REGISTERING_NETWORK);
441408
} else {
442409
retry_state_or_fail();
443410
}
@@ -448,44 +415,25 @@ void CellularStateMachine::state_registering()
448415
_cellularDevice.set_timeout(TIMEOUT_NETWORK);
449416
tr_info("Network registration (timeout %d s)", TIMEOUT_REGISTRATION / 1000);
450417
if (is_registered()) {
451-
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
418+
if (_cb_data.status_data != CellularNetwork::RegisteredHomeNetwork &&
419+
_cb_data.status_data != CellularNetwork::RegisteredRoaming && _status) {
420+
// there was already activated context or attached to network, and registration status is not registered, set to already registered.
421+
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
422+
}
452423
_cb_data.error = NSAPI_ERROR_OK;
453424
_event_status_cb(_current_event, (intptr_t)&_cb_data);
454425
// we are already registered, go to attach
455426
enter_to_state(STATE_ATTACHING_NETWORK);
456427
} else {
457428
_cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
458-
if (!_command_success) {
459-
_cb_data.error = _network->set_registration();
429+
if (!_command_success && !_plmn) { // don't call set_registration twice for manual registration
430+
_cb_data.error = _network->set_registration(_plmn);
460431
_command_success = (_cb_data.error == NSAPI_ERROR_OK);
461432
}
462433
retry_state_or_fail();
463434
}
464435
}
465436

466-
// only used when _plmn is set
467-
void CellularStateMachine::state_manual_registering_network()
468-
{
469-
_cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
470-
tr_info("Manual registration %s (timeout %d s)", _plmn, TIMEOUT_REGISTRATION / 1000);
471-
if (!_plmn_network_found) {
472-
if (is_registered() && is_registered_to_plmn()) {
473-
// we have to send registration changed event as network thinks that we are not registered even we have active PDP context
474-
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
475-
_cb_data.error = NSAPI_ERROR_OK;
476-
_event_status_cb(_current_event, (intptr_t)&_cb_data);
477-
_plmn_network_found = true;
478-
enter_to_state(STATE_ATTACHING_NETWORK);
479-
} else {
480-
if (!_command_success) {
481-
_cb_data.error = _network->set_registration(_plmn);
482-
_command_success = (_cb_data.error == NSAPI_ERROR_OK);
483-
}
484-
retry_state_or_fail();
485-
}
486-
}
487-
}
488-
489437
void CellularStateMachine::state_attaching()
490438
{
491439
_cellularDevice.set_timeout(TIMEOUT_CONNECT);
@@ -523,13 +471,8 @@ void CellularStateMachine::continue_from_state(CellularState state)
523471
nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularState state)
524472
{
525473
_mutex.lock();
526-
527-
CellularState tmp_state = state;
528-
if (_plmn && tmp_state == STATE_REGISTERING_NETWORK) {
529-
tmp_state = STATE_MANUAL_REGISTERING_NETWORK;
530-
}
531474
// call pre_event via queue so that it's in same thread and it's safe to decisions
532-
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, tmp_state);
475+
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, state);
533476
if (!id) {
534477
report_failure("Failed to call queue.");
535478
stop();
@@ -620,10 +563,6 @@ void CellularStateMachine::event()
620563
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged;
621564
state_registering();
622565
break;
623-
case STATE_MANUAL_REGISTERING_NETWORK:
624-
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged;
625-
state_manual_registering_network();
626-
break;
627566
case STATE_ATTACHING_NETWORK:
628567
_current_event = (nsapi_event_t)CellularAttachNetwork;
629568
state_attaching();
@@ -694,30 +633,23 @@ bool CellularStateMachine::check_is_target_reached()
694633
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
695634
{
696635
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
697-
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged &&
698-
(_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK)) {
636+
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) {
699637
// expect packet data so only these states are valid
700-
if ((data->status_data == CellularNetwork::RegisteredHomeNetwork || data->status_data == CellularNetwork::RegisteredRoaming) && data->error == NSAPI_ERROR_OK) {
701-
if (_plmn) {
702-
if (is_registered_to_plmn()) {
703-
if (!_plmn_network_found) {
704-
_plmn_network_found = true;
705-
_queue.cancel(_event_id);
706-
_is_retry = false;
707-
_event_id = -1;
708-
if (!check_is_target_reached()) {
709-
continue_from_state(STATE_ATTACHING_NETWORK);
710-
}
711-
}
712-
}
713-
} else {
638+
CellularNetwork::registration_params_t reg_params;
639+
nsapi_error_t err = _network->get_registration_params(reg_params);
640+
641+
if (err == NSAPI_ERROR_OK && (reg_params._type == CellularNetwork::C_EREG || reg_params._type == CellularNetwork::C_GREG)) {
642+
if ((data->status_data == CellularNetwork::RegisteredHomeNetwork ||
643+
data->status_data == CellularNetwork::RegisteredRoaming) && data->error == NSAPI_ERROR_OK) {
714644
_queue.cancel(_event_id);
715645
_is_retry = false;
716646
_event_id = -1;
717647
if (!check_is_target_reached()) {
718648
continue_from_state(STATE_ATTACHING_NETWORK);
719649
}
720650
}
651+
} else {
652+
tr_debug("creg event, discard...");
721653
}
722654
}
723655
}

features/cellular/framework/device/CellularStateMachine.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ class CellularStateMachine {
5858
STATE_DEVICE_READY,
5959
STATE_SIM_PIN,
6060
STATE_REGISTERING_NETWORK,
61-
STATE_MANUAL_REGISTERING_NETWORK,
6261
STATE_ATTACHING_NETWORK,
6362
STATE_MAX_FSM_STATE
6463
};
@@ -146,12 +145,10 @@ class CellularStateMachine {
146145
void state_device_ready();
147146
void state_sim_pin();
148147
void state_registering();
149-
void state_manual_registering_network();
150148
void state_attaching();
151149
void enter_to_state(CellularState state);
152150
void retry_state_or_fail();
153151
void continue_from_state(CellularState state);
154-
bool is_registered_to_plmn();
155152
void report_failure(const char *msg);
156153
void event();
157154
void device_ready_cb();
@@ -179,7 +176,6 @@ class CellularStateMachine {
179176
int _event_id;
180177
const char *_plmn;
181178
bool _command_success;
182-
bool _plmn_network_found;
183179
bool _is_retry;
184180
cell_callback_data_t _cb_data;
185181
nsapi_event_t _current_event;

0 commit comments

Comments
 (0)