Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CellularConnectionFSM.cpp
00001 /* 00002 * Copyright (c) 2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "CellularConnectionFSM.h" 00019 00020 #ifdef CELLULAR_DEVICE 00021 00022 #ifndef MBED_TRACE_MAX_LEVEL 00023 #define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO 00024 #endif 00025 #include "CellularLog.h" 00026 #include "CellularCommon.h" 00027 #include "CellularDevice.h" 00028 #include "CellularUtil.h" 00029 00030 // timeout to wait for AT responses 00031 #define TIMEOUT_POWER_ON (1*1000) 00032 #define TIMEOUT_SIM_PIN (1*1000) 00033 #define TIMEOUT_NETWORK (10*1000) 00034 #define TIMEOUT_CONNECT (60*1000) 00035 #define TIMEOUT_REGISTRATION (180*1000) 00036 00037 // maximum time when retrying network register, attach and connect in seconds ( 20minutes ) 00038 #define TIMEOUT_NETWORK_MAX (20*60) 00039 00040 #define RETRY_COUNT_DEFAULT 3 00041 00042 namespace mbed { 00043 00044 CellularConnectionFSM::CellularConnectionFSM() : 00045 _serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _event_status_cb(0), _network(0), _power(0), _sim(0), 00046 _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _event_timeout(-1), 00047 _at_queue(0), _event_id(0), _plmn(0), _command_success(false), _plmn_network_found(false) 00048 { 00049 memset(_sim_pin, 0, sizeof(_sim_pin)); 00050 #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0 00051 _start_time = 0; 00052 #else 00053 // so that not every device don't start at the exact same time (for example after power outage) 00054 _start_time = rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY); 00055 #endif // MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY 00056 00057 // set initial retry values in seconds 00058 _retry_timeout_array[0] = 1; // double time on each retry in order to keep network happy 00059 _retry_timeout_array[1] = 2; 00060 _retry_timeout_array[2] = 4; 00061 _retry_timeout_array[3] = 8; 00062 _retry_timeout_array[4] = 16; 00063 _retry_timeout_array[5] = 32; 00064 _retry_timeout_array[6] = 64; 00065 _retry_timeout_array[7] = 128; // if around two minutes was not enough then let's wait much longer 00066 _retry_timeout_array[8] = 600; 00067 _retry_timeout_array[9] = TIMEOUT_NETWORK_MAX; 00068 _retry_array_length = MAX_RETRY_ARRAY_SIZE; 00069 } 00070 00071 CellularConnectionFSM::~CellularConnectionFSM() 00072 { 00073 stop(); 00074 } 00075 00076 void CellularConnectionFSM::stop() 00077 { 00078 _queue.cancel(_event_id); 00079 _queue.break_dispatch(); 00080 00081 if (_queue_thread) { 00082 _queue_thread->terminate(); 00083 delete _queue_thread; 00084 _queue_thread = NULL; 00085 } 00086 00087 if (_power) { 00088 _cellularDevice->close_power(); 00089 _power = NULL; 00090 } 00091 00092 if (_network) { 00093 _cellularDevice->close_network(); 00094 _network = NULL; 00095 } 00096 00097 if (_sim) { 00098 _cellularDevice->close_sim(); 00099 _sim = NULL; 00100 } 00101 00102 _state = STATE_INIT; 00103 _next_state = _state; 00104 } 00105 00106 nsapi_error_t CellularConnectionFSM::init() 00107 { 00108 tr_info("CELLULAR_DEVICE: %s", CELLULAR_STRINGIFY(CELLULAR_DEVICE)); 00109 _cellularDevice = CellularDevice::get_default_instance(); 00110 if (!_cellularDevice) { 00111 stop(); 00112 return NSAPI_ERROR_NO_MEMORY ; 00113 } 00114 00115 _power = _cellularDevice->open_power(_serial); 00116 if (!_power) { 00117 stop(); 00118 return NSAPI_ERROR_NO_MEMORY ; 00119 } 00120 00121 _network = _cellularDevice->open_network(_serial); 00122 if (!_network) { 00123 stop(); 00124 return NSAPI_ERROR_NO_MEMORY ; 00125 } 00126 00127 _sim = _cellularDevice->open_sim(_serial); 00128 if (!_sim) { 00129 stop(); 00130 return NSAPI_ERROR_NO_MEMORY ; 00131 } 00132 00133 _at_queue = _cellularDevice->get_queue(); 00134 _at_queue->chain(&_queue); 00135 00136 _retry_count = 0; 00137 _state = STATE_INIT; 00138 _next_state = STATE_INIT; 00139 00140 return _network->init(); 00141 } 00142 00143 bool CellularConnectionFSM::power_on() 00144 { 00145 nsapi_error_t err = _power->on(); 00146 if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED ) { 00147 tr_warn("Cellular start failed. Power off/on."); 00148 err = _power->off(); 00149 if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED ) { 00150 tr_error("Cellular power down failing after failed power up attempt!"); 00151 } 00152 return false; 00153 } 00154 return true; 00155 } 00156 00157 void CellularConnectionFSM::set_sim_pin(const char *sim_pin) 00158 { 00159 strncpy(_sim_pin, sim_pin, sizeof(_sim_pin)); 00160 _sim_pin[sizeof(_sim_pin) - 1] = '\0'; 00161 } 00162 00163 void CellularConnectionFSM::set_plmn(const char *plmn) 00164 { 00165 _plmn = plmn; 00166 } 00167 00168 bool CellularConnectionFSM::open_sim() 00169 { 00170 CellularSIM::SimState state = CellularSIM::SimStateUnknown; 00171 // wait until SIM is readable 00172 // here you could add wait(secs) if you know start delay of your SIM 00173 if (_sim->get_sim_state(state) != NSAPI_ERROR_OK ) { 00174 tr_info("Waiting for SIM (err while reading)..."); 00175 if (_event_status_cb) { 00176 _event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state); 00177 } 00178 return false; 00179 } 00180 00181 // report current state so callback can set sim pin if needed 00182 if (_event_status_cb) { 00183 _event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state); 00184 } 00185 00186 if (state == CellularSIM::SimStatePinNeeded) { 00187 if (strlen(_sim_pin)) { 00188 tr_info("SIM pin required, entering pin"); 00189 nsapi_error_t err = _sim->set_pin(_sim_pin); 00190 if (err) { 00191 tr_error("SIM pin set failed with: %d, bailing out...", err); 00192 } 00193 } else { 00194 // No sim pin provided even it's needed, stop state machine 00195 tr_error("PIN required but No SIM pin provided."); 00196 _retry_count = MAX_RETRY_ARRAY_SIZE; 00197 return false; 00198 } 00199 } 00200 00201 return state == CellularSIM::SimStateReady; 00202 } 00203 00204 bool CellularConnectionFSM::is_registered() 00205 { 00206 CellularNetwork::RegistrationStatus status; 00207 bool is_registered = false; 00208 00209 for (int type = 0; type < CellularNetwork::C_MAX; type++) { 00210 if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) { 00211 tr_debug("get_network_registration: type=%d, status=%d", type, status); 00212 if (is_registered) { 00213 break; 00214 } 00215 } 00216 } 00217 00218 return is_registered; 00219 } 00220 00221 bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type, 00222 CellularNetwork::RegistrationStatus &status, bool &is_registered) 00223 { 00224 is_registered = false; 00225 bool is_roaming = false; 00226 nsapi_error_t err = _network->get_registration_status(type, status); 00227 if (err != NSAPI_ERROR_OK ) { 00228 if (err != NSAPI_ERROR_UNSUPPORTED ) { 00229 tr_warn("Get network registration failed (type %d)!", type); 00230 } 00231 return false; 00232 } 00233 switch (status) { 00234 case CellularNetwork::RegisteredRoaming: 00235 is_roaming = true; 00236 // fall-through 00237 case CellularNetwork::RegisteredHomeNetwork: 00238 is_registered = true; 00239 break; 00240 case CellularNetwork::RegisteredSMSOnlyRoaming: 00241 is_roaming = true; 00242 // fall-through 00243 case CellularNetwork::RegisteredSMSOnlyHome: 00244 tr_warn("SMS only network registration!"); 00245 break; 00246 case CellularNetwork::RegisteredCSFBNotPreferredRoaming: 00247 is_roaming = true; 00248 // fall-through 00249 case CellularNetwork::RegisteredCSFBNotPreferredHome: 00250 tr_warn("Not preferred network registration!"); 00251 break; 00252 case CellularNetwork::AttachedEmergencyOnly: 00253 tr_warn("Emergency only network registration!"); 00254 break; 00255 case CellularNetwork::RegistrationDenied: 00256 case CellularNetwork::NotRegistered: 00257 case CellularNetwork::Unknown: 00258 case CellularNetwork::SearchingNetwork: 00259 default: 00260 break; 00261 } 00262 00263 if (is_roaming) { 00264 tr_warn("Roaming cellular network!"); 00265 } 00266 00267 return true; 00268 } 00269 00270 void CellularConnectionFSM::report_failure(const char *msg) 00271 { 00272 tr_error("Cellular network failed: %s", msg); 00273 if (_status_callback) { 00274 _status_callback(_state, _next_state); 00275 } 00276 } 00277 00278 const char *CellularConnectionFSM::get_state_string(CellularState state) 00279 { 00280 #if MBED_CONF_MBED_TRACE_ENABLE 00281 static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Manual registering", "Attaching network", "Activating PDP Context", "Connecting network", "Connected"}; 00282 return strings[state]; 00283 #else 00284 return NULL; 00285 #endif // #if MBED_CONF_MBED_TRACE_ENABLE 00286 } 00287 00288 bool CellularConnectionFSM::is_registered_to_plmn() 00289 { 00290 int format; 00291 CellularNetwork::operator_t op; 00292 00293 nsapi_error_t err = _network->get_operator_params(format, op); 00294 if (err == NSAPI_ERROR_OK ) { 00295 if (format == 2) { 00296 // great, numeric format we can do comparison for that 00297 if (strcmp(op.op_num, _plmn) == 0) { 00298 return true; 00299 } 00300 return false; 00301 } 00302 00303 // format was alpha, get operator names to do the comparing 00304 CellularNetwork::operator_names_list names_list; 00305 nsapi_error_t err = _network->get_operator_names(names_list); 00306 if (err == NSAPI_ERROR_OK ) { 00307 CellularNetwork::operator_names_t *op_names = names_list.get_head(); 00308 bool found_match = false; 00309 while (op_names) { 00310 if (format == 0) { 00311 if (strcmp(op.op_long, op_names->alpha) == 0) { 00312 found_match = true; 00313 } 00314 } else if (format == 1) { 00315 if (strcmp(op.op_short, op_names->alpha) == 0) { 00316 found_match = true; 00317 } 00318 } 00319 00320 if (found_match) { 00321 if (strcmp(_plmn, op_names->numeric)) { 00322 names_list.delete_all(); 00323 return true; 00324 } 00325 names_list.delete_all(); 00326 return false; 00327 } 00328 } 00329 } 00330 names_list.delete_all(); 00331 } 00332 00333 return false; 00334 } 00335 00336 nsapi_error_t CellularConnectionFSM::continue_from_state(CellularState state) 00337 { 00338 tr_info("Continue state from %s to %s", get_state_string((CellularConnectionFSM::CellularState)_state), 00339 get_state_string((CellularConnectionFSM::CellularState)state)); 00340 _state = state; 00341 _next_state = state; 00342 _retry_count = 0; 00343 if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) { 00344 stop(); 00345 return NSAPI_ERROR_NO_MEMORY ; 00346 } 00347 00348 return NSAPI_ERROR_OK ; 00349 } 00350 00351 nsapi_error_t CellularConnectionFSM::continue_to_state(CellularState state) 00352 { 00353 MBED_ASSERT(_cellularDevice); 00354 _retry_count = 0; 00355 if (state < _state) { 00356 _state = state; 00357 } else { 00358 // update next state so that we don't continue from previous state 00359 _state = _next_state; 00360 } 00361 if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) { 00362 stop(); 00363 return NSAPI_ERROR_NO_MEMORY ; 00364 } 00365 00366 return NSAPI_ERROR_OK ; 00367 } 00368 00369 void CellularConnectionFSM::enter_to_state(CellularState state) 00370 { 00371 _next_state = state; 00372 _retry_count = 0; 00373 _command_success = false; 00374 } 00375 00376 void CellularConnectionFSM::retry_state_or_fail() 00377 { 00378 if (++_retry_count < MAX_RETRY_ARRAY_SIZE) { 00379 tr_debug("Retry State %s, retry %d/%d", get_state_string(_state), _retry_count, MAX_RETRY_ARRAY_SIZE); 00380 _event_timeout = _retry_timeout_array[_retry_count]; 00381 } else { 00382 report_failure(get_state_string(_state)); 00383 return; 00384 } 00385 } 00386 00387 void CellularConnectionFSM::state_init() 00388 { 00389 // we should check that if power is already on then we can jump to device ready state 00390 _cellularDevice->set_timeout(TIMEOUT_POWER_ON); 00391 tr_info("Cellular state init (timeout %d ms)", TIMEOUT_POWER_ON); 00392 nsapi_error_t err = _power->is_device_ready(); 00393 if (err != NSAPI_ERROR_OK ) { 00394 _event_timeout = _start_time; 00395 tr_info("Init state, waiting %d ms before POWER state)", _start_time); 00396 enter_to_state(STATE_POWER_ON); 00397 } else { 00398 tr_info("Device was ready to accept commands, jump to device ready"); 00399 enter_to_state(STATE_DEVICE_READY); 00400 } 00401 } 00402 00403 void CellularConnectionFSM::state_power_on() 00404 { 00405 _cellularDevice->set_timeout(TIMEOUT_POWER_ON); 00406 tr_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON); 00407 if (power_on()) { 00408 enter_to_state(STATE_DEVICE_READY); 00409 } else { 00410 // retry to power on device 00411 retry_state_or_fail(); 00412 } 00413 } 00414 00415 bool CellularConnectionFSM::device_ready() 00416 { 00417 if (_cellularDevice->init_module(_serial) != NSAPI_ERROR_OK ) { 00418 return false; 00419 } 00420 tr_info("Cellular device ready"); 00421 if (_event_status_cb) { 00422 _event_status_cb((nsapi_event_t)CellularDeviceReady, 0); 00423 } 00424 _power->remove_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb)); 00425 _cellularDevice->close_power(); 00426 _power = NULL; 00427 return true; 00428 } 00429 00430 void CellularConnectionFSM::state_device_ready() 00431 { 00432 _cellularDevice->set_timeout(TIMEOUT_POWER_ON); 00433 if (_power->set_at_mode() == NSAPI_ERROR_OK ) { 00434 if (device_ready()) { 00435 enter_to_state(STATE_SIM_PIN); 00436 } 00437 } else { 00438 if (_retry_count == 0) { 00439 (void)_power->set_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb)); 00440 } 00441 retry_state_or_fail(); 00442 } 00443 } 00444 00445 void CellularConnectionFSM::state_sim_pin() 00446 { 00447 _cellularDevice->set_timeout(TIMEOUT_SIM_PIN); 00448 tr_info("Sim state (timeout %d ms)", TIMEOUT_SIM_PIN); 00449 if (open_sim()) { 00450 bool success = false; 00451 for (int type = 0; type < CellularNetwork::C_MAX; type++) { 00452 if (!_network->set_registration_urc((CellularNetwork::RegistrationType)type, true)) { 00453 success = true; 00454 } 00455 } 00456 if (!success) { 00457 tr_warn("Failed to set any URC's for registration"); 00458 retry_state_or_fail(); 00459 return; 00460 } 00461 if (_plmn) { 00462 enter_to_state(STATE_MANUAL_REGISTERING_NETWORK); 00463 } else { 00464 enter_to_state(STATE_REGISTERING_NETWORK); 00465 } 00466 } else { 00467 retry_state_or_fail(); 00468 } 00469 } 00470 00471 void CellularConnectionFSM::state_registering() 00472 { 00473 _cellularDevice->set_timeout(TIMEOUT_NETWORK); 00474 if (is_registered()) { 00475 // we are already registered, go to attach 00476 enter_to_state(STATE_ATTACHING_NETWORK); 00477 } else { 00478 _cellularDevice->set_timeout(TIMEOUT_REGISTRATION); 00479 if (!_command_success) { 00480 _command_success = (_network->set_registration() == NSAPI_ERROR_OK ); 00481 } 00482 retry_state_or_fail(); 00483 } 00484 } 00485 00486 // only used when _plmn is set 00487 void CellularConnectionFSM::state_manual_registering_network() 00488 { 00489 _cellularDevice->set_timeout(TIMEOUT_REGISTRATION); 00490 tr_info("state_manual_registering_network"); 00491 if (!_plmn_network_found) { 00492 if (is_registered() && is_registered_to_plmn()) { 00493 _plmn_network_found = true; 00494 enter_to_state(STATE_ATTACHING_NETWORK); 00495 } else { 00496 if (!_command_success) { 00497 _command_success = (_network->set_registration(_plmn) == NSAPI_ERROR_OK ); 00498 } 00499 retry_state_or_fail(); 00500 } 00501 } 00502 } 00503 00504 void CellularConnectionFSM::state_attaching() 00505 { 00506 _cellularDevice->set_timeout(TIMEOUT_CONNECT); 00507 if (_network->set_attach() == NSAPI_ERROR_OK ) { 00508 _cellularDevice->close_sim(); 00509 _sim = NULL; 00510 enter_to_state(STATE_ACTIVATING_PDP_CONTEXT); 00511 } else { 00512 retry_state_or_fail(); 00513 } 00514 } 00515 00516 void CellularConnectionFSM::state_activating_pdp_context() 00517 { 00518 _cellularDevice->set_timeout(TIMEOUT_CONNECT); 00519 tr_info("Activate PDP Context (timeout %d ms)", TIMEOUT_CONNECT); 00520 if (_network->activate_context() == NSAPI_ERROR_OK ) { 00521 // when using modems stack connect is synchronous 00522 _next_state = STATE_CONNECTING_NETWORK; 00523 } else { 00524 retry_state_or_fail(); 00525 } 00526 } 00527 00528 void CellularConnectionFSM::state_connect_to_network() 00529 { 00530 _cellularDevice->set_timeout(TIMEOUT_CONNECT); 00531 tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_CONNECT); 00532 if (_network->connect() == NSAPI_ERROR_OK ) { 00533 _cellularDevice->set_timeout(TIMEOUT_NETWORK); 00534 tr_debug("Connected to cellular network, set at timeout (timeout %d ms)", TIMEOUT_NETWORK); 00535 // when using modems stack connect is synchronous 00536 _next_state = STATE_CONNECTED; 00537 } else { 00538 retry_state_or_fail(); 00539 } 00540 } 00541 00542 void CellularConnectionFSM::state_connected() 00543 { 00544 _cellularDevice->set_timeout(TIMEOUT_NETWORK); 00545 tr_debug("Cellular ready! (timeout %d ms)", TIMEOUT_NETWORK); 00546 if (_status_callback) { 00547 _status_callback(_state, _next_state); 00548 } 00549 } 00550 00551 void CellularConnectionFSM::event() 00552 { 00553 _event_timeout = -1; 00554 switch (_state) { 00555 case STATE_INIT: 00556 state_init(); 00557 break; 00558 case STATE_POWER_ON: 00559 state_power_on(); 00560 break; 00561 case STATE_DEVICE_READY: 00562 state_device_ready(); 00563 break; 00564 case STATE_SIM_PIN: 00565 state_sim_pin(); 00566 break; 00567 case STATE_REGISTERING_NETWORK: 00568 state_registering(); 00569 break; 00570 case STATE_MANUAL_REGISTERING_NETWORK: 00571 state_manual_registering_network(); 00572 break; 00573 case STATE_ATTACHING_NETWORK: 00574 state_attaching(); 00575 break; 00576 case STATE_ACTIVATING_PDP_CONTEXT: 00577 state_activating_pdp_context(); 00578 break; 00579 case STATE_CONNECTING_NETWORK: 00580 state_connect_to_network(); 00581 break; 00582 case STATE_CONNECTED: 00583 state_connected(); 00584 break; 00585 default: 00586 MBED_ASSERT(0); 00587 break; 00588 } 00589 00590 if (_next_state != _state || _event_timeout >= 0) { 00591 if (_next_state != _state) { // state exit condition 00592 tr_info("Cellular state from %s to %s", get_state_string((CellularConnectionFSM::CellularState)_state), 00593 get_state_string((CellularConnectionFSM::CellularState)_next_state)); 00594 if (_status_callback) { 00595 if (!_status_callback(_state, _next_state)) { 00596 return; 00597 } 00598 } 00599 } else { 00600 tr_info("Cellular event in %d seconds", _event_timeout); 00601 } 00602 _state = _next_state; 00603 if (_event_timeout == -1) { 00604 _event_timeout = 0; 00605 } 00606 _event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularConnectionFSM::event)); 00607 if (!_event_id) { 00608 report_failure("Cellular event failure!"); 00609 return; 00610 } 00611 } 00612 } 00613 00614 nsapi_error_t CellularConnectionFSM::start_dispatch() 00615 { 00616 MBED_ASSERT(!_queue_thread); 00617 00618 _queue_thread = new rtos::Thread(osPriorityNormal, 2048); 00619 if (!_queue_thread) { 00620 stop(); 00621 return NSAPI_ERROR_NO_MEMORY ; 00622 } 00623 if (_queue_thread->start(callback(&_queue, &events::EventQueue::dispatch_forever)) != osOK) { 00624 stop(); 00625 return NSAPI_ERROR_NO_MEMORY ; 00626 } 00627 00628 return NSAPI_ERROR_OK ; 00629 } 00630 00631 void CellularConnectionFSM::set_serial(UARTSerial *serial) 00632 { 00633 _serial = serial; 00634 } 00635 00636 void CellularConnectionFSM::set_callback(mbed::Callback<bool(int, int)> status_callback) 00637 { 00638 _status_callback = status_callback; 00639 } 00640 00641 void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) 00642 { 00643 MBED_ASSERT(_network); 00644 _event_status_cb = status_cb; 00645 if (status_cb) { 00646 _network->attach(callback(this, &CellularConnectionFSM::network_callback)); 00647 } else { 00648 _network->attach(NULL); 00649 } 00650 } 00651 00652 void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr) 00653 { 00654 tr_info("FSM: network_callback called with event: %d, intptr: %d, _state: %s", ev, ptr, get_state_string(_state)); 00655 if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && 00656 (_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK)) { 00657 // expect packet data so only these states are valid 00658 if (ptr == CellularNetwork::RegisteredHomeNetwork || ptr == CellularNetwork::RegisteredRoaming) { 00659 if (_plmn) { 00660 if (is_registered_to_plmn()) { 00661 if (!_plmn_network_found) { 00662 _plmn_network_found = true; 00663 _queue.cancel(_event_id); 00664 continue_from_state(STATE_ATTACHING_NETWORK); 00665 } 00666 } 00667 } else { 00668 _queue.cancel(_event_id); 00669 continue_from_state(STATE_ATTACHING_NETWORK); 00670 } 00671 } 00672 } 00673 00674 if (_event_status_cb) { 00675 _event_status_cb(ev, ptr); 00676 } 00677 } 00678 00679 void CellularConnectionFSM::ready_urc_cb() 00680 { 00681 tr_debug("Device ready URC func called"); 00682 if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK ) { 00683 tr_debug("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next"); 00684 if (device_ready()) { 00685 _queue.cancel(_event_id); 00686 continue_from_state(STATE_SIM_PIN); 00687 } 00688 } 00689 } 00690 00691 events::EventQueue *CellularConnectionFSM::get_queue() 00692 { 00693 return &_queue; 00694 } 00695 00696 CellularNetwork *CellularConnectionFSM::get_network() 00697 { 00698 return _network; 00699 } 00700 00701 CellularDevice *CellularConnectionFSM::get_device() 00702 { 00703 return _cellularDevice; 00704 } 00705 00706 CellularSIM *CellularConnectionFSM::get_sim() 00707 { 00708 return _sim; 00709 } 00710 00711 NetworkStack *CellularConnectionFSM::get_stack() 00712 { 00713 return _cellularDevice->get_stack(); 00714 } 00715 00716 void CellularConnectionFSM::set_retry_timeout_array(uint16_t timeout[], int array_len) 00717 { 00718 _retry_array_length = array_len > MAX_RETRY_ARRAY_SIZE ? MAX_RETRY_ARRAY_SIZE : array_len; 00719 00720 for (int i = 0; i < _retry_array_length; i++) { 00721 _retry_timeout_array[i] = timeout[i]; 00722 } 00723 } 00724 00725 } // namespace 00726 00727 #endif // CELLULAR_DEVICE
Generated on Tue Aug 9 2022 00:37:03 by
