Committer:
kevman
Date:
Wed Nov 28 15:10:15 2018 +0000
Revision:
0:38ceb79fef03
RTC modified

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /*
kevman 0:38ceb79fef03 2 * Copyright (c) 2017, Arm Limited and affiliates.
kevman 0:38ceb79fef03 3 * SPDX-License-Identifier: Apache-2.0
kevman 0:38ceb79fef03 4 *
kevman 0:38ceb79fef03 5 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 0:38ceb79fef03 6 * you may not use this file except in compliance with the License.
kevman 0:38ceb79fef03 7 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 8 *
kevman 0:38ceb79fef03 9 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 10 *
kevman 0:38ceb79fef03 11 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 12 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 0:38ceb79fef03 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 14 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 15 * limitations under the License.
kevman 0:38ceb79fef03 16 */
kevman 0:38ceb79fef03 17
kevman 0:38ceb79fef03 18 #include "CellularConnectionFSM.h"
kevman 0:38ceb79fef03 19
kevman 0:38ceb79fef03 20 #ifdef CELLULAR_DEVICE
kevman 0:38ceb79fef03 21
kevman 0:38ceb79fef03 22 #ifndef MBED_TRACE_MAX_LEVEL
kevman 0:38ceb79fef03 23 #define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO
kevman 0:38ceb79fef03 24 #endif
kevman 0:38ceb79fef03 25 #include "CellularLog.h"
kevman 0:38ceb79fef03 26 #include "CellularCommon.h"
kevman 0:38ceb79fef03 27
kevman 0:38ceb79fef03 28 // timeout to wait for AT responses
kevman 0:38ceb79fef03 29 #define TIMEOUT_POWER_ON (1*1000)
kevman 0:38ceb79fef03 30 #define TIMEOUT_SIM_PIN (1*1000)
kevman 0:38ceb79fef03 31 #define TIMEOUT_NETWORK (10*1000)
kevman 0:38ceb79fef03 32 #define TIMEOUT_CONNECT (60*1000)
kevman 0:38ceb79fef03 33 #define TIMEOUT_REGISTRATION (180*1000)
kevman 0:38ceb79fef03 34
kevman 0:38ceb79fef03 35 // maximum time when retrying network register, attach and connect in seconds ( 20minutes )
kevman 0:38ceb79fef03 36 #define TIMEOUT_NETWORK_MAX (20*60)
kevman 0:38ceb79fef03 37
kevman 0:38ceb79fef03 38 #define RETRY_COUNT_DEFAULT 3
kevman 0:38ceb79fef03 39
kevman 0:38ceb79fef03 40 namespace mbed {
kevman 0:38ceb79fef03 41
kevman 0:38ceb79fef03 42 CellularConnectionFSM::CellularConnectionFSM() :
kevman 0:38ceb79fef03 43 _serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _event_status_cb(0), _network(0), _power(0), _sim(0),
kevman 0:38ceb79fef03 44 _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _event_timeout(-1),
kevman 0:38ceb79fef03 45 _at_queue(8 * EVENTS_EVENT_SIZE), _event_id(0), _plmn(0), _command_success(false), _plmn_network_found(false)
kevman 0:38ceb79fef03 46 {
kevman 0:38ceb79fef03 47 memset(_sim_pin, 0, sizeof(_sim_pin));
kevman 0:38ceb79fef03 48 #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
kevman 0:38ceb79fef03 49 _start_time = 0;
kevman 0:38ceb79fef03 50 #else
kevman 0:38ceb79fef03 51 // so that not every device don't start at the exact same time (for example after power outage)
kevman 0:38ceb79fef03 52 _start_time = rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY);
kevman 0:38ceb79fef03 53 #endif // MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY
kevman 0:38ceb79fef03 54
kevman 0:38ceb79fef03 55 // set initial retry values in seconds
kevman 0:38ceb79fef03 56 _retry_timeout_array[0] = 1; // double time on each retry in order to keep network happy
kevman 0:38ceb79fef03 57 _retry_timeout_array[1] = 2;
kevman 0:38ceb79fef03 58 _retry_timeout_array[2] = 4;
kevman 0:38ceb79fef03 59 _retry_timeout_array[3] = 8;
kevman 0:38ceb79fef03 60 _retry_timeout_array[4] = 16;
kevman 0:38ceb79fef03 61 _retry_timeout_array[5] = 32;
kevman 0:38ceb79fef03 62 _retry_timeout_array[6] = 64;
kevman 0:38ceb79fef03 63 _retry_timeout_array[7] = 128; // if around two minutes was not enough then let's wait much longer
kevman 0:38ceb79fef03 64 _retry_timeout_array[8] = 600;
kevman 0:38ceb79fef03 65 _retry_timeout_array[9] = TIMEOUT_NETWORK_MAX;
kevman 0:38ceb79fef03 66 _retry_array_length = MAX_RETRY_ARRAY_SIZE;
kevman 0:38ceb79fef03 67 }
kevman 0:38ceb79fef03 68
kevman 0:38ceb79fef03 69 CellularConnectionFSM::~CellularConnectionFSM()
kevman 0:38ceb79fef03 70 {
kevman 0:38ceb79fef03 71 stop();
kevman 0:38ceb79fef03 72 }
kevman 0:38ceb79fef03 73
kevman 0:38ceb79fef03 74 void CellularConnectionFSM::stop()
kevman 0:38ceb79fef03 75 {
kevman 0:38ceb79fef03 76 _queue.cancel(_event_id);
kevman 0:38ceb79fef03 77 _queue.break_dispatch();
kevman 0:38ceb79fef03 78
kevman 0:38ceb79fef03 79 if (_queue_thread) {
kevman 0:38ceb79fef03 80 _queue_thread->terminate();
kevman 0:38ceb79fef03 81 delete _queue_thread;
kevman 0:38ceb79fef03 82 _queue_thread = NULL;
kevman 0:38ceb79fef03 83 }
kevman 0:38ceb79fef03 84
kevman 0:38ceb79fef03 85 delete _cellularDevice;
kevman 0:38ceb79fef03 86 _cellularDevice = NULL;
kevman 0:38ceb79fef03 87 // _cellularDevice closes all interfaces in destructor
kevman 0:38ceb79fef03 88 _power = NULL;
kevman 0:38ceb79fef03 89 _network = NULL;
kevman 0:38ceb79fef03 90 _sim = NULL;
kevman 0:38ceb79fef03 91
kevman 0:38ceb79fef03 92 _state = STATE_INIT;
kevman 0:38ceb79fef03 93 _next_state = _state;
kevman 0:38ceb79fef03 94 }
kevman 0:38ceb79fef03 95
kevman 0:38ceb79fef03 96 nsapi_error_t CellularConnectionFSM::init()
kevman 0:38ceb79fef03 97 {
kevman 0:38ceb79fef03 98 tr_info("CELLULAR_DEVICE: %s", CELLULAR_STRINGIFY(CELLULAR_DEVICE));
kevman 0:38ceb79fef03 99 _cellularDevice = new CELLULAR_DEVICE(_at_queue);
kevman 0:38ceb79fef03 100 if (!_cellularDevice) {
kevman 0:38ceb79fef03 101 stop();
kevman 0:38ceb79fef03 102 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 103 }
kevman 0:38ceb79fef03 104
kevman 0:38ceb79fef03 105 _power = _cellularDevice->open_power(_serial);
kevman 0:38ceb79fef03 106 if (!_power) {
kevman 0:38ceb79fef03 107 stop();
kevman 0:38ceb79fef03 108 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 109 }
kevman 0:38ceb79fef03 110
kevman 0:38ceb79fef03 111 _network = _cellularDevice->open_network(_serial);
kevman 0:38ceb79fef03 112 if (!_network) {
kevman 0:38ceb79fef03 113 stop();
kevman 0:38ceb79fef03 114 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 115 }
kevman 0:38ceb79fef03 116
kevman 0:38ceb79fef03 117 _sim = _cellularDevice->open_sim(_serial);
kevman 0:38ceb79fef03 118 if (!_sim) {
kevman 0:38ceb79fef03 119 stop();
kevman 0:38ceb79fef03 120 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 121 }
kevman 0:38ceb79fef03 122
kevman 0:38ceb79fef03 123 _at_queue.chain(&_queue);
kevman 0:38ceb79fef03 124
kevman 0:38ceb79fef03 125 _retry_count = 0;
kevman 0:38ceb79fef03 126 _state = STATE_INIT;
kevman 0:38ceb79fef03 127 _next_state = STATE_INIT;
kevman 0:38ceb79fef03 128
kevman 0:38ceb79fef03 129 return _network->init();
kevman 0:38ceb79fef03 130 }
kevman 0:38ceb79fef03 131
kevman 0:38ceb79fef03 132 bool CellularConnectionFSM::power_on()
kevman 0:38ceb79fef03 133 {
kevman 0:38ceb79fef03 134 nsapi_error_t err = _power->on();
kevman 0:38ceb79fef03 135 if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED) {
kevman 0:38ceb79fef03 136 tr_warn("Cellular start failed. Power off/on.");
kevman 0:38ceb79fef03 137 err = _power->off();
kevman 0:38ceb79fef03 138 if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED) {
kevman 0:38ceb79fef03 139 tr_error("Cellular power down failing after failed power up attempt!");
kevman 0:38ceb79fef03 140 }
kevman 0:38ceb79fef03 141 return false;
kevman 0:38ceb79fef03 142 }
kevman 0:38ceb79fef03 143 return true;
kevman 0:38ceb79fef03 144 }
kevman 0:38ceb79fef03 145
kevman 0:38ceb79fef03 146 void CellularConnectionFSM::set_sim_pin(const char *sim_pin)
kevman 0:38ceb79fef03 147 {
kevman 0:38ceb79fef03 148 strncpy(_sim_pin, sim_pin, sizeof(_sim_pin));
kevman 0:38ceb79fef03 149 _sim_pin[sizeof(_sim_pin) - 1] = '\0';
kevman 0:38ceb79fef03 150 }
kevman 0:38ceb79fef03 151
kevman 0:38ceb79fef03 152 void CellularConnectionFSM::set_plmn(const char *plmn)
kevman 0:38ceb79fef03 153 {
kevman 0:38ceb79fef03 154 _plmn = plmn;
kevman 0:38ceb79fef03 155 }
kevman 0:38ceb79fef03 156
kevman 0:38ceb79fef03 157 bool CellularConnectionFSM::open_sim()
kevman 0:38ceb79fef03 158 {
kevman 0:38ceb79fef03 159 CellularSIM::SimState state = CellularSIM::SimStateUnknown;
kevman 0:38ceb79fef03 160 // wait until SIM is readable
kevman 0:38ceb79fef03 161 // here you could add wait(secs) if you know start delay of your SIM
kevman 0:38ceb79fef03 162 if (_sim->get_sim_state(state) != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 163 tr_info("Waiting for SIM (err while reading)...");
kevman 0:38ceb79fef03 164 if (_event_status_cb) {
kevman 0:38ceb79fef03 165 _event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state);
kevman 0:38ceb79fef03 166 }
kevman 0:38ceb79fef03 167 return false;
kevman 0:38ceb79fef03 168 }
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 // report current state so callback can set sim pin if needed
kevman 0:38ceb79fef03 171 if (_event_status_cb) {
kevman 0:38ceb79fef03 172 _event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state);
kevman 0:38ceb79fef03 173 }
kevman 0:38ceb79fef03 174
kevman 0:38ceb79fef03 175 if (state == CellularSIM::SimStatePinNeeded) {
kevman 0:38ceb79fef03 176 if (strlen(_sim_pin)) {
kevman 0:38ceb79fef03 177 tr_info("SIM pin required, entering pin");
kevman 0:38ceb79fef03 178 nsapi_error_t err = _sim->set_pin(_sim_pin);
kevman 0:38ceb79fef03 179 if (err) {
kevman 0:38ceb79fef03 180 tr_error("SIM pin set failed with: %d, bailing out...", err);
kevman 0:38ceb79fef03 181 }
kevman 0:38ceb79fef03 182 } else {
kevman 0:38ceb79fef03 183 // No sim pin provided even it's needed, stop state machine
kevman 0:38ceb79fef03 184 tr_error("PIN required but No SIM pin provided.");
kevman 0:38ceb79fef03 185 _retry_count = MAX_RETRY_ARRAY_SIZE;
kevman 0:38ceb79fef03 186 return false;
kevman 0:38ceb79fef03 187 }
kevman 0:38ceb79fef03 188 }
kevman 0:38ceb79fef03 189
kevman 0:38ceb79fef03 190 return state == CellularSIM::SimStateReady;
kevman 0:38ceb79fef03 191 }
kevman 0:38ceb79fef03 192
kevman 0:38ceb79fef03 193 bool CellularConnectionFSM::is_registered()
kevman 0:38ceb79fef03 194 {
kevman 0:38ceb79fef03 195 CellularNetwork::RegistrationStatus status;
kevman 0:38ceb79fef03 196 bool is_registered = false;
kevman 0:38ceb79fef03 197
kevman 0:38ceb79fef03 198 for (int type = 0; type < CellularNetwork::C_MAX; type++) {
kevman 0:38ceb79fef03 199 if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) {
kevman 0:38ceb79fef03 200 tr_debug("get_network_registration: type=%d, status=%d", type, status);
kevman 0:38ceb79fef03 201 if (is_registered) {
kevman 0:38ceb79fef03 202 break;
kevman 0:38ceb79fef03 203 }
kevman 0:38ceb79fef03 204 }
kevman 0:38ceb79fef03 205 }
kevman 0:38ceb79fef03 206
kevman 0:38ceb79fef03 207 return is_registered;
kevman 0:38ceb79fef03 208 }
kevman 0:38ceb79fef03 209
kevman 0:38ceb79fef03 210 bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type,
kevman 0:38ceb79fef03 211 CellularNetwork::RegistrationStatus &status, bool &is_registered)
kevman 0:38ceb79fef03 212 {
kevman 0:38ceb79fef03 213 is_registered = false;
kevman 0:38ceb79fef03 214 bool is_roaming = false;
kevman 0:38ceb79fef03 215 nsapi_error_t err = _network->get_registration_status(type, status);
kevman 0:38ceb79fef03 216 if (err != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 217 if (err != NSAPI_ERROR_UNSUPPORTED) {
kevman 0:38ceb79fef03 218 tr_warn("Get network registration failed (type %d)!", type);
kevman 0:38ceb79fef03 219 }
kevman 0:38ceb79fef03 220 return false;
kevman 0:38ceb79fef03 221 }
kevman 0:38ceb79fef03 222 switch (status) {
kevman 0:38ceb79fef03 223 case CellularNetwork::RegisteredRoaming:
kevman 0:38ceb79fef03 224 is_roaming = true;
kevman 0:38ceb79fef03 225 // fall-through
kevman 0:38ceb79fef03 226 case CellularNetwork::RegisteredHomeNetwork:
kevman 0:38ceb79fef03 227 is_registered = true;
kevman 0:38ceb79fef03 228 break;
kevman 0:38ceb79fef03 229 case CellularNetwork::RegisteredSMSOnlyRoaming:
kevman 0:38ceb79fef03 230 is_roaming = true;
kevman 0:38ceb79fef03 231 // fall-through
kevman 0:38ceb79fef03 232 case CellularNetwork::RegisteredSMSOnlyHome:
kevman 0:38ceb79fef03 233 tr_warn("SMS only network registration!");
kevman 0:38ceb79fef03 234 break;
kevman 0:38ceb79fef03 235 case CellularNetwork::RegisteredCSFBNotPreferredRoaming:
kevman 0:38ceb79fef03 236 is_roaming = true;
kevman 0:38ceb79fef03 237 // fall-through
kevman 0:38ceb79fef03 238 case CellularNetwork::RegisteredCSFBNotPreferredHome:
kevman 0:38ceb79fef03 239 tr_warn("Not preferred network registration!");
kevman 0:38ceb79fef03 240 break;
kevman 0:38ceb79fef03 241 case CellularNetwork::AttachedEmergencyOnly:
kevman 0:38ceb79fef03 242 tr_warn("Emergency only network registration!");
kevman 0:38ceb79fef03 243 break;
kevman 0:38ceb79fef03 244 case CellularNetwork::RegistrationDenied:
kevman 0:38ceb79fef03 245 case CellularNetwork::NotRegistered:
kevman 0:38ceb79fef03 246 case CellularNetwork::Unknown:
kevman 0:38ceb79fef03 247 case CellularNetwork::SearchingNetwork:
kevman 0:38ceb79fef03 248 default:
kevman 0:38ceb79fef03 249 break;
kevman 0:38ceb79fef03 250 }
kevman 0:38ceb79fef03 251
kevman 0:38ceb79fef03 252 if (is_roaming) {
kevman 0:38ceb79fef03 253 tr_warn("Roaming cellular network!");
kevman 0:38ceb79fef03 254 }
kevman 0:38ceb79fef03 255
kevman 0:38ceb79fef03 256 return true;
kevman 0:38ceb79fef03 257 }
kevman 0:38ceb79fef03 258
kevman 0:38ceb79fef03 259 void CellularConnectionFSM::report_failure(const char *msg)
kevman 0:38ceb79fef03 260 {
kevman 0:38ceb79fef03 261 tr_error("Cellular network failed: %s", msg);
kevman 0:38ceb79fef03 262 if (_status_callback) {
kevman 0:38ceb79fef03 263 _status_callback(_state, _next_state);
kevman 0:38ceb79fef03 264 }
kevman 0:38ceb79fef03 265 }
kevman 0:38ceb79fef03 266
kevman 0:38ceb79fef03 267 const char *CellularConnectionFSM::get_state_string(CellularState state)
kevman 0:38ceb79fef03 268 {
kevman 0:38ceb79fef03 269 #if MBED_CONF_MBED_TRACE_ENABLE
kevman 0:38ceb79fef03 270 static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Manual registering", "Attaching network", "Activating PDP Context", "Connecting network", "Connected"};
kevman 0:38ceb79fef03 271 return strings[state];
kevman 0:38ceb79fef03 272 #else
kevman 0:38ceb79fef03 273 return NULL;
kevman 0:38ceb79fef03 274 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
kevman 0:38ceb79fef03 275 }
kevman 0:38ceb79fef03 276
kevman 0:38ceb79fef03 277 bool CellularConnectionFSM::is_registered_to_plmn()
kevman 0:38ceb79fef03 278 {
kevman 0:38ceb79fef03 279 int format;
kevman 0:38ceb79fef03 280 CellularNetwork::operator_t op;
kevman 0:38ceb79fef03 281
kevman 0:38ceb79fef03 282 nsapi_error_t err = _network->get_operator_params(format, op);
kevman 0:38ceb79fef03 283 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 284 if (format == 2) {
kevman 0:38ceb79fef03 285 // great, numeric format we can do comparison for that
kevman 0:38ceb79fef03 286 if (strcmp(op.op_num, _plmn) == 0) {
kevman 0:38ceb79fef03 287 return true;
kevman 0:38ceb79fef03 288 }
kevman 0:38ceb79fef03 289 return false;
kevman 0:38ceb79fef03 290 }
kevman 0:38ceb79fef03 291
kevman 0:38ceb79fef03 292 // format was alpha, get operator names to do the comparing
kevman 0:38ceb79fef03 293 CellularNetwork::operator_names_list names_list;
kevman 0:38ceb79fef03 294 nsapi_error_t err = _network->get_operator_names(names_list);
kevman 0:38ceb79fef03 295 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 296 CellularNetwork::operator_names_t *op_names = names_list.get_head();
kevman 0:38ceb79fef03 297 bool found_match = false;
kevman 0:38ceb79fef03 298 while (op_names) {
kevman 0:38ceb79fef03 299 if (format == 0) {
kevman 0:38ceb79fef03 300 if (strcmp(op.op_long, op_names->alpha) == 0) {
kevman 0:38ceb79fef03 301 found_match = true;
kevman 0:38ceb79fef03 302 }
kevman 0:38ceb79fef03 303 } else if (format == 1) {
kevman 0:38ceb79fef03 304 if (strcmp(op.op_short, op_names->alpha) == 0) {
kevman 0:38ceb79fef03 305 found_match = true;
kevman 0:38ceb79fef03 306 }
kevman 0:38ceb79fef03 307 }
kevman 0:38ceb79fef03 308
kevman 0:38ceb79fef03 309 if (found_match) {
kevman 0:38ceb79fef03 310 if (strcmp(_plmn, op_names->numeric)) {
kevman 0:38ceb79fef03 311 names_list.delete_all();
kevman 0:38ceb79fef03 312 return true;
kevman 0:38ceb79fef03 313 }
kevman 0:38ceb79fef03 314 names_list.delete_all();
kevman 0:38ceb79fef03 315 return false;
kevman 0:38ceb79fef03 316 }
kevman 0:38ceb79fef03 317 }
kevman 0:38ceb79fef03 318 }
kevman 0:38ceb79fef03 319 names_list.delete_all();
kevman 0:38ceb79fef03 320 }
kevman 0:38ceb79fef03 321
kevman 0:38ceb79fef03 322 return false;
kevman 0:38ceb79fef03 323 }
kevman 0:38ceb79fef03 324
kevman 0:38ceb79fef03 325 nsapi_error_t CellularConnectionFSM::continue_from_state(CellularState state)
kevman 0:38ceb79fef03 326 {
kevman 0:38ceb79fef03 327 tr_info("Continue state from %s to %s", get_state_string((CellularConnectionFSM::CellularState)_state),
kevman 0:38ceb79fef03 328 get_state_string((CellularConnectionFSM::CellularState)state));
kevman 0:38ceb79fef03 329 _state = state;
kevman 0:38ceb79fef03 330 _next_state = state;
kevman 0:38ceb79fef03 331 _retry_count = 0;
kevman 0:38ceb79fef03 332 if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) {
kevman 0:38ceb79fef03 333 stop();
kevman 0:38ceb79fef03 334 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 335 }
kevman 0:38ceb79fef03 336
kevman 0:38ceb79fef03 337 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 338 }
kevman 0:38ceb79fef03 339
kevman 0:38ceb79fef03 340 nsapi_error_t CellularConnectionFSM::continue_to_state(CellularState state)
kevman 0:38ceb79fef03 341 {
kevman 0:38ceb79fef03 342 MBED_ASSERT(_cellularDevice);
kevman 0:38ceb79fef03 343 _retry_count = 0;
kevman 0:38ceb79fef03 344 if (state < _state) {
kevman 0:38ceb79fef03 345 _state = state;
kevman 0:38ceb79fef03 346 } else {
kevman 0:38ceb79fef03 347 // update next state so that we don't continue from previous state
kevman 0:38ceb79fef03 348 _state = _next_state;
kevman 0:38ceb79fef03 349 }
kevman 0:38ceb79fef03 350 if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) {
kevman 0:38ceb79fef03 351 stop();
kevman 0:38ceb79fef03 352 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 353 }
kevman 0:38ceb79fef03 354
kevman 0:38ceb79fef03 355 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 356 }
kevman 0:38ceb79fef03 357
kevman 0:38ceb79fef03 358 void CellularConnectionFSM::enter_to_state(CellularState state)
kevman 0:38ceb79fef03 359 {
kevman 0:38ceb79fef03 360 _next_state = state;
kevman 0:38ceb79fef03 361 _retry_count = 0;
kevman 0:38ceb79fef03 362 _command_success = false;
kevman 0:38ceb79fef03 363 }
kevman 0:38ceb79fef03 364
kevman 0:38ceb79fef03 365 void CellularConnectionFSM::retry_state_or_fail()
kevman 0:38ceb79fef03 366 {
kevman 0:38ceb79fef03 367 if (++_retry_count < MAX_RETRY_ARRAY_SIZE) {
kevman 0:38ceb79fef03 368 tr_debug("Retry State %s, retry %d/%d", get_state_string(_state), _retry_count, MAX_RETRY_ARRAY_SIZE);
kevman 0:38ceb79fef03 369 _event_timeout = _retry_timeout_array[_retry_count];
kevman 0:38ceb79fef03 370 } else {
kevman 0:38ceb79fef03 371 report_failure(get_state_string(_state));
kevman 0:38ceb79fef03 372 return;
kevman 0:38ceb79fef03 373 }
kevman 0:38ceb79fef03 374 }
kevman 0:38ceb79fef03 375
kevman 0:38ceb79fef03 376 void CellularConnectionFSM::state_init()
kevman 0:38ceb79fef03 377 {
kevman 0:38ceb79fef03 378 // we should check that if power is already on then we can jump to device ready state
kevman 0:38ceb79fef03 379 _cellularDevice->set_timeout(TIMEOUT_POWER_ON);
kevman 0:38ceb79fef03 380 tr_info("Cellular state init (timeout %d ms)", TIMEOUT_POWER_ON);
kevman 0:38ceb79fef03 381 nsapi_error_t err = _power->is_device_ready();
kevman 0:38ceb79fef03 382 if (err != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 383 _event_timeout = _start_time;
kevman 0:38ceb79fef03 384 tr_info("Init state, waiting %d ms before POWER state)", _start_time);
kevman 0:38ceb79fef03 385 enter_to_state(STATE_POWER_ON);
kevman 0:38ceb79fef03 386 } else {
kevman 0:38ceb79fef03 387 tr_info("Device was ready to accept commands, jump to device ready");
kevman 0:38ceb79fef03 388 enter_to_state(STATE_DEVICE_READY);
kevman 0:38ceb79fef03 389 }
kevman 0:38ceb79fef03 390 }
kevman 0:38ceb79fef03 391
kevman 0:38ceb79fef03 392 void CellularConnectionFSM::state_power_on()
kevman 0:38ceb79fef03 393 {
kevman 0:38ceb79fef03 394 _cellularDevice->set_timeout(TIMEOUT_POWER_ON);
kevman 0:38ceb79fef03 395 tr_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON);
kevman 0:38ceb79fef03 396 if (power_on()) {
kevman 0:38ceb79fef03 397 enter_to_state(STATE_DEVICE_READY);
kevman 0:38ceb79fef03 398 } else {
kevman 0:38ceb79fef03 399 // retry to power on device
kevman 0:38ceb79fef03 400 retry_state_or_fail();
kevman 0:38ceb79fef03 401 }
kevman 0:38ceb79fef03 402 }
kevman 0:38ceb79fef03 403
kevman 0:38ceb79fef03 404 bool CellularConnectionFSM::device_ready()
kevman 0:38ceb79fef03 405 {
kevman 0:38ceb79fef03 406 if (_cellularDevice->init_module(_serial) != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 407 return false;
kevman 0:38ceb79fef03 408 }
kevman 0:38ceb79fef03 409 tr_info("Cellular device ready");
kevman 0:38ceb79fef03 410 if (_event_status_cb) {
kevman 0:38ceb79fef03 411 _event_status_cb((nsapi_event_t)CellularDeviceReady, 0);
kevman 0:38ceb79fef03 412 }
kevman 0:38ceb79fef03 413 _power->remove_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb));
kevman 0:38ceb79fef03 414 _cellularDevice->close_power();
kevman 0:38ceb79fef03 415 _power = NULL;
kevman 0:38ceb79fef03 416 return true;
kevman 0:38ceb79fef03 417 }
kevman 0:38ceb79fef03 418
kevman 0:38ceb79fef03 419 void CellularConnectionFSM::state_device_ready()
kevman 0:38ceb79fef03 420 {
kevman 0:38ceb79fef03 421 _cellularDevice->set_timeout(TIMEOUT_POWER_ON);
kevman 0:38ceb79fef03 422 if (_power->set_at_mode() == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 423 if (device_ready()) {
kevman 0:38ceb79fef03 424 enter_to_state(STATE_SIM_PIN);
kevman 0:38ceb79fef03 425 }
kevman 0:38ceb79fef03 426 } else {
kevman 0:38ceb79fef03 427 if (_retry_count == 0) {
kevman 0:38ceb79fef03 428 (void)_power->set_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb));
kevman 0:38ceb79fef03 429 }
kevman 0:38ceb79fef03 430 retry_state_or_fail();
kevman 0:38ceb79fef03 431 }
kevman 0:38ceb79fef03 432 }
kevman 0:38ceb79fef03 433
kevman 0:38ceb79fef03 434 void CellularConnectionFSM::state_sim_pin()
kevman 0:38ceb79fef03 435 {
kevman 0:38ceb79fef03 436 _cellularDevice->set_timeout(TIMEOUT_SIM_PIN);
kevman 0:38ceb79fef03 437 tr_info("Sim state (timeout %d ms)", TIMEOUT_SIM_PIN);
kevman 0:38ceb79fef03 438 if (open_sim()) {
kevman 0:38ceb79fef03 439 bool success = false;
kevman 0:38ceb79fef03 440 for (int type = 0; type < CellularNetwork::C_MAX; type++) {
kevman 0:38ceb79fef03 441 if (!_network->set_registration_urc((CellularNetwork::RegistrationType)type, true)) {
kevman 0:38ceb79fef03 442 success = true;
kevman 0:38ceb79fef03 443 }
kevman 0:38ceb79fef03 444 }
kevman 0:38ceb79fef03 445 if (!success) {
kevman 0:38ceb79fef03 446 tr_warn("Failed to set any URC's for registration");
kevman 0:38ceb79fef03 447 retry_state_or_fail();
kevman 0:38ceb79fef03 448 return;
kevman 0:38ceb79fef03 449 }
kevman 0:38ceb79fef03 450 if (_plmn) {
kevman 0:38ceb79fef03 451 enter_to_state(STATE_MANUAL_REGISTERING_NETWORK);
kevman 0:38ceb79fef03 452 } else {
kevman 0:38ceb79fef03 453 enter_to_state(STATE_REGISTERING_NETWORK);
kevman 0:38ceb79fef03 454 }
kevman 0:38ceb79fef03 455 } else {
kevman 0:38ceb79fef03 456 retry_state_or_fail();
kevman 0:38ceb79fef03 457 }
kevman 0:38ceb79fef03 458 }
kevman 0:38ceb79fef03 459
kevman 0:38ceb79fef03 460 void CellularConnectionFSM::state_registering()
kevman 0:38ceb79fef03 461 {
kevman 0:38ceb79fef03 462 _cellularDevice->set_timeout(TIMEOUT_NETWORK);
kevman 0:38ceb79fef03 463 if (is_registered()) {
kevman 0:38ceb79fef03 464 // we are already registered, go to attach
kevman 0:38ceb79fef03 465 enter_to_state(STATE_ATTACHING_NETWORK);
kevman 0:38ceb79fef03 466 } else {
kevman 0:38ceb79fef03 467 _cellularDevice->set_timeout(TIMEOUT_REGISTRATION);
kevman 0:38ceb79fef03 468 if (!_command_success) {
kevman 0:38ceb79fef03 469 _command_success = (_network->set_registration() == NSAPI_ERROR_OK);
kevman 0:38ceb79fef03 470 }
kevman 0:38ceb79fef03 471 retry_state_or_fail();
kevman 0:38ceb79fef03 472 }
kevman 0:38ceb79fef03 473 }
kevman 0:38ceb79fef03 474
kevman 0:38ceb79fef03 475 // only used when _plmn is set
kevman 0:38ceb79fef03 476 void CellularConnectionFSM::state_manual_registering_network()
kevman 0:38ceb79fef03 477 {
kevman 0:38ceb79fef03 478 _cellularDevice->set_timeout(TIMEOUT_REGISTRATION);
kevman 0:38ceb79fef03 479 tr_info("state_manual_registering_network");
kevman 0:38ceb79fef03 480 if (!_plmn_network_found) {
kevman 0:38ceb79fef03 481 if (is_registered() && is_registered_to_plmn()) {
kevman 0:38ceb79fef03 482 _plmn_network_found = true;
kevman 0:38ceb79fef03 483 enter_to_state(STATE_ATTACHING_NETWORK);
kevman 0:38ceb79fef03 484 } else {
kevman 0:38ceb79fef03 485 if (!_command_success) {
kevman 0:38ceb79fef03 486 _command_success = (_network->set_registration(_plmn) == NSAPI_ERROR_OK);
kevman 0:38ceb79fef03 487 }
kevman 0:38ceb79fef03 488 retry_state_or_fail();
kevman 0:38ceb79fef03 489 }
kevman 0:38ceb79fef03 490 }
kevman 0:38ceb79fef03 491 }
kevman 0:38ceb79fef03 492
kevman 0:38ceb79fef03 493 void CellularConnectionFSM::state_attaching()
kevman 0:38ceb79fef03 494 {
kevman 0:38ceb79fef03 495 _cellularDevice->set_timeout(TIMEOUT_CONNECT);
kevman 0:38ceb79fef03 496 if (_network->set_attach() == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 497 _cellularDevice->close_sim();
kevman 0:38ceb79fef03 498 _sim = NULL;
kevman 0:38ceb79fef03 499 enter_to_state(STATE_ACTIVATING_PDP_CONTEXT);
kevman 0:38ceb79fef03 500 } else {
kevman 0:38ceb79fef03 501 retry_state_or_fail();
kevman 0:38ceb79fef03 502 }
kevman 0:38ceb79fef03 503 }
kevman 0:38ceb79fef03 504
kevman 0:38ceb79fef03 505 void CellularConnectionFSM::state_activating_pdp_context()
kevman 0:38ceb79fef03 506 {
kevman 0:38ceb79fef03 507 _cellularDevice->set_timeout(TIMEOUT_CONNECT);
kevman 0:38ceb79fef03 508 tr_info("Activate PDP Context (timeout %d ms)", TIMEOUT_CONNECT);
kevman 0:38ceb79fef03 509 if (_network->activate_context() == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 510 // when using modems stack connect is synchronous
kevman 0:38ceb79fef03 511 _next_state = STATE_CONNECTING_NETWORK;
kevman 0:38ceb79fef03 512 } else {
kevman 0:38ceb79fef03 513 retry_state_or_fail();
kevman 0:38ceb79fef03 514 }
kevman 0:38ceb79fef03 515 }
kevman 0:38ceb79fef03 516
kevman 0:38ceb79fef03 517 void CellularConnectionFSM::state_connect_to_network()
kevman 0:38ceb79fef03 518 {
kevman 0:38ceb79fef03 519 _cellularDevice->set_timeout(TIMEOUT_CONNECT);
kevman 0:38ceb79fef03 520 tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_CONNECT);
kevman 0:38ceb79fef03 521 if (_network->connect() == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 522 _cellularDevice->set_timeout(TIMEOUT_NETWORK);
kevman 0:38ceb79fef03 523 tr_debug("Connected to cellular network, set at timeout (timeout %d ms)", TIMEOUT_NETWORK);
kevman 0:38ceb79fef03 524 // when using modems stack connect is synchronous
kevman 0:38ceb79fef03 525 _next_state = STATE_CONNECTED;
kevman 0:38ceb79fef03 526 } else {
kevman 0:38ceb79fef03 527 retry_state_or_fail();
kevman 0:38ceb79fef03 528 }
kevman 0:38ceb79fef03 529 }
kevman 0:38ceb79fef03 530
kevman 0:38ceb79fef03 531 void CellularConnectionFSM::state_connected()
kevman 0:38ceb79fef03 532 {
kevman 0:38ceb79fef03 533 _cellularDevice->set_timeout(TIMEOUT_NETWORK);
kevman 0:38ceb79fef03 534 tr_debug("Cellular ready! (timeout %d ms)", TIMEOUT_NETWORK);
kevman 0:38ceb79fef03 535 if (_status_callback) {
kevman 0:38ceb79fef03 536 _status_callback(_state, _next_state);
kevman 0:38ceb79fef03 537 }
kevman 0:38ceb79fef03 538 }
kevman 0:38ceb79fef03 539
kevman 0:38ceb79fef03 540 void CellularConnectionFSM::event()
kevman 0:38ceb79fef03 541 {
kevman 0:38ceb79fef03 542 _event_timeout = -1;
kevman 0:38ceb79fef03 543 switch (_state) {
kevman 0:38ceb79fef03 544 case STATE_INIT:
kevman 0:38ceb79fef03 545 state_init();
kevman 0:38ceb79fef03 546 break;
kevman 0:38ceb79fef03 547 case STATE_POWER_ON:
kevman 0:38ceb79fef03 548 state_power_on();
kevman 0:38ceb79fef03 549 break;
kevman 0:38ceb79fef03 550 case STATE_DEVICE_READY:
kevman 0:38ceb79fef03 551 state_device_ready();
kevman 0:38ceb79fef03 552 break;
kevman 0:38ceb79fef03 553 case STATE_SIM_PIN:
kevman 0:38ceb79fef03 554 state_sim_pin();
kevman 0:38ceb79fef03 555 break;
kevman 0:38ceb79fef03 556 case STATE_REGISTERING_NETWORK:
kevman 0:38ceb79fef03 557 state_registering();
kevman 0:38ceb79fef03 558 break;
kevman 0:38ceb79fef03 559 case STATE_MANUAL_REGISTERING_NETWORK:
kevman 0:38ceb79fef03 560 state_manual_registering_network();
kevman 0:38ceb79fef03 561 break;
kevman 0:38ceb79fef03 562 case STATE_ATTACHING_NETWORK:
kevman 0:38ceb79fef03 563 state_attaching();
kevman 0:38ceb79fef03 564 break;
kevman 0:38ceb79fef03 565 case STATE_ACTIVATING_PDP_CONTEXT:
kevman 0:38ceb79fef03 566 state_activating_pdp_context();
kevman 0:38ceb79fef03 567 break;
kevman 0:38ceb79fef03 568 case STATE_CONNECTING_NETWORK:
kevman 0:38ceb79fef03 569 state_connect_to_network();
kevman 0:38ceb79fef03 570 break;
kevman 0:38ceb79fef03 571 case STATE_CONNECTED:
kevman 0:38ceb79fef03 572 state_connected();
kevman 0:38ceb79fef03 573 break;
kevman 0:38ceb79fef03 574 default:
kevman 0:38ceb79fef03 575 MBED_ASSERT(0);
kevman 0:38ceb79fef03 576 break;
kevman 0:38ceb79fef03 577 }
kevman 0:38ceb79fef03 578
kevman 0:38ceb79fef03 579 if (_next_state != _state || _event_timeout >= 0) {
kevman 0:38ceb79fef03 580 if (_next_state != _state) { // state exit condition
kevman 0:38ceb79fef03 581 tr_info("Cellular state from %s to %s", get_state_string((CellularConnectionFSM::CellularState)_state),
kevman 0:38ceb79fef03 582 get_state_string((CellularConnectionFSM::CellularState)_next_state));
kevman 0:38ceb79fef03 583 if (_status_callback) {
kevman 0:38ceb79fef03 584 if (!_status_callback(_state, _next_state)) {
kevman 0:38ceb79fef03 585 return;
kevman 0:38ceb79fef03 586 }
kevman 0:38ceb79fef03 587 }
kevman 0:38ceb79fef03 588 } else {
kevman 0:38ceb79fef03 589 tr_info("Cellular event in %d seconds", _event_timeout);
kevman 0:38ceb79fef03 590 }
kevman 0:38ceb79fef03 591 _state = _next_state;
kevman 0:38ceb79fef03 592 if (_event_timeout == -1) {
kevman 0:38ceb79fef03 593 _event_timeout = 0;
kevman 0:38ceb79fef03 594 }
kevman 0:38ceb79fef03 595 _event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularConnectionFSM::event));
kevman 0:38ceb79fef03 596 if (!_event_id) {
kevman 0:38ceb79fef03 597 report_failure("Cellular event failure!");
kevman 0:38ceb79fef03 598 return;
kevman 0:38ceb79fef03 599 }
kevman 0:38ceb79fef03 600 }
kevman 0:38ceb79fef03 601 }
kevman 0:38ceb79fef03 602
kevman 0:38ceb79fef03 603 nsapi_error_t CellularConnectionFSM::start_dispatch()
kevman 0:38ceb79fef03 604 {
kevman 0:38ceb79fef03 605 MBED_ASSERT(!_queue_thread);
kevman 0:38ceb79fef03 606
kevman 0:38ceb79fef03 607 _queue_thread = new rtos::Thread(osPriorityNormal, 2048);
kevman 0:38ceb79fef03 608 if (!_queue_thread) {
kevman 0:38ceb79fef03 609 stop();
kevman 0:38ceb79fef03 610 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 611 }
kevman 0:38ceb79fef03 612 if (_queue_thread->start(callback(&_queue, &events::EventQueue::dispatch_forever)) != osOK) {
kevman 0:38ceb79fef03 613 stop();
kevman 0:38ceb79fef03 614 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 615 }
kevman 0:38ceb79fef03 616
kevman 0:38ceb79fef03 617 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 618 }
kevman 0:38ceb79fef03 619
kevman 0:38ceb79fef03 620 void CellularConnectionFSM::set_serial(UARTSerial *serial)
kevman 0:38ceb79fef03 621 {
kevman 0:38ceb79fef03 622 _serial = serial;
kevman 0:38ceb79fef03 623 }
kevman 0:38ceb79fef03 624
kevman 0:38ceb79fef03 625 void CellularConnectionFSM::set_callback(mbed::Callback<bool(int, int)> status_callback)
kevman 0:38ceb79fef03 626 {
kevman 0:38ceb79fef03 627 _status_callback = status_callback;
kevman 0:38ceb79fef03 628 }
kevman 0:38ceb79fef03 629
kevman 0:38ceb79fef03 630 void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
kevman 0:38ceb79fef03 631 {
kevman 0:38ceb79fef03 632 MBED_ASSERT(_network);
kevman 0:38ceb79fef03 633 _event_status_cb = status_cb;
kevman 0:38ceb79fef03 634 if (status_cb) {
kevman 0:38ceb79fef03 635 _network->attach(callback(this, &CellularConnectionFSM::network_callback));
kevman 0:38ceb79fef03 636 } else {
kevman 0:38ceb79fef03 637 _network->attach(NULL);
kevman 0:38ceb79fef03 638 }
kevman 0:38ceb79fef03 639 }
kevman 0:38ceb79fef03 640
kevman 0:38ceb79fef03 641 void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
kevman 0:38ceb79fef03 642 {
kevman 0:38ceb79fef03 643 tr_info("FSM: network_callback called with event: %d, intptr: %d, _state: %s", ev, ptr, get_state_string(_state));
kevman 0:38ceb79fef03 644 if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged &&
kevman 0:38ceb79fef03 645 (_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK)) {
kevman 0:38ceb79fef03 646 // expect packet data so only these states are valid
kevman 0:38ceb79fef03 647 if (ptr == CellularNetwork::RegisteredHomeNetwork || ptr == CellularNetwork::RegisteredRoaming) {
kevman 0:38ceb79fef03 648 if (_plmn) {
kevman 0:38ceb79fef03 649 if (is_registered_to_plmn()) {
kevman 0:38ceb79fef03 650 if (!_plmn_network_found) {
kevman 0:38ceb79fef03 651 _plmn_network_found = true;
kevman 0:38ceb79fef03 652 _queue.cancel(_event_id);
kevman 0:38ceb79fef03 653 continue_from_state(STATE_ATTACHING_NETWORK);
kevman 0:38ceb79fef03 654 }
kevman 0:38ceb79fef03 655 }
kevman 0:38ceb79fef03 656 } else {
kevman 0:38ceb79fef03 657 _queue.cancel(_event_id);
kevman 0:38ceb79fef03 658 continue_from_state(STATE_ATTACHING_NETWORK);
kevman 0:38ceb79fef03 659 }
kevman 0:38ceb79fef03 660 }
kevman 0:38ceb79fef03 661 }
kevman 0:38ceb79fef03 662
kevman 0:38ceb79fef03 663 if (_event_status_cb) {
kevman 0:38ceb79fef03 664 _event_status_cb(ev, ptr);
kevman 0:38ceb79fef03 665 }
kevman 0:38ceb79fef03 666 }
kevman 0:38ceb79fef03 667
kevman 0:38ceb79fef03 668 void CellularConnectionFSM::ready_urc_cb()
kevman 0:38ceb79fef03 669 {
kevman 0:38ceb79fef03 670 tr_debug("Device ready URC func called");
kevman 0:38ceb79fef03 671 if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 672 tr_debug("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next");
kevman 0:38ceb79fef03 673 if (device_ready()) {
kevman 0:38ceb79fef03 674 _queue.cancel(_event_id);
kevman 0:38ceb79fef03 675 continue_from_state(STATE_SIM_PIN);
kevman 0:38ceb79fef03 676 }
kevman 0:38ceb79fef03 677 }
kevman 0:38ceb79fef03 678 }
kevman 0:38ceb79fef03 679
kevman 0:38ceb79fef03 680 events::EventQueue *CellularConnectionFSM::get_queue()
kevman 0:38ceb79fef03 681 {
kevman 0:38ceb79fef03 682 return &_queue;
kevman 0:38ceb79fef03 683 }
kevman 0:38ceb79fef03 684
kevman 0:38ceb79fef03 685 CellularNetwork *CellularConnectionFSM::get_network()
kevman 0:38ceb79fef03 686 {
kevman 0:38ceb79fef03 687 return _network;
kevman 0:38ceb79fef03 688 }
kevman 0:38ceb79fef03 689
kevman 0:38ceb79fef03 690 CellularDevice *CellularConnectionFSM::get_device()
kevman 0:38ceb79fef03 691 {
kevman 0:38ceb79fef03 692 return _cellularDevice;
kevman 0:38ceb79fef03 693 }
kevman 0:38ceb79fef03 694
kevman 0:38ceb79fef03 695 CellularSIM *CellularConnectionFSM::get_sim()
kevman 0:38ceb79fef03 696 {
kevman 0:38ceb79fef03 697 return _sim;
kevman 0:38ceb79fef03 698 }
kevman 0:38ceb79fef03 699
kevman 0:38ceb79fef03 700 NetworkStack *CellularConnectionFSM::get_stack()
kevman 0:38ceb79fef03 701 {
kevman 0:38ceb79fef03 702 return _cellularDevice->get_stack();
kevman 0:38ceb79fef03 703 }
kevman 0:38ceb79fef03 704
kevman 0:38ceb79fef03 705 void CellularConnectionFSM::set_retry_timeout_array(uint16_t timeout[], int array_len)
kevman 0:38ceb79fef03 706 {
kevman 0:38ceb79fef03 707 _retry_array_length = array_len > MAX_RETRY_ARRAY_SIZE ? MAX_RETRY_ARRAY_SIZE : array_len;
kevman 0:38ceb79fef03 708
kevman 0:38ceb79fef03 709 for (int i = 0; i < _retry_array_length; i++) {
kevman 0:38ceb79fef03 710 _retry_timeout_array[i] = timeout[i];
kevman 0:38ceb79fef03 711 }
kevman 0:38ceb79fef03 712 }
kevman 0:38ceb79fef03 713
kevman 0:38ceb79fef03 714 } // namespace
kevman 0:38ceb79fef03 715
kevman 0:38ceb79fef03 716 #endif // CELLULAR_DEVICE