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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
AT_CellularDevice.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 "rtos/ThisThread.h" 00019 #include "CellularUtil.h" 00020 #include "AT_CellularDevice.h" 00021 #include "AT_CellularInformation.h" 00022 #include "AT_CellularNetwork.h" 00023 #include "AT_CellularSMS.h" 00024 #include "AT_CellularContext.h" 00025 #include "AT_CellularStack.h" 00026 #include "CellularLog.h" 00027 #include "ATHandler.h" 00028 #if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY) 00029 #include "UARTSerial.h" 00030 #endif // #if DEVICE_SERIAL 00031 #include "FileHandle.h" 00032 #include <ctype.h> 00033 00034 using namespace mbed_cellular_util; 00035 using namespace events; 00036 using namespace mbed; 00037 00038 #define DEFAULT_AT_TIMEOUT 1000 // at default timeout in milliseconds 00039 const int MAX_SIM_RESPONSE_LENGTH = 16; 00040 00041 AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), 00042 #if MBED_CONF_CELLULAR_USE_SMS 00043 _sms(0), 00044 #endif // MBED_CONF_CELLULAR_USE_SMS 00045 _network(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT), 00046 _modem_debug_on(false), _property_array(NULL) 00047 { 00048 MBED_ASSERT(fh); 00049 _at = get_at_handler(fh); 00050 MBED_ASSERT(_at); 00051 } 00052 00053 AT_CellularDevice::~AT_CellularDevice() 00054 { 00055 if (get_property(PROPERTY_AT_CGEREP)) { 00056 _at->set_urc_handler("+CGEV: NW DEACT", 0); 00057 _at->set_urc_handler("+CGEV: ME DEACT", 0); 00058 _at->set_urc_handler("+CGEV: NW PDN D", 0); 00059 _at->set_urc_handler("+CGEV: ME PDN D", 0); 00060 } 00061 00062 // make sure that all is deleted even if somewhere close was not called and reference counting is messed up. 00063 _network_ref_count = 1; 00064 #if MBED_CONF_CELLULAR_USE_SMS 00065 _sms_ref_count = 1; 00066 #endif // MBED_CONF_CELLULAR_USE_SMS 00067 _info_ref_count = 1; 00068 00069 close_network(); 00070 00071 #if MBED_CONF_CELLULAR_USE_SMS 00072 close_sms(); 00073 #endif //MBED_CONF_CELLULAR_USE_SMS 00074 00075 close_information(); 00076 00077 AT_CellularContext *curr = _context_list; 00078 AT_CellularContext *next; 00079 while (curr) { 00080 next = (AT_CellularContext *)curr->_next; 00081 ATHandler *at = &curr->get_at_handler(); 00082 delete curr; 00083 curr = next; 00084 release_at_handler(at); 00085 } 00086 00087 release_at_handler(_at); 00088 } 00089 00090 void AT_CellularDevice::set_at_urcs_impl() 00091 { 00092 } 00093 00094 void AT_CellularDevice::set_at_urcs() 00095 { 00096 if (get_property(PROPERTY_AT_CGEREP)) { 00097 _at->set_urc_handler("+CGEV: NW DEACT", callback(this, &AT_CellularDevice::urc_nw_deact)); 00098 _at->set_urc_handler("+CGEV: ME DEACT", callback(this, &AT_CellularDevice::urc_nw_deact)); 00099 _at->set_urc_handler("+CGEV: NW PDN D", callback(this, &AT_CellularDevice::urc_pdn_deact)); 00100 _at->set_urc_handler("+CGEV: ME PDN D", callback(this, &AT_CellularDevice::urc_pdn_deact)); 00101 } 00102 00103 set_at_urcs_impl(); 00104 } 00105 00106 void AT_CellularDevice::setup_at_handler() 00107 { 00108 set_at_urcs(); 00109 00110 _at->set_send_delay(get_send_delay()); 00111 } 00112 00113 void AT_CellularDevice::urc_nw_deact() 00114 { 00115 // The network has forced a context deactivation 00116 char buf[10]; 00117 _at->read_string(buf, 10); 00118 int cid; 00119 if (isalpha(buf[0])) { 00120 // this is +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>] 00121 // or +CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>] 00122 _at->skip_param(); // skip <PDP_addr> 00123 cid = _at->read_int(); 00124 } else { 00125 // this is +CGEV: NW DEACT <p_cid>, <cid>, <event_type>[,<WLAN_Offload>] 00126 // or +CGEV: ME DEACT <p_cid>, <cid>, <event_type 00127 cid = _at->read_int(); 00128 } 00129 send_disconnect_to_context(cid); 00130 } 00131 00132 void AT_CellularDevice::urc_pdn_deact() 00133 { 00134 // The network has deactivated a context 00135 // The mobile termination has deactivated a context. 00136 // +CGEV: NW PDN DEACT <cid>[,<WLAN_Offload>] 00137 // +CGEV: ME PDN DEACT <cid> 00138 _at->set_delimiter(' '); 00139 _at->skip_param(); 00140 _at->set_delimiter(','); 00141 00142 int cid = _at->read_int(); 00143 send_disconnect_to_context(cid); 00144 } 00145 00146 void AT_CellularDevice::send_disconnect_to_context(int cid) 00147 { 00148 tr_debug("send_disconnect_to_context, cid: %d", cid); 00149 AT_CellularContext *curr = _context_list; 00150 while (curr) { 00151 if (cid >= 0) { 00152 if (curr->get_cid() == cid) { 00153 CellularDevice::cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_STATUS_DISCONNECTED , curr); 00154 break; 00155 } 00156 } else { 00157 CellularDevice::cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_STATUS_DISCONNECTED ); 00158 } 00159 curr = (AT_CellularContext *)curr->_next; 00160 } 00161 } 00162 00163 nsapi_error_t AT_CellularDevice::hard_power_on() 00164 { 00165 return NSAPI_ERROR_OK ; 00166 } 00167 00168 nsapi_error_t AT_CellularDevice::hard_power_off() 00169 { 00170 return NSAPI_ERROR_OK ; 00171 } 00172 00173 nsapi_error_t AT_CellularDevice::soft_power_on() 00174 { 00175 return NSAPI_ERROR_OK ; 00176 } 00177 00178 nsapi_error_t AT_CellularDevice::soft_power_off() 00179 { 00180 return NSAPI_ERROR_OK ; 00181 } 00182 00183 // each parser is associated with one filehandle (that is UART) 00184 ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle) 00185 { 00186 if (!fileHandle) { 00187 fileHandle = _fh; 00188 } 00189 00190 return ATHandler::get_instance(fileHandle, _queue, _default_timeout, 00191 "\r", get_send_delay(), _modem_debug_on); 00192 } 00193 00194 ATHandler *AT_CellularDevice::get_at_handler() 00195 { 00196 return get_at_handler(NULL); 00197 } 00198 00199 nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler) 00200 { 00201 if (at_handler) { 00202 return at_handler->close(); 00203 } else { 00204 return NSAPI_ERROR_PARAMETER ; 00205 } 00206 } 00207 00208 nsapi_error_t AT_CellularDevice::get_sim_state(SimState &state) 00209 { 00210 char simstr[MAX_SIM_RESPONSE_LENGTH]; 00211 _at->lock(); 00212 _at->flush(); 00213 nsapi_error_t error = _at->at_cmd_str("+CPIN", "?", simstr, sizeof(simstr)); 00214 ssize_t len = strlen(simstr); 00215 #if MBED_CONF_MBED_TRACE_ENABLE 00216 device_err_t err = _at->get_last_device_error(); 00217 #endif 00218 _at->unlock(); 00219 00220 if (len != -1) { 00221 if (len >= 5 && memcmp(simstr, "READY", 5) == 0) { 00222 state = SimStateReady; 00223 } else if (len >= 7 && memcmp(simstr, "SIM PIN", 7) == 0) { 00224 state = SimStatePinNeeded; 00225 } else if (len >= 7 && memcmp(simstr, "SIM PUK", 7) == 0) { 00226 state = SimStatePukNeeded; 00227 } else { 00228 simstr[len] = '\0'; 00229 state = SimStateUnknown; 00230 } 00231 } else { 00232 tr_warn("SIM not readable."); 00233 state = SimStateUnknown; // SIM may not be ready yet or +CPIN may be unsupported command 00234 } 00235 #if MBED_CONF_MBED_TRACE_ENABLE 00236 switch (state) { 00237 case SimStatePinNeeded: 00238 tr_info("SIM PIN required"); 00239 break; 00240 case SimStatePukNeeded: 00241 tr_error("SIM PUK required"); 00242 break; 00243 case SimStateUnknown: 00244 if (err.errType == DeviceErrorTypeErrorCME && err.errCode == 14) { 00245 tr_info("SIM busy"); 00246 } else { 00247 tr_warn("SIM state unknown"); 00248 } 00249 break; 00250 default: 00251 tr_info("SIM is ready"); 00252 break; 00253 } 00254 #endif 00255 return error; 00256 } 00257 00258 nsapi_error_t AT_CellularDevice::set_pin(const char *sim_pin) 00259 { 00260 // if SIM is already in ready state then settings the PIN 00261 // will return error so let's check the state before settings the pin. 00262 SimState state = SimStateUnknown; 00263 if (get_sim_state(state) == NSAPI_ERROR_OK && state == SimStateReady) { 00264 return NSAPI_ERROR_OK ; 00265 } 00266 00267 if (sim_pin == NULL) { 00268 return NSAPI_ERROR_PARAMETER ; 00269 } 00270 00271 _at->lock(); 00272 00273 const bool stored_debug_state = _at->get_debug(); 00274 _at->set_debug(false); 00275 00276 _at->at_cmd_discard("+CPIN", "=", "%s", sim_pin); 00277 00278 _at->set_debug(stored_debug_state); 00279 00280 return _at->unlock_return_error(); 00281 } 00282 00283 CellularContext *AT_CellularDevice::get_context_list() const 00284 { 00285 return _context_list; 00286 } 00287 00288 #if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY) 00289 CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin, 00290 bool active_high, bool cp_req, bool nonip_req) 00291 { 00292 // Call FileHandle base version - explict upcast to avoid recursing into ourselves 00293 CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn, cp_req, nonip_req); 00294 if (serial) { 00295 ctx->set_file_handle(serial, dcd_pin, active_high); 00296 } 00297 return ctx; 00298 } 00299 #endif // #if DEVICE_SERIAL 00300 00301 CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn, bool cp_req, bool nonip_req) 00302 { 00303 AT_CellularContext *ctx = create_context_impl(*get_at_handler(fh), apn, cp_req, nonip_req); 00304 AT_CellularContext *curr = _context_list; 00305 00306 if (_context_list == NULL) { 00307 _context_list = ctx; 00308 return ctx; 00309 } 00310 00311 AT_CellularContext *prev = NULL; 00312 while (curr) { 00313 prev = curr; 00314 curr = (AT_CellularContext *)curr->_next; 00315 } 00316 00317 prev->_next = ctx; 00318 return ctx; 00319 } 00320 00321 AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req) 00322 { 00323 if (cp_req) { 00324 00325 } 00326 return new AT_CellularContext(at, this, apn, cp_req, nonip_req); 00327 } 00328 00329 void AT_CellularDevice::delete_context(CellularContext *context) 00330 { 00331 AT_CellularContext *curr = _context_list; 00332 AT_CellularContext *prev = NULL; 00333 while (curr) { 00334 if (curr == context) { 00335 if (prev == NULL) { 00336 _context_list = (AT_CellularContext *)curr->_next; 00337 } else { 00338 prev->_next = curr->_next; 00339 } 00340 } 00341 prev = curr; 00342 curr = (AT_CellularContext *)curr->_next; 00343 } 00344 curr = (AT_CellularContext *)context; 00345 ATHandler *at = NULL; 00346 if (curr) { 00347 at = &curr->get_at_handler(); 00348 } 00349 delete (AT_CellularContext *)context; 00350 release_at_handler(at); 00351 } 00352 00353 CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh) 00354 { 00355 if (!_network) { 00356 _network = open_network_impl(*get_at_handler(fh)); 00357 } 00358 _network_ref_count++; 00359 return _network; 00360 } 00361 00362 CellularInformation *AT_CellularDevice::open_information(FileHandle *fh) 00363 { 00364 if (!_information) { 00365 _information = open_information_impl(*get_at_handler(fh)); 00366 } 00367 _info_ref_count++; 00368 return _information; 00369 } 00370 00371 AT_CellularNetwork *AT_CellularDevice::open_network_impl(ATHandler &at) 00372 { 00373 return new AT_CellularNetwork(at, *this); 00374 } 00375 00376 #if MBED_CONF_CELLULAR_USE_SMS 00377 00378 CellularSMS *AT_CellularDevice::open_sms(FileHandle *fh) 00379 { 00380 if (!_sms) { 00381 _sms = open_sms_impl(*get_at_handler(fh)); 00382 } 00383 _sms_ref_count++; 00384 return _sms; 00385 } 00386 00387 void AT_CellularDevice::close_sms() 00388 { 00389 if (_sms) { 00390 _sms_ref_count--; 00391 if (_sms_ref_count == 0) { 00392 ATHandler *atHandler = &_sms->get_at_handler(); 00393 delete _sms; 00394 _sms = NULL; 00395 release_at_handler(atHandler); 00396 } 00397 } 00398 } 00399 00400 AT_CellularSMS *AT_CellularDevice::open_sms_impl(ATHandler &at) 00401 { 00402 return new AT_CellularSMS(at, *this); 00403 } 00404 #endif // MBED_CONF_CELLULAR_USE_SMS 00405 00406 AT_CellularInformation *AT_CellularDevice::open_information_impl(ATHandler &at) 00407 { 00408 return new AT_CellularInformation(at, *this); 00409 } 00410 00411 void AT_CellularDevice::close_network() 00412 { 00413 if (_network) { 00414 _network_ref_count--; 00415 if (_network_ref_count == 0) { 00416 ATHandler *atHandler = &_network->get_at_handler(); 00417 delete _network; 00418 _network = NULL; 00419 release_at_handler(atHandler); 00420 } 00421 } 00422 } 00423 00424 void AT_CellularDevice::close_information() 00425 { 00426 if (_information) { 00427 _info_ref_count--; 00428 if (_info_ref_count == 0) { 00429 ATHandler *atHandler = &_information->get_at_handler(); 00430 delete _information; 00431 _information = NULL; 00432 release_at_handler(atHandler); 00433 } 00434 } 00435 } 00436 00437 void AT_CellularDevice::set_timeout(int timeout) 00438 { 00439 _default_timeout = timeout; 00440 00441 ATHandler::set_at_timeout_list(_default_timeout, true); 00442 00443 if (_state_machine) { 00444 _state_machine->set_timeout(_default_timeout); 00445 } 00446 } 00447 00448 uint16_t AT_CellularDevice::get_send_delay() const 00449 { 00450 return 0; 00451 } 00452 00453 void AT_CellularDevice::modem_debug_on(bool on) 00454 { 00455 _modem_debug_on = on; 00456 00457 ATHandler::set_debug_list(_modem_debug_on); 00458 } 00459 00460 nsapi_error_t AT_CellularDevice::init() 00461 { 00462 setup_at_handler(); 00463 00464 _at->lock(); 00465 for (int retry = 1; retry <= 3; retry++) { 00466 _at->clear_error(); 00467 _at->flush(); 00468 _at->at_cmd_discard("E0", ""); 00469 if (_at->get_last_error() == NSAPI_ERROR_OK ) { 00470 _at->at_cmd_discard("+CMEE", "=1"); 00471 _at->at_cmd_discard("+CFUN", "=1"); 00472 if (_at->get_last_error() == NSAPI_ERROR_OK ) { 00473 break; 00474 } 00475 } 00476 tr_debug("Wait 100ms to init modem"); 00477 rtos::ThisThread::sleep_for(100); // let modem have time to get ready 00478 } 00479 00480 return _at->unlock_return_error(); 00481 } 00482 00483 nsapi_error_t AT_CellularDevice::shutdown() 00484 { 00485 CellularDevice::shutdown(); 00486 00487 return _at->at_cmd_discard("+CFUN", "=0"); 00488 } 00489 00490 nsapi_error_t AT_CellularDevice::is_ready() 00491 { 00492 _at->lock(); 00493 _at->at_cmd_discard("", ""); 00494 00495 // we need to do this twice because for example after data mode the first 'AT' command will give modem a 00496 // stimulus that we are back to command mode. 00497 _at->clear_error(); 00498 _at->at_cmd_discard("", ""); 00499 00500 return _at->unlock_return_error(); 00501 } 00502 00503 void AT_CellularDevice::set_ready_cb(Callback<void()> callback) 00504 { 00505 } 00506 00507 nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int active_time) 00508 { 00509 _at->lock(); 00510 00511 if (periodic_time == 0 && active_time == 0) { 00512 // disable PSM 00513 _at->at_cmd_discard("+CPSMS", "=0"); 00514 } else { 00515 const int PSMTimerBits = 5; 00516 00517 /** 00518 Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element 00519 00520 Bits 5 to 1 represent the binary coded timer value. 00521 00522 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00523 8 7 6 00524 0 0 0 value is incremented in multiples of 10 minutes 00525 0 0 1 value is incremented in multiples of 1 hour 00526 0 1 0 value is incremented in multiples of 10 hours 00527 0 1 1 value is incremented in multiples of 2 seconds 00528 1 0 0 value is incremented in multiples of 30 seconds 00529 1 0 1 value is incremented in multiples of 1 minute 00530 1 1 0 value is incremented in multiples of 320 hours (NOTE 1) 00531 1 1 1 value indicates that the timer is deactivated (NOTE 2). 00532 */ 00533 char pt[8 + 1]; // timer value encoded as 3GPP IE 00534 const int ie_value_max = 0x1f; 00535 uint32_t periodic_timer = 0; 00536 if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds 00537 periodic_timer = periodic_time / 2; 00538 strcpy(pt, "01100000"); 00539 } else { 00540 if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds 00541 periodic_timer = periodic_time / 30; 00542 strcpy(pt, "10000000"); 00543 } else { 00544 if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute 00545 periodic_timer = periodic_time / 60; 00546 strcpy(pt, "10100000"); 00547 } else { 00548 if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes 00549 periodic_timer = periodic_time / (10 * 60); 00550 strcpy(pt, "00000000"); 00551 } else { 00552 if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour 00553 periodic_timer = periodic_time / (60 * 60); 00554 strcpy(pt, "00100000"); 00555 } else { 00556 if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours 00557 periodic_timer = periodic_time / (10 * 60 * 60); 00558 strcpy(pt, "01000000"); 00559 } else { // multiples of 320 hours 00560 int t = periodic_time / (320 * 60 * 60); 00561 if (t > ie_value_max) { 00562 t = ie_value_max; 00563 } 00564 periodic_timer = t; 00565 strcpy(pt, "11000000"); 00566 } 00567 } 00568 } 00569 } 00570 } 00571 } 00572 00573 uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits); 00574 pt[8] = '\0'; 00575 00576 /** 00577 Table 10.5.172/3GPP TS 24.008: GPRS Timer information element 00578 00579 Bits 5 to 1 represent the binary coded timer value. 00580 00581 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00582 00583 8 7 6 00584 0 0 0 value is incremented in multiples of 2 seconds 00585 0 0 1 value is incremented in multiples of 1 minute 00586 0 1 0 value is incremented in multiples of decihours 00587 1 1 1 value indicates that the timer is deactivated. 00588 00589 Other values shall be interpreted as multiples of 1 minute in this version of the protocol. 00590 */ 00591 char at[8 + 1]; 00592 uint32_t active_timer; // timer value encoded as 3GPP IE 00593 if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds 00594 active_timer = active_time / 2; 00595 strcpy(at, "00000000"); 00596 } else { 00597 if (active_time <= 60 * ie_value_max) { // multiples of 1 minute 00598 active_timer = (1 << 5) | (active_time / 60); 00599 strcpy(at, "00100000"); 00600 } else { // multiples of decihours 00601 int t = active_time / (6 * 60); 00602 if (t > ie_value_max) { 00603 t = ie_value_max; 00604 } 00605 active_timer = t; 00606 strcpy(at, "01000000"); 00607 } 00608 } 00609 00610 uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits); 00611 at[8] = '\0'; 00612 00613 // request for both GPRS and LTE 00614 00615 _at->at_cmd_discard("+CPSMS", "=1,", "%s%s%s%s", pt, at, pt, at); 00616 00617 if (_at->get_last_error() != NSAPI_ERROR_OK ) { 00618 tr_warn("Power save mode not enabled!"); 00619 } else { 00620 // network may not agree with power save options but 00621 // that should be fine as timeout is not longer than requested 00622 } 00623 } 00624 00625 return _at->unlock_return_error(); 00626 } 00627 00628 void AT_CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx) 00629 { 00630 if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END ) { 00631 cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev; 00632 if (cell_ev == CellularDeviceTimeout) { 00633 cell_callback_data_t *data = (cell_callback_data_t *)ptr; 00634 int timeout = *(int *)data->data; 00635 if (_default_timeout != timeout) { 00636 _default_timeout = timeout; 00637 ATHandler::set_at_timeout_list(_default_timeout, true); 00638 } 00639 } 00640 } 00641 CellularDevice::cellular_callback(ev, ptr, ctx); 00642 } 00643 00644 nsapi_error_t AT_CellularDevice::clear() 00645 { 00646 AT_CellularNetwork *net = static_cast<AT_CellularNetwork *>(open_network()); 00647 nsapi_error_t err = net->clear(); 00648 close_network(); 00649 00650 return err; 00651 } 00652 00653 nsapi_error_t AT_CellularDevice::set_baud_rate(int baud_rate) 00654 { 00655 nsapi_error_t error = set_baud_rate_impl(baud_rate); 00656 00657 if (error) { 00658 tr_warning("Baudrate was not changed to desired value: %d", baud_rate); 00659 return error; 00660 } 00661 00662 _at->set_baud(baud_rate); 00663 00664 // Give some time before starting using the UART with the new baud rate 00665 rtos::ThisThread::sleep_for(3000); 00666 00667 return error; 00668 } 00669 00670 nsapi_error_t AT_CellularDevice::set_baud_rate_impl(int baud_rate) 00671 { 00672 return _at->at_cmd_discard("+IPR", "=", "%d", baud_rate); 00673 } 00674 00675 void AT_CellularDevice::set_cellular_properties(const intptr_t *property_array) 00676 { 00677 if (!property_array) { 00678 tr_warning("trying to set an empty cellular property array"); 00679 return; 00680 } 00681 00682 _property_array = property_array; 00683 } 00684 00685 intptr_t AT_CellularDevice::get_property(CellularProperty key) 00686 { 00687 if (_property_array) { 00688 return _property_array[key]; 00689 } else { 00690 return 0; 00691 } 00692 }
Generated on Tue Jul 12 2022 13:54:02 by
