@@ -43,7 +43,7 @@ namespace mbed
43
43
CellularConnectionFSM::CellularConnectionFSM () :
44
44
_serial (0 ), _state(STATE_INIT), _next_state(_state), _status_callback(0 ), _event_status_cb(0 ), _network(0 ), _power(0 ), _sim(0 ),
45
45
_queue (8 * EVENTS_EVENT_SIZE), _queue_thread(0 ), _cellularDevice(0 ), _retry_count(0 ), _event_timeout(-1 ),
46
- _at_queue (8 * EVENTS_EVENT_SIZE), _event_id(0 ), _plmn(0 )
46
+ _at_queue (8 * EVENTS_EVENT_SIZE), _event_id(0 ), _plmn(0 ), _command_success( false ), _plmn_network_found( false )
47
47
{
48
48
memset (_sim_pin, 0 , sizeof (_sim_pin));
49
49
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
@@ -284,7 +284,7 @@ void CellularConnectionFSM::report_failure(const char* msg)
284
284
const char * CellularConnectionFSM::get_state_string (CellularState state)
285
285
{
286
286
#if MBED_CONF_MBED_TRACE_ENABLE
287
- static const char *strings[] = { " Init" , " Power" , " Device ready" , " SIM pin" , " Registering network" , " Attaching network" , " Connecting network" , " Connected" };
287
+ static const char *strings[] = { " Init" , " Power" , " Device ready" , " SIM pin" , " Registering network" , " Manual registering " , " Attaching network" , " Connecting network" , " Connected" };
288
288
return strings[state];
289
289
#else
290
290
return NULL ;
@@ -302,6 +302,55 @@ nsapi_error_t CellularConnectionFSM::is_automatic_registering(bool& auto_reg)
302
302
return err;
303
303
}
304
304
305
+ bool CellularConnectionFSM::is_registered_to_plmn ()
306
+ {
307
+ int format;
308
+ CellularNetwork::operator_t op;
309
+
310
+ nsapi_error_t err = _network->get_operator_params (format, op);
311
+ if (err == NSAPI_ERROR_OK) {
312
+ if (format == 2 ) {
313
+ // great, numeric format we can do comparison for that
314
+ if (strcmp (op.op_num , _plmn) == 0 ) {
315
+ return true ;
316
+ }
317
+ return false ;
318
+ }
319
+
320
+ // format was alpha, get operator names to do the comparing
321
+ CellularNetwork::operator_names_list names_list;
322
+ nsapi_error_t err = _network->get_operator_names (names_list);
323
+ if (err == NSAPI_ERROR_OK) {
324
+ CellularNetwork::operator_names_t * op_names = names_list.get_head ();
325
+ bool found_match = false ;
326
+ while (op_names) {
327
+ if (format == 0 ) {
328
+ if (strcmp (op.op_long , op_names->alpha ) == 0 ) {
329
+ found_match = true ;
330
+ }
331
+ } else if (format == 1 ) {
332
+ if (strcmp (op.op_short , op_names->alpha ) == 0 ) {
333
+ found_match = true ;
334
+ }
335
+ }
336
+
337
+ if (found_match) {
338
+ if (strcmp (_plmn, op_names->numeric )) {
339
+ names_list.delete_all ();
340
+ return true ;
341
+ } else {
342
+ names_list.delete_all ();
343
+ return false ;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ names_list.delete_all ();
349
+ }
350
+
351
+ return false ;
352
+ }
353
+
305
354
nsapi_error_t CellularConnectionFSM::continue_from_state (CellularState state)
306
355
{
307
356
tr_info (" Continue state from %s to %s" , get_state_string ((CellularConnectionFSM::CellularState)_state),
@@ -338,6 +387,7 @@ void CellularConnectionFSM::enter_to_state(CellularState state)
338
387
{
339
388
_next_state = state;
340
389
_retry_count = 0 ;
390
+ _command_success = false ;
341
391
}
342
392
343
393
void CellularConnectionFSM::retry_state_or_fail ()
@@ -414,7 +464,11 @@ void CellularConnectionFSM::state_sim_pin()
414
464
_cellularDevice->set_timeout (TIMEOUT_SIM_PIN);
415
465
tr_info (" Sim state (timeout %d ms)" , TIMEOUT_SIM_PIN);
416
466
if (open_sim ()) {
417
- enter_to_state (STATE_REGISTERING_NETWORK);
467
+ if (_plmn) {
468
+ enter_to_state (STATE_MANUAL_REGISTERING_NETWORK);
469
+ } else {
470
+ enter_to_state (STATE_REGISTERING_NETWORK);
471
+ }
418
472
} else {
419
473
retry_state_or_fail ();
420
474
}
@@ -424,28 +478,35 @@ void CellularConnectionFSM::state_registering()
424
478
{
425
479
_cellularDevice->set_timeout (TIMEOUT_NETWORK);
426
480
if (is_registered ()) {
427
- if (_plmn && _retry_count == 0 ) {
428
- // we don't know which network we are registered, try to register to specific network
481
+ // we are already registered, go to attach
482
+ enter_to_state (STATE_ATTACHING_NETWORK);
483
+ } else {
484
+ bool auto_reg = false ;
485
+ nsapi_error_t err = is_automatic_registering (auto_reg);
486
+ if (err == NSAPI_ERROR_OK && !auto_reg) {
487
+ // automatic registering is not on, set registration and retry
429
488
_cellularDevice->set_timeout (TIMEOUT_REGISTRATION);
430
489
set_network_registration ();
431
- retry_state_or_fail ();
432
- } else {
433
- // we are already registered, go to attach
434
- enter_to_state (STATE_ATTACHING_NETWORK);
435
490
}
436
- } else {
437
- if (_plmn) {
438
- set_network_registration ();
491
+ retry_state_or_fail ();
492
+ }
493
+ }
494
+
495
+ // only used when _plmn is set
496
+ void CellularConnectionFSM::state_manual_registering_network ()
497
+ {
498
+ _cellularDevice->set_timeout (TIMEOUT_REGISTRATION);
499
+ tr_info (" state_manual_registering_network" );
500
+ if (!_plmn_network_found) {
501
+ if (is_registered () && is_registered_to_plmn ()) {
502
+ _plmn_network_found = true ;
503
+ enter_to_state (STATE_ATTACHING_NETWORK);
439
504
} else {
440
- bool auto_reg = false ;
441
- nsapi_error_t err = is_automatic_registering (auto_reg);
442
- if (err == NSAPI_ERROR_OK && !auto_reg) {
443
- // automatic registering is not on, set registration and retry
444
- _cellularDevice->set_timeout (TIMEOUT_REGISTRATION);
445
- set_network_registration ();
505
+ if (!_command_success) {
506
+ _command_success = set_network_registration ();
446
507
}
508
+ retry_state_or_fail ();
447
509
}
448
- retry_state_or_fail ();
449
510
}
450
511
}
451
512
@@ -457,7 +518,9 @@ void CellularConnectionFSM::state_attaching()
457
518
if (attach_status == CellularNetwork::Attached) {
458
519
enter_to_state (STATE_ACTIVATING_PDP_CONTEXT);
459
520
} else {
460
- set_attach_network ();
521
+ if (!_command_success) {
522
+ _command_success = set_attach_network ();
523
+ }
461
524
retry_state_or_fail ();
462
525
}
463
526
} else {
@@ -519,6 +582,9 @@ void CellularConnectionFSM::event()
519
582
case STATE_REGISTERING_NETWORK:
520
583
state_registering ();
521
584
break ;
585
+ case STATE_MANUAL_REGISTERING_NETWORK:
586
+ state_manual_registering_network ();
587
+ break ;
522
588
case STATE_ATTACHING_NETWORK:
523
589
state_attaching ();
524
590
break ;
@@ -595,13 +661,23 @@ void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)>
595
661
596
662
void CellularConnectionFSM::network_callback (nsapi_event_t ev, intptr_t ptr)
597
663
{
598
-
599
- tr_info ( " FSM: network_callback called with event: %d, intptr: %d " , ev, ptr);
600
- if (( cellular_connection_status_t )ev == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK ) {
664
+ tr_info ( " FSM: network_callback called with event: %d, intptr: %d, _state: %s " , ev, ptr, get_state_string (_state));
665
+ if (( cellular_connection_status_t )ev == CellularRegistrationStatusChanged &&
666
+ (_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK) ) {
601
667
// expect packet data so only these states are valid
602
- if (ptr == CellularNetwork::RegisteredHomeNetwork && CellularNetwork::RegisteredRoaming) {
603
- _queue.cancel (_event_id);
604
- continue_from_state (STATE_ATTACHING_NETWORK);
668
+ if (ptr == CellularNetwork::RegisteredHomeNetwork || ptr == CellularNetwork::RegisteredRoaming) {
669
+ if (_plmn) {
670
+ if (is_registered_to_plmn ()) {
671
+ if (!_plmn_network_found) {
672
+ _plmn_network_found = true ;
673
+ _queue.cancel (_event_id);
674
+ continue_from_state (STATE_ATTACHING_NETWORK);
675
+ }
676
+ }
677
+ } else {
678
+ _queue.cancel (_event_id);
679
+ continue_from_state (STATE_ATTACHING_NETWORK);
680
+ }
605
681
}
606
682
}
607
683
0 commit comments