RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

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 "CellularTargets.h"
kevman 0:38ceb79fef03 19 #ifdef CELLULAR_DEVICE
kevman 0:38ceb79fef03 20
kevman 0:38ceb79fef03 21 #if NSAPI_PPP_AVAILABLE
kevman 0:38ceb79fef03 22 #include "nsapi_ppp.h"
kevman 0:38ceb79fef03 23 #endif
kevman 0:38ceb79fef03 24
kevman 0:38ceb79fef03 25 #include "CellularConnectionFSM.h"
kevman 0:38ceb79fef03 26 #include "CellularUtil.h"
kevman 0:38ceb79fef03 27
kevman 0:38ceb79fef03 28 #include "EasyCellularConnection.h"
kevman 0:38ceb79fef03 29 #include "CellularLog.h"
kevman 0:38ceb79fef03 30 #include "mbed_wait_api.h"
kevman 0:38ceb79fef03 31
kevman 0:38ceb79fef03 32 #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 33 #include "APN_db.h"
kevman 0:38ceb79fef03 34 #endif //USE_APN_LOOKUP
kevman 0:38ceb79fef03 35
kevman 0:38ceb79fef03 36 namespace mbed {
kevman 0:38ceb79fef03 37
kevman 0:38ceb79fef03 38 bool EasyCellularConnection::cellular_status(int state, int next_state)
kevman 0:38ceb79fef03 39 {
kevman 0:38ceb79fef03 40 tr_info("cellular_status: %s ==> %s", _cellularConnectionFSM->get_state_string((CellularConnectionFSM::CellularState)state),
kevman 0:38ceb79fef03 41 _cellularConnectionFSM->get_state_string((CellularConnectionFSM::CellularState)next_state));
kevman 0:38ceb79fef03 42
kevman 0:38ceb79fef03 43 if (_target_state == state) {
kevman 0:38ceb79fef03 44 tr_info("Target state reached: %s", _cellularConnectionFSM->get_state_string(_target_state));
kevman 0:38ceb79fef03 45 (void)_cellularSemaphore.release();
kevman 0:38ceb79fef03 46 return false; // return false -> state machine is halted
kevman 0:38ceb79fef03 47 }
kevman 0:38ceb79fef03 48
kevman 0:38ceb79fef03 49 // only in case of an error or when connected is reached state and next_state can be the same.
kevman 0:38ceb79fef03 50 // Release semaphore to return application instead of waiting for semaphore to complete.
kevman 0:38ceb79fef03 51 if (state == next_state) {
kevman 0:38ceb79fef03 52 tr_error("cellular_status: state and next_state are same, release semaphore as this is an error in state machine");
kevman 0:38ceb79fef03 53 _stm_error = true;
kevman 0:38ceb79fef03 54 (void)_cellularSemaphore.release();
kevman 0:38ceb79fef03 55 return false; // return false -> state machine is halted
kevman 0:38ceb79fef03 56 }
kevman 0:38ceb79fef03 57
kevman 0:38ceb79fef03 58 return true;
kevman 0:38ceb79fef03 59 }
kevman 0:38ceb79fef03 60
kevman 0:38ceb79fef03 61 void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr)
kevman 0:38ceb79fef03 62 {
kevman 0:38ceb79fef03 63 if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
kevman 0:38ceb79fef03 64 if (ptr == NSAPI_STATUS_GLOBAL_UP) {
kevman 0:38ceb79fef03 65 _is_connected = true;
kevman 0:38ceb79fef03 66 } else {
kevman 0:38ceb79fef03 67 _is_connected = false;
kevman 0:38ceb79fef03 68 }
kevman 0:38ceb79fef03 69 }
kevman 0:38ceb79fef03 70 if (_status_cb) {
kevman 0:38ceb79fef03 71 _status_cb(ev, ptr);
kevman 0:38ceb79fef03 72 }
kevman 0:38ceb79fef03 73 }
kevman 0:38ceb79fef03 74
kevman 0:38ceb79fef03 75 EasyCellularConnection::EasyCellularConnection(bool debug) :
kevman 0:38ceb79fef03 76 _is_connected(false), _is_initialized(false), _stm_error(false),
kevman 0:38ceb79fef03 77 _target_state(CellularConnectionFSM::STATE_POWER_ON),
kevman 0:38ceb79fef03 78 _cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0),
kevman 0:38ceb79fef03 79 _cellularConnectionFSM(0), _credentials_err(NSAPI_ERROR_OK), _status_cb(0)
kevman 0:38ceb79fef03 80 {
kevman 0:38ceb79fef03 81 tr_info("EasyCellularConnection()");
kevman 0:38ceb79fef03 82 #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 83 _credentials_set = false;
kevman 0:38ceb79fef03 84 #endif // #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 85 modem_debug_on(debug);
kevman 0:38ceb79fef03 86 }
kevman 0:38ceb79fef03 87
kevman 0:38ceb79fef03 88 EasyCellularConnection::~EasyCellularConnection()
kevman 0:38ceb79fef03 89 {
kevman 0:38ceb79fef03 90 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 91 _cellularConnectionFSM->set_callback(NULL);
kevman 0:38ceb79fef03 92 _cellularConnectionFSM->attach(NULL);
kevman 0:38ceb79fef03 93 delete _cellularConnectionFSM;
kevman 0:38ceb79fef03 94 }
kevman 0:38ceb79fef03 95 }
kevman 0:38ceb79fef03 96
kevman 0:38ceb79fef03 97 nsapi_error_t EasyCellularConnection::init()
kevman 0:38ceb79fef03 98 {
kevman 0:38ceb79fef03 99 nsapi_error_t err = NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 100 _stm_error = false;
kevman 0:38ceb79fef03 101 if (!_is_initialized) {
kevman 0:38ceb79fef03 102 #if defined (MDMRTS) && defined (MDMCTS)
kevman 0:38ceb79fef03 103 _cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
kevman 0:38ceb79fef03 104 #endif
kevman 0:38ceb79fef03 105 _cellularConnectionFSM = new CellularConnectionFSM();
kevman 0:38ceb79fef03 106 _cellularConnectionFSM->set_serial(&_cellularSerial);
kevman 0:38ceb79fef03 107 _cellularConnectionFSM->set_callback(callback(this, &EasyCellularConnection::cellular_status));
kevman 0:38ceb79fef03 108
kevman 0:38ceb79fef03 109 err = _cellularConnectionFSM->init();
kevman 0:38ceb79fef03 110
kevman 0:38ceb79fef03 111 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 112 err = _cellularConnectionFSM->start_dispatch();
kevman 0:38ceb79fef03 113 _cellularConnectionFSM->attach(callback(this, &EasyCellularConnection::network_callback));
kevman 0:38ceb79fef03 114 }
kevman 0:38ceb79fef03 115 _is_initialized = true;
kevman 0:38ceb79fef03 116 }
kevman 0:38ceb79fef03 117
kevman 0:38ceb79fef03 118 return err;
kevman 0:38ceb79fef03 119 }
kevman 0:38ceb79fef03 120
kevman 0:38ceb79fef03 121 void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
kevman 0:38ceb79fef03 122 {
kevman 0:38ceb79fef03 123 if (apn && strlen(apn) > 0) {
kevman 0:38ceb79fef03 124 _credentials_err = init();
kevman 0:38ceb79fef03 125
kevman 0:38ceb79fef03 126 if (_credentials_err) {
kevman 0:38ceb79fef03 127 return;
kevman 0:38ceb79fef03 128 }
kevman 0:38ceb79fef03 129 CellularNetwork *network = _cellularConnectionFSM->get_network();
kevman 0:38ceb79fef03 130 if (network) {
kevman 0:38ceb79fef03 131 _credentials_err = network->set_credentials(apn, uname, pwd);
kevman 0:38ceb79fef03 132 #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 133 if (_credentials_err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 134 _credentials_set = true;
kevman 0:38ceb79fef03 135 }
kevman 0:38ceb79fef03 136 #endif // #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 137 } else {
kevman 0:38ceb79fef03 138 //if get_network() returns NULL it means there was not enough memory for
kevman 0:38ceb79fef03 139 //an AT_CellularNetwork element during CellularConnectionFSM initialization
kevman 0:38ceb79fef03 140 tr_error("There was not enough memory during CellularConnectionFSM initialization");
kevman 0:38ceb79fef03 141 }
kevman 0:38ceb79fef03 142 }
kevman 0:38ceb79fef03 143 }
kevman 0:38ceb79fef03 144
kevman 0:38ceb79fef03 145 void EasyCellularConnection::set_sim_pin(const char *sim_pin)
kevman 0:38ceb79fef03 146 {
kevman 0:38ceb79fef03 147 if (sim_pin && strlen(sim_pin) > 0) {
kevman 0:38ceb79fef03 148 if (!_cellularConnectionFSM) {
kevman 0:38ceb79fef03 149 _credentials_err = init();
kevman 0:38ceb79fef03 150
kevman 0:38ceb79fef03 151 if (_credentials_err) {
kevman 0:38ceb79fef03 152 return;
kevman 0:38ceb79fef03 153 }
kevman 0:38ceb79fef03 154 }
kevman 0:38ceb79fef03 155 _cellularConnectionFSM->set_sim_pin(sim_pin);
kevman 0:38ceb79fef03 156 }
kevman 0:38ceb79fef03 157 }
kevman 0:38ceb79fef03 158
kevman 0:38ceb79fef03 159 nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
kevman 0:38ceb79fef03 160 {
kevman 0:38ceb79fef03 161 if (_is_connected) {
kevman 0:38ceb79fef03 162 return NSAPI_ERROR_IS_CONNECTED;
kevman 0:38ceb79fef03 163 }
kevman 0:38ceb79fef03 164
kevman 0:38ceb79fef03 165 set_credentials(apn, uname, pwd);
kevman 0:38ceb79fef03 166 if (_credentials_err) {
kevman 0:38ceb79fef03 167 return _credentials_err;
kevman 0:38ceb79fef03 168 }
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 if (sim_pin) {
kevman 0:38ceb79fef03 171 set_sim_pin(sim_pin);
kevman 0:38ceb79fef03 172 }
kevman 0:38ceb79fef03 173
kevman 0:38ceb79fef03 174 return connect();
kevman 0:38ceb79fef03 175 }
kevman 0:38ceb79fef03 176
kevman 0:38ceb79fef03 177 nsapi_error_t EasyCellularConnection::check_connect()
kevman 0:38ceb79fef03 178 {
kevman 0:38ceb79fef03 179 if (_is_connected) {
kevman 0:38ceb79fef03 180 return NSAPI_ERROR_IS_CONNECTED;
kevman 0:38ceb79fef03 181 }
kevman 0:38ceb79fef03 182
kevman 0:38ceb79fef03 183 // there was an error while setting credentials but it's a void function so check error here...
kevman 0:38ceb79fef03 184 if (_credentials_err) {
kevman 0:38ceb79fef03 185 return _credentials_err;
kevman 0:38ceb79fef03 186 }
kevman 0:38ceb79fef03 187
kevman 0:38ceb79fef03 188 nsapi_error_t err = init();
kevman 0:38ceb79fef03 189 if (err) {
kevman 0:38ceb79fef03 190 return err;
kevman 0:38ceb79fef03 191 }
kevman 0:38ceb79fef03 192
kevman 0:38ceb79fef03 193 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 194 }
kevman 0:38ceb79fef03 195
kevman 0:38ceb79fef03 196 nsapi_error_t EasyCellularConnection::connect()
kevman 0:38ceb79fef03 197 {
kevman 0:38ceb79fef03 198 nsapi_error_t err = check_connect();
kevman 0:38ceb79fef03 199 if (err) {
kevman 0:38ceb79fef03 200 return err;
kevman 0:38ceb79fef03 201 }
kevman 0:38ceb79fef03 202 #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 203 if (!_credentials_set) {
kevman 0:38ceb79fef03 204 _target_state = CellularConnectionFSM::STATE_SIM_PIN;
kevman 0:38ceb79fef03 205 err = _cellularConnectionFSM->continue_to_state(_target_state);
kevman 0:38ceb79fef03 206 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 207 int sim_wait = _cellularSemaphore.wait(60 * 1000); // reserve 60 seconds to access to SIM
kevman 0:38ceb79fef03 208 if (sim_wait != 1 || _stm_error) {
kevman 0:38ceb79fef03 209 tr_error("NO SIM ACCESS");
kevman 0:38ceb79fef03 210 err = NSAPI_ERROR_NO_CONNECTION;
kevman 0:38ceb79fef03 211 } else {
kevman 0:38ceb79fef03 212 char imsi[MAX_IMSI_LENGTH + 1];
kevman 0:38ceb79fef03 213 wait(1); // need to wait to access SIM in some modems
kevman 0:38ceb79fef03 214 err = _cellularConnectionFSM->get_sim()->get_imsi(imsi);
kevman 0:38ceb79fef03 215 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 216 const char *apn_config = apnconfig(imsi);
kevman 0:38ceb79fef03 217 if (apn_config) {
kevman 0:38ceb79fef03 218 const char *apn = _APN_GET(apn_config);
kevman 0:38ceb79fef03 219 const char *uname = _APN_GET(apn_config);
kevman 0:38ceb79fef03 220 const char *pwd = _APN_GET(apn_config);
kevman 0:38ceb79fef03 221 tr_info("Looked up APN %s", apn);
kevman 0:38ceb79fef03 222 err = _cellularConnectionFSM->get_network()->set_credentials(apn, uname, pwd);
kevman 0:38ceb79fef03 223 }
kevman 0:38ceb79fef03 224 }
kevman 0:38ceb79fef03 225 }
kevman 0:38ceb79fef03 226 }
kevman 0:38ceb79fef03 227 if (err) {
kevman 0:38ceb79fef03 228 tr_error("APN lookup failed");
kevman 0:38ceb79fef03 229 return err;
kevman 0:38ceb79fef03 230 }
kevman 0:38ceb79fef03 231 }
kevman 0:38ceb79fef03 232 #endif // USE_APN_LOOKUP
kevman 0:38ceb79fef03 233
kevman 0:38ceb79fef03 234 _target_state = CellularConnectionFSM::STATE_CONNECTED;
kevman 0:38ceb79fef03 235 err = _cellularConnectionFSM->continue_to_state(_target_state);
kevman 0:38ceb79fef03 236 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 237 int ret_wait = _cellularSemaphore.wait(10 * 60 * 1000); // cellular network searching may take several minutes
kevman 0:38ceb79fef03 238 if (ret_wait != 1 || _stm_error) {
kevman 0:38ceb79fef03 239 tr_info("No cellular connection");
kevman 0:38ceb79fef03 240 err = NSAPI_ERROR_NO_CONNECTION;
kevman 0:38ceb79fef03 241 }
kevman 0:38ceb79fef03 242 }
kevman 0:38ceb79fef03 243
kevman 0:38ceb79fef03 244 return err;
kevman 0:38ceb79fef03 245 }
kevman 0:38ceb79fef03 246
kevman 0:38ceb79fef03 247 nsapi_error_t EasyCellularConnection::disconnect()
kevman 0:38ceb79fef03 248 {
kevman 0:38ceb79fef03 249 _credentials_err = NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 250 _is_connected = false;
kevman 0:38ceb79fef03 251 _is_initialized = false;
kevman 0:38ceb79fef03 252 _stm_error = false;
kevman 0:38ceb79fef03 253 #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 254 _credentials_set = false;
kevman 0:38ceb79fef03 255 #endif // #if USE_APN_LOOKUP
kevman 0:38ceb79fef03 256
kevman 0:38ceb79fef03 257 nsapi_error_t err = NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 258 if (_cellularConnectionFSM && _cellularConnectionFSM->get_network()) {
kevman 0:38ceb79fef03 259 err = _cellularConnectionFSM->get_network()->disconnect();
kevman 0:38ceb79fef03 260 }
kevman 0:38ceb79fef03 261
kevman 0:38ceb79fef03 262 if (err == NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 263 delete _cellularConnectionFSM;
kevman 0:38ceb79fef03 264 _cellularConnectionFSM = NULL;
kevman 0:38ceb79fef03 265 }
kevman 0:38ceb79fef03 266
kevman 0:38ceb79fef03 267 return err;
kevman 0:38ceb79fef03 268 }
kevman 0:38ceb79fef03 269
kevman 0:38ceb79fef03 270 bool EasyCellularConnection::is_connected()
kevman 0:38ceb79fef03 271 {
kevman 0:38ceb79fef03 272 return _is_connected;
kevman 0:38ceb79fef03 273 }
kevman 0:38ceb79fef03 274
kevman 0:38ceb79fef03 275 const char *EasyCellularConnection::get_ip_address()
kevman 0:38ceb79fef03 276 {
kevman 0:38ceb79fef03 277 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 278 CellularNetwork *network = _cellularConnectionFSM->get_network();
kevman 0:38ceb79fef03 279 if (!network) {
kevman 0:38ceb79fef03 280 return NULL;
kevman 0:38ceb79fef03 281 }
kevman 0:38ceb79fef03 282 return _cellularConnectionFSM->get_network()->get_ip_address();
kevman 0:38ceb79fef03 283 } else {
kevman 0:38ceb79fef03 284 return NULL;
kevman 0:38ceb79fef03 285 }
kevman 0:38ceb79fef03 286 }
kevman 0:38ceb79fef03 287
kevman 0:38ceb79fef03 288 const char *EasyCellularConnection::get_netmask()
kevman 0:38ceb79fef03 289 {
kevman 0:38ceb79fef03 290 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 291 CellularNetwork *network = _cellularConnectionFSM->get_network();
kevman 0:38ceb79fef03 292 if (!network) {
kevman 0:38ceb79fef03 293 return NULL;
kevman 0:38ceb79fef03 294 }
kevman 0:38ceb79fef03 295 return network->get_netmask();
kevman 0:38ceb79fef03 296 } else {
kevman 0:38ceb79fef03 297 return NULL;
kevman 0:38ceb79fef03 298 }
kevman 0:38ceb79fef03 299 }
kevman 0:38ceb79fef03 300
kevman 0:38ceb79fef03 301 const char *EasyCellularConnection::get_gateway()
kevman 0:38ceb79fef03 302 {
kevman 0:38ceb79fef03 303 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 304 CellularNetwork *network = _cellularConnectionFSM->get_network();
kevman 0:38ceb79fef03 305 if (!network) {
kevman 0:38ceb79fef03 306 return NULL;
kevman 0:38ceb79fef03 307 }
kevman 0:38ceb79fef03 308 return network->get_gateway();
kevman 0:38ceb79fef03 309 } else {
kevman 0:38ceb79fef03 310 return NULL;
kevman 0:38ceb79fef03 311 }
kevman 0:38ceb79fef03 312 }
kevman 0:38ceb79fef03 313
kevman 0:38ceb79fef03 314 void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
kevman 0:38ceb79fef03 315 {
kevman 0:38ceb79fef03 316 _status_cb = status_cb;
kevman 0:38ceb79fef03 317 }
kevman 0:38ceb79fef03 318
kevman 0:38ceb79fef03 319 void EasyCellularConnection::modem_debug_on(bool on)
kevman 0:38ceb79fef03 320 {
kevman 0:38ceb79fef03 321 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 322 CellularDevice *dev = _cellularConnectionFSM->get_device();
kevman 0:38ceb79fef03 323 if (dev) {
kevman 0:38ceb79fef03 324 dev->modem_debug_on(on);
kevman 0:38ceb79fef03 325 }
kevman 0:38ceb79fef03 326 }
kevman 0:38ceb79fef03 327 }
kevman 0:38ceb79fef03 328
kevman 0:38ceb79fef03 329 void EasyCellularConnection::set_plmn(const char *plmn)
kevman 0:38ceb79fef03 330 {
kevman 0:38ceb79fef03 331 if (plmn && strlen(plmn) > 0) {
kevman 0:38ceb79fef03 332 if (!_cellularConnectionFSM) {
kevman 0:38ceb79fef03 333 _credentials_err = init();
kevman 0:38ceb79fef03 334
kevman 0:38ceb79fef03 335 if (_credentials_err) {
kevman 0:38ceb79fef03 336 return;
kevman 0:38ceb79fef03 337 }
kevman 0:38ceb79fef03 338 }
kevman 0:38ceb79fef03 339 _cellularConnectionFSM->set_plmn(plmn);
kevman 0:38ceb79fef03 340 }
kevman 0:38ceb79fef03 341 }
kevman 0:38ceb79fef03 342
kevman 0:38ceb79fef03 343 NetworkStack *EasyCellularConnection::get_stack()
kevman 0:38ceb79fef03 344 {
kevman 0:38ceb79fef03 345 if (_cellularConnectionFSM) {
kevman 0:38ceb79fef03 346 return _cellularConnectionFSM->get_stack();
kevman 0:38ceb79fef03 347 } else {
kevman 0:38ceb79fef03 348 return NULL;
kevman 0:38ceb79fef03 349 }
kevman 0:38ceb79fef03 350 }
kevman 0:38ceb79fef03 351
kevman 0:38ceb79fef03 352 CellularDevice *EasyCellularConnection::get_device()
kevman 0:38ceb79fef03 353 {
kevman 0:38ceb79fef03 354 return _cellularConnectionFSM->get_device();
kevman 0:38ceb79fef03 355 }
kevman 0:38ceb79fef03 356
kevman 0:38ceb79fef03 357 UARTSerial *EasyCellularConnection::get_serial()
kevman 0:38ceb79fef03 358 {
kevman 0:38ceb79fef03 359 return &_cellularSerial;
kevman 0:38ceb79fef03 360 }
kevman 0:38ceb79fef03 361
kevman 0:38ceb79fef03 362 } // namespace
kevman 0:38ceb79fef03 363
kevman 0:38ceb79fef03 364 #endif // CELLULAR_DEVICE