@@ -48,8 +48,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event
48
48
_cellularDevice (device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
49
49
_event_status_cb (0 ), _network(0 ), _queue(queue), _queue_thread(0 ), _sim_pin(0 ),
50
50
_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 )
53
52
{
54
53
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
55
54
_start_time = 0 ;
@@ -83,7 +82,6 @@ void CellularStateMachine::reset()
83
82
_state = STATE_INIT;
84
83
_event_timeout = -1 ;
85
84
_event_id = -1 ;
86
- _plmn_network_found = false ;
87
85
_is_retry = false ;
88
86
_status = 0 ;
89
87
_target_state = STATE_INIT;
@@ -161,15 +159,30 @@ bool CellularStateMachine::open_sim()
161
159
}
162
160
}
163
161
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;
165
176
}
166
177
167
178
bool CellularStateMachine::is_registered ()
168
179
{
169
180
CellularNetwork::RegistrationStatus status;
170
181
bool is_registered = false ;
171
182
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++) {
173
186
if (get_network_registration ((CellularNetwork::RegistrationType) type, status, is_registered)) {
174
187
if (is_registered) {
175
188
break ;
@@ -178,6 +191,11 @@ bool CellularStateMachine::is_registered()
178
191
}
179
192
180
193
_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
+ }
181
199
return is_registered || _status;
182
200
}
183
201
@@ -249,61 +267,13 @@ void CellularStateMachine::report_failure(const char *msg)
249
267
const char *CellularStateMachine::get_state_string (CellularState state) const
250
268
{
251
269
#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" };
253
271
return strings[state];
254
272
#else
255
273
return NULL ;
256
274
#endif // #if MBED_CONF_MBED_TRACE_ENABLE
257
275
}
258
276
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
-
307
277
void CellularStateMachine::enter_to_state (CellularState state)
308
278
{
309
279
_next_state = state;
@@ -378,6 +348,7 @@ bool CellularStateMachine::device_ready()
378
348
_event_status_cb ((nsapi_event_t )CellularDeviceReady, (intptr_t )&_cb_data);
379
349
}
380
350
_cellularDevice.set_ready_cb (0 );
351
+
381
352
return true ;
382
353
}
383
354
@@ -410,16 +381,15 @@ void CellularStateMachine::state_sim_pin()
410
381
_cellularDevice.set_timeout (TIMEOUT_SIM_PIN);
411
382
tr_info (" Setup SIM (timeout %d s)" , TIMEOUT_SIM_PIN / 1000 );
412
383
if (open_sim ()) {
413
-
414
384
bool success = false ;
415
385
for (int type = 0 ; type < CellularNetwork::C_MAX; type++) {
416
386
_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) ) {
418
388
success = true ;
419
389
}
420
390
}
421
391
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" );
423
393
retry_state_or_fail ();
424
394
return ;
425
395
}
@@ -428,16 +398,13 @@ void CellularStateMachine::state_sim_pin()
428
398
tr_debug (" Active context found." );
429
399
_status |= ACTIVE_PDP_CONTEXT;
430
400
}
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
432
402
if (_network->get_attach (status) == NSAPI_ERROR_OK && status == CellularNetwork::Attached) {
433
403
_status |= ATTACHED_TO_NETWORK;
434
404
tr_debug (" Cellular already attached." );
435
405
}
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);
441
408
} else {
442
409
retry_state_or_fail ();
443
410
}
@@ -448,44 +415,25 @@ void CellularStateMachine::state_registering()
448
415
_cellularDevice.set_timeout (TIMEOUT_NETWORK);
449
416
tr_info (" Network registration (timeout %d s)" , TIMEOUT_REGISTRATION / 1000 );
450
417
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
+ }
452
423
_cb_data.error = NSAPI_ERROR_OK;
453
424
_event_status_cb (_current_event, (intptr_t )&_cb_data);
454
425
// we are already registered, go to attach
455
426
enter_to_state (STATE_ATTACHING_NETWORK);
456
427
} else {
457
428
_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 );
460
431
_command_success = (_cb_data.error == NSAPI_ERROR_OK);
461
432
}
462
433
retry_state_or_fail ();
463
434
}
464
435
}
465
436
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
-
489
437
void CellularStateMachine::state_attaching ()
490
438
{
491
439
_cellularDevice.set_timeout (TIMEOUT_CONNECT);
@@ -523,13 +471,8 @@ void CellularStateMachine::continue_from_state(CellularState state)
523
471
nsapi_error_t CellularStateMachine::run_to_state (CellularStateMachine::CellularState state)
524
472
{
525
473
_mutex.lock ();
526
-
527
- CellularState tmp_state = state;
528
- if (_plmn && tmp_state == STATE_REGISTERING_NETWORK) {
529
- tmp_state = STATE_MANUAL_REGISTERING_NETWORK;
530
- }
531
474
// 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 );
533
476
if (!id) {
534
477
report_failure (" Failed to call queue." );
535
478
stop ();
@@ -620,10 +563,6 @@ void CellularStateMachine::event()
620
563
_current_event = (nsapi_event_t )CellularRegistrationStatusChanged;
621
564
state_registering ();
622
565
break ;
623
- case STATE_MANUAL_REGISTERING_NETWORK:
624
- _current_event = (nsapi_event_t )CellularRegistrationStatusChanged;
625
- state_manual_registering_network ();
626
- break ;
627
566
case STATE_ATTACHING_NETWORK:
628
567
_current_event = (nsapi_event_t )CellularAttachNetwork;
629
568
state_attaching ();
@@ -694,30 +633,23 @@ bool CellularStateMachine::check_is_target_reached()
694
633
void CellularStateMachine::cellular_event_changed (nsapi_event_t ev, intptr_t ptr)
695
634
{
696
635
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) {
699
637
// 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) {
714
644
_queue.cancel (_event_id);
715
645
_is_retry = false ;
716
646
_event_id = -1 ;
717
647
if (!check_is_target_reached ()) {
718
648
continue_from_state (STATE_ATTACHING_NETWORK);
719
649
}
720
650
}
651
+ } else {
652
+ tr_debug (" creg event, discard..." );
721
653
}
722
654
}
723
655
}
0 commit comments