@@ -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 )
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
@@ -146,6 +146,11 @@ void CellularConnectionFSM::set_sim_pin(const char * sim_pin)
146
146
_sim_pin[sizeof (_sim_pin)-1 ] = ' \0 ' ;
147
147
}
148
148
149
+ void CellularConnectionFSM::set_plmn (const char * plmn)
150
+ {
151
+ _plmn = plmn;
152
+ }
153
+
149
154
bool CellularConnectionFSM::open_sim ()
150
155
{
151
156
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
@@ -162,7 +167,7 @@ bool CellularConnectionFSM::open_sim()
162
167
nsapi_error_t err = _sim->set_pin (_sim_pin);
163
168
if (err) {
164
169
tr_error (" SIM pin set failed with: %d, bailing out..." , err);
165
- }
170
+ }
166
171
} else {
167
172
tr_warn (" PIN required but No SIM pin provided." );
168
173
}
@@ -175,11 +180,10 @@ bool CellularConnectionFSM::open_sim()
175
180
return state == CellularSIM::SimStateReady;
176
181
}
177
182
178
- bool CellularConnectionFSM::set_network_registration (char *plmn )
183
+ bool CellularConnectionFSM::set_network_registration ()
179
184
{
180
- nsapi_error_t error = _network->set_registration (plmn);
181
- if (error != NSAPI_ERROR_OK) {
182
- tr_error (" Set network registration mode failing (%d)" , error);
185
+ if (_network->set_registration (_plmn) != NSAPI_ERROR_OK) {
186
+ tr_error (" Failed to set network registration." );
183
187
return false ;
184
188
}
185
189
return true ;
@@ -279,8 +283,12 @@ void CellularConnectionFSM::report_failure(const char* msg)
279
283
280
284
const char * CellularConnectionFSM::get_state_string (CellularState state)
281
285
{
282
- static const char *strings[] = { " Init" , " Power" , " Device ready" , " SIM pin" , " Registering network" , " Attaching network" , " Activating PDP Context" , " Connecting network" , " Connected" };
286
+ #if MBED_CONF_MBED_TRACE_ENABLE
287
+ static const char *strings[] = { " Init" , " Power" , " Device ready" , " SIM pin" , " Registering network" , " Manual registering" , " Attaching network" , " Activating PDP Context" , " Connecting network" , " Connected" };
283
288
return strings[state];
289
+ #else
290
+ return NULL ;
291
+ #endif // #if MBED_CONF_MBED_TRACE_ENABLE
284
292
}
285
293
286
294
nsapi_error_t CellularConnectionFSM::is_automatic_registering (bool & auto_reg)
@@ -294,6 +302,54 @@ nsapi_error_t CellularConnectionFSM::is_automatic_registering(bool& auto_reg)
294
302
return err;
295
303
}
296
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
+ }
342
+ names_list.delete_all ();
343
+ return false ;
344
+ }
345
+ }
346
+ }
347
+ names_list.delete_all ();
348
+ }
349
+
350
+ return false ;
351
+ }
352
+
297
353
nsapi_error_t CellularConnectionFSM::continue_from_state (CellularState state)
298
354
{
299
355
tr_info (" Continue state from %s to %s" , get_state_string ((CellularConnectionFSM::CellularState)_state),
@@ -330,6 +386,7 @@ void CellularConnectionFSM::enter_to_state(CellularState state)
330
386
{
331
387
_next_state = state;
332
388
_retry_count = 0 ;
389
+ _command_success = false ;
333
390
}
334
391
335
392
void CellularConnectionFSM::retry_state_or_fail ()
@@ -406,7 +463,11 @@ void CellularConnectionFSM::state_sim_pin()
406
463
_cellularDevice->set_timeout (TIMEOUT_SIM_PIN);
407
464
tr_info (" Sim state (timeout %d ms)" , TIMEOUT_SIM_PIN);
408
465
if (open_sim ()) {
409
- enter_to_state (STATE_REGISTERING_NETWORK);
466
+ if (_plmn) {
467
+ enter_to_state (STATE_MANUAL_REGISTERING_NETWORK);
468
+ } else {
469
+ enter_to_state (STATE_REGISTERING_NETWORK);
470
+ }
410
471
} else {
411
472
retry_state_or_fail ();
412
473
}
@@ -421,7 +482,7 @@ void CellularConnectionFSM::state_registering()
421
482
} else {
422
483
bool auto_reg = false ;
423
484
nsapi_error_t err = is_automatic_registering (auto_reg);
424
- if (err == NSAPI_ERROR_OK && !auto_reg) { // when we support plmn add this : || plmn
485
+ if (err == NSAPI_ERROR_OK && !auto_reg) {
425
486
// automatic registering is not on, set registration and retry
426
487
_cellularDevice->set_timeout (TIMEOUT_REGISTRATION);
427
488
set_network_registration ();
@@ -430,6 +491,24 @@ void CellularConnectionFSM::state_registering()
430
491
}
431
492
}
432
493
494
+ // only used when _plmn is set
495
+ void CellularConnectionFSM::state_manual_registering_network ()
496
+ {
497
+ _cellularDevice->set_timeout (TIMEOUT_REGISTRATION);
498
+ tr_info (" state_manual_registering_network" );
499
+ if (!_plmn_network_found) {
500
+ if (is_registered () && is_registered_to_plmn ()) {
501
+ _plmn_network_found = true ;
502
+ enter_to_state (STATE_ATTACHING_NETWORK);
503
+ } else {
504
+ if (!_command_success) {
505
+ _command_success = set_network_registration ();
506
+ }
507
+ retry_state_or_fail ();
508
+ }
509
+ }
510
+ }
511
+
433
512
void CellularConnectionFSM::state_attaching ()
434
513
{
435
514
_cellularDevice->set_timeout (TIMEOUT_CONNECT);
@@ -438,7 +517,9 @@ void CellularConnectionFSM::state_attaching()
438
517
if (attach_status == CellularNetwork::Attached) {
439
518
enter_to_state (STATE_ACTIVATING_PDP_CONTEXT);
440
519
} else {
441
- set_attach_network ();
520
+ if (!_command_success) {
521
+ _command_success = set_attach_network ();
522
+ }
442
523
retry_state_or_fail ();
443
524
}
444
525
} else {
@@ -500,6 +581,9 @@ void CellularConnectionFSM::event()
500
581
case STATE_REGISTERING_NETWORK:
501
582
state_registering ();
502
583
break ;
584
+ case STATE_MANUAL_REGISTERING_NETWORK:
585
+ state_manual_registering_network ();
586
+ break ;
503
587
case STATE_ATTACHING_NETWORK:
504
588
state_attaching ();
505
589
break ;
@@ -576,13 +660,23 @@ void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)>
576
660
577
661
void CellularConnectionFSM::network_callback (nsapi_event_t ev, intptr_t ptr)
578
662
{
579
-
580
- tr_info ( " FSM: network_callback called with event: %d, intptr: %d " , ev, ptr);
581
- if (( cellular_connection_status_t )ev == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK ) {
663
+ tr_info ( " FSM: network_callback called with event: %d, intptr: %d, _state: %s " , ev, ptr, get_state_string (_state));
664
+ if (( cellular_connection_status_t )ev == CellularRegistrationStatusChanged &&
665
+ (_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK) ) {
582
666
// expect packet data so only these states are valid
583
- if (ptr == CellularNetwork::RegisteredHomeNetwork && CellularNetwork::RegisteredRoaming) {
584
- _queue.cancel (_event_id);
585
- continue_from_state (STATE_ATTACHING_NETWORK);
667
+ if (ptr == CellularNetwork::RegisteredHomeNetwork || ptr == CellularNetwork::RegisteredRoaming) {
668
+ if (_plmn) {
669
+ if (is_registered_to_plmn ()) {
670
+ if (!_plmn_network_found) {
671
+ _plmn_network_found = true ;
672
+ _queue.cancel (_event_id);
673
+ continue_from_state (STATE_ATTACHING_NETWORK);
674
+ }
675
+ }
676
+ } else {
677
+ _queue.cancel (_event_id);
678
+ continue_from_state (STATE_ATTACHING_NETWORK);
679
+ }
586
680
}
587
681
}
588
682
0 commit comments