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_CellularNetwork.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 <stdlib.h> 00019 #include "AT_CellularNetwork.h" 00020 #include "CellularUtil.h" 00021 #include "CellularLog.h" 00022 #include "CellularCommon.h" 00023 #include "AT_CellularDevice.h" 00024 00025 using namespace std; 00026 using namespace mbed_cellular_util; 00027 using namespace mbed; 00028 00029 struct at_reg_t { 00030 const CellularNetwork::RegistrationType type; 00031 const char *const cmd; 00032 const char *const urc_prefix; 00033 }; 00034 00035 static const at_reg_t at_reg[] = { 00036 { CellularNetwork::C_EREG, "+CEREG", "+CEREG:"}, 00037 { CellularNetwork::C_GREG, "+CGREG", "+CGREG:"}, 00038 { CellularNetwork::C_REG, "+CREG", "+CREG:"} 00039 }; 00040 00041 #if MBED_CONF_MBED_TRACE_ENABLE 00042 static const char *const reg_type_str[(int)AT_CellularNetwork::RegistrationStatusMax] = { 00043 "NotRegistered", 00044 "RegisteredHomeNetwork", 00045 "SearchingNetwork", 00046 "RegistrationDenied", 00047 "RegistrationUnknown", 00048 "RegisteredRoaming", 00049 "RegisteredSMSOnlyHome", 00050 "RegisteredSMSOnlyRoaming", 00051 "AttachedEmergencyOnly", 00052 "RegisteredCSFBNotPreferredHome", 00053 "RegisteredCSFBNotPreferredRoaming", 00054 "AlreadyRegistered" 00055 }; 00056 00057 static const char *const rat_str[AT_CellularNetwork::RAT_MAX] = { 00058 "GSM", 00059 "GSM_COMPACT", 00060 "UTRAN", 00061 "EGPRS", 00062 "HSDPA", 00063 "HSUPA", 00064 "HSDPA_HSUPA", 00065 "E_UTRAN", 00066 "CATM1", 00067 "NB1", 00068 "RAT unknown", 00069 }; 00070 00071 #endif 00072 00073 00074 AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : 00075 _connection_status_cb(NULL), _ciotopt_network_support_cb(NULL), _op_act(RAT_UNKNOWN), 00076 _connect_status(NSAPI_STATUS_DISCONNECTED ), _supported_network_opt(CIOT_OPT_MAX), 00077 _at(atHandler), _device(device) 00078 { 00079 _urc_funcs[C_EREG] = callback(this, &AT_CellularNetwork::urc_cereg); 00080 _urc_funcs[C_GREG] = callback(this, &AT_CellularNetwork::urc_cgreg); 00081 _urc_funcs[C_REG] = callback(this, &AT_CellularNetwork::urc_creg); 00082 00083 for (int type = 0; type < CellularNetwork::C_MAX; type++) { 00084 if (_device.get_property((AT_CellularDevice::CellularProperty)type) != RegistrationModeDisable) { 00085 _at.set_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type]); 00086 } 00087 } 00088 00089 if (_device.get_property(AT_CellularDevice::PROPERTY_AT_CGEREP)) { 00090 // additional urc to get better disconnect info for application. Not critical. 00091 _at.set_urc_handler("+CGEV: NW DET", callback(this, &AT_CellularNetwork::urc_cgev)); 00092 _at.set_urc_handler("+CGEV: ME DET", callback(this, &AT_CellularNetwork::urc_cgev)); 00093 } 00094 00095 00096 _at.set_urc_handler("+CCIOTOPTI:", callback(this, &AT_CellularNetwork::urc_cciotopti)); 00097 } 00098 00099 AT_CellularNetwork::~AT_CellularNetwork() 00100 { 00101 (void)set_packet_domain_event_reporting(false); 00102 for (int type = 0; type < CellularNetwork::C_MAX; type++) { 00103 if (_device.get_property((AT_CellularDevice::CellularProperty)type) != RegistrationModeDisable) { 00104 _at.set_urc_handler(at_reg[type].urc_prefix, 0); 00105 } 00106 } 00107 00108 if (_device.get_property(AT_CellularDevice::PROPERTY_AT_CGEREP)) { 00109 _at.set_urc_handler("+CGEV: ME DET", 0); 00110 _at.set_urc_handler("+CGEV: NW DET", 0); 00111 } 00112 _at.set_urc_handler("+CCIOTOPTI:", 0); 00113 } 00114 00115 void AT_CellularNetwork::urc_cgev() 00116 { 00117 call_network_cb(NSAPI_STATUS_DISCONNECTED ); 00118 } 00119 00120 void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type) 00121 { 00122 registration_params_t reg_params; 00123 read_reg_params(type, reg_params); 00124 00125 if (_at.get_last_error() == NSAPI_ERROR_OK && _connection_status_cb) { 00126 _reg_params._type = type; 00127 cell_callback_data_t data; 00128 data.error = NSAPI_ERROR_OK ; 00129 if (reg_params._act != _reg_params._act) { 00130 _reg_params._act = reg_params._act; 00131 data.status_data = reg_params._act; 00132 _connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, (intptr_t)&data); 00133 } 00134 if (reg_params._status != _reg_params._status) { 00135 RegistrationStatus previous_registration_status = _reg_params._status; 00136 _reg_params._status = reg_params._status; 00137 data.status_data = reg_params._status; 00138 _connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data); 00139 if (reg_params._status == NotRegistered) { // Other states means that we are trying to connect or connected 00140 if (previous_registration_status == RegisteredHomeNetwork || 00141 previous_registration_status == RegisteredRoaming) { 00142 if (type != C_REG) {// we are interested only if we drop from packet network 00143 _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_STATUS_DISCONNECTED ); 00144 } 00145 } 00146 } 00147 } 00148 if (reg_params._cell_id != -1 && reg_params._cell_id != _reg_params._cell_id) { 00149 _reg_params._cell_id = reg_params._cell_id; 00150 _reg_params._lac = reg_params._lac; 00151 data.status_data = reg_params._cell_id; 00152 _connection_status_cb((nsapi_event_t)CellularCellIDChanged, (intptr_t)&data); 00153 } 00154 } 00155 } 00156 00157 void AT_CellularNetwork::urc_creg() 00158 { 00159 read_reg_params_and_compare(C_REG); 00160 } 00161 00162 void AT_CellularNetwork::urc_cereg() 00163 { 00164 read_reg_params_and_compare(C_EREG); 00165 } 00166 00167 void AT_CellularNetwork::urc_cgreg() 00168 { 00169 read_reg_params_and_compare(C_GREG); 00170 } 00171 00172 void AT_CellularNetwork::call_network_cb(nsapi_connection_status_t status) 00173 { 00174 if (_connection_status_cb) { 00175 _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , _connect_status); 00176 } 00177 } 00178 00179 void AT_CellularNetwork::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb) 00180 { 00181 _connection_status_cb = status_cb; 00182 } 00183 00184 nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bool urc_on) 00185 { 00186 int index = (int)type; 00187 MBED_ASSERT(index >= 0 && index < C_MAX); 00188 00189 RegistrationMode mode = (RegistrationMode)_device.get_property((AT_CellularDevice::CellularProperty)type); 00190 if (mode == RegistrationModeDisable) { 00191 return NSAPI_ERROR_UNSUPPORTED ; 00192 } else { 00193 if (urc_on) { 00194 return _at.at_cmd_discard(at_reg[index].cmd, "=", "%d", mode); 00195 } else { 00196 return _at.at_cmd_discard(at_reg[index].cmd, "=0"); 00197 } 00198 } 00199 } 00200 00201 nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode &mode) 00202 { 00203 int ret; 00204 nsapi_error_t error = _at.at_cmd_int("+COPS", "?", ret); 00205 mode = (NWRegisteringMode)ret; 00206 return error; 00207 } 00208 00209 nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn) 00210 { 00211 00212 if (!plmn) { 00213 tr_debug("Automatic network registration"); 00214 NWRegisteringMode mode; 00215 if (get_network_registering_mode(mode) != NSAPI_ERROR_OK ) { 00216 return NSAPI_ERROR_DEVICE_ERROR ; 00217 } 00218 if (mode != NWModeAutomatic) { 00219 return _at.at_cmd_discard("+COPS", "=0"); 00220 } 00221 return NSAPI_ERROR_OK ; 00222 } else { 00223 tr_debug("Manual network registration to %s", plmn); 00224 if (_op_act != RAT_UNKNOWN) { 00225 return _at.at_cmd_discard("+COPS", "=1,2,", "%s%d", plmn, _op_act); 00226 } else { 00227 return _at.at_cmd_discard("+COPS", "=1,2,", "%s", plmn); 00228 } 00229 } 00230 } 00231 00232 void AT_CellularNetwork::read_reg_params(RegistrationType type, registration_params_t ®_params) 00233 { 00234 const int MAX_STRING_LENGTH = 9; 00235 char string_param[MAX_STRING_LENGTH] = {0}; 00236 00237 reg_params._type = type; 00238 00239 int int_param = _at.read_int(); 00240 reg_params._status = (int_param >= 0 && int_param < RegistrationStatusMax) ? (RegistrationStatus)int_param : NotRegistered; 00241 00242 int len = _at.read_string(string_param, TWO_BYTES_HEX + 1); 00243 if (len > 0) { 00244 reg_params._lac = hex_str_to_int(string_param, TWO_BYTES_HEX); 00245 } else { 00246 reg_params._lac = -1; 00247 } 00248 00249 len = _at.read_string(string_param, FOUR_BYTES_HEX + 1); 00250 if (len > 0) { 00251 reg_params._cell_id = hex_str_to_int(string_param, FOUR_BYTES_HEX); 00252 } else { 00253 reg_params._cell_id = -1; 00254 } 00255 00256 int_param = _at.read_int(); 00257 reg_params._act = (int_param >= 0 && int_param < RAT_MAX) ? (RadioAccessTechnology)int_param : RAT_UNKNOWN ; 00258 00259 // Skip [<cause_type>],[<reject_cause>] 00260 _at.skip_param(2); 00261 00262 len = _at.read_string(string_param, ONE_BYTE_BINARY + 1); 00263 reg_params._active_time = calculate_active_time(string_param, len); 00264 00265 len = _at.read_string(string_param, ONE_BYTE_BINARY + 1); 00266 reg_params._periodic_tau = calculate_periodic_tau(string_param, len); 00267 00268 #if MBED_CONF_MBED_TRACE_ENABLE 00269 tr_debug("%s %s, LAC %d, cell %d, %s", at_reg[(int)type].urc_prefix, reg_type_str[reg_params._status], reg_params._lac, reg_params._cell_id, rat_str[reg_params._act]); 00270 #endif 00271 } 00272 00273 nsapi_error_t AT_CellularNetwork::set_attach() 00274 { 00275 _at.lock(); 00276 AttachStatus status; 00277 get_attach(status); 00278 00279 if (status == Detached) { 00280 tr_debug("Network attach"); 00281 _at.at_cmd_discard("+CGATT", "=1"); 00282 } 00283 00284 return _at.unlock_return_error(); 00285 } 00286 00287 nsapi_error_t AT_CellularNetwork::get_attach(AttachStatus &status) 00288 { 00289 int attach_status; 00290 nsapi_error_t err = _at.at_cmd_int("+CGATT", "?", attach_status); 00291 status = (attach_status == 1) ? Attached : Detached; 00292 00293 return err; 00294 } 00295 00296 nsapi_error_t AT_CellularNetwork::detach() 00297 { 00298 _at.lock(); 00299 tr_debug("Network detach"); 00300 _at.at_cmd_discard("+CGATT", "=0"); 00301 00302 _at.at_cmd_discard("+COPS", "=2"); 00303 00304 call_network_cb(NSAPI_STATUS_DISCONNECTED ); 00305 00306 return _at.unlock_return_error(); 00307 } 00308 00309 nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct) 00310 { 00311 _op_act = RAT_UNKNOWN; 00312 return NSAPI_ERROR_UNSUPPORTED ; 00313 } 00314 00315 nsapi_error_t AT_CellularNetwork::set_access_technology(RadioAccessTechnology opAct) 00316 { 00317 if (opAct == RAT_UNKNOWN) { 00318 return NSAPI_ERROR_UNSUPPORTED ; 00319 } 00320 00321 _op_act = opAct; 00322 00323 return set_access_technology_impl(opAct); 00324 } 00325 00326 nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount) 00327 { 00328 int idx = 0; 00329 00330 _at.lock(); 00331 00332 _at.cmd_start_stop("+COPS", "=?"); 00333 00334 _at.resp_start("+COPS:"); 00335 00336 int ret, error_code = -1; 00337 operator_t *op = NULL; 00338 00339 while (_at.info_elem('(')) { 00340 00341 op = operators.add_new(); 00342 op->op_status = (operator_t::Status)_at.read_int(); 00343 _at.read_string(op->op_long, sizeof(op->op_long)); 00344 _at.read_string(op->op_short, sizeof(op->op_short)); 00345 _at.read_string(op->op_num, sizeof(op->op_num)); 00346 00347 // Optional - try read an int 00348 ret = _at.read_int(); 00349 op->op_rat = (ret == error_code) ? RAT_UNKNOWN : (RadioAccessTechnology)ret; 00350 00351 if ((_op_act == RAT_UNKNOWN) || 00352 ((op->op_rat != RAT_UNKNOWN) && (op->op_rat == _op_act))) { 00353 idx++; 00354 } else { 00355 operators.delete_last(); 00356 } 00357 } 00358 00359 _at.resp_stop(); 00360 00361 opsCount = idx; 00362 return _at.unlock_return_error(); 00363 } 00364 00365 nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(CIoT_Supported_Opt supported_opt, 00366 CIoT_Preferred_UE_Opt preferred_opt, 00367 Callback<void(CIoT_Supported_Opt)> network_support_cb) 00368 { 00369 _ciotopt_network_support_cb = network_support_cb; 00370 return _at.at_cmd_discard("+CCIOTOPT", "=1,", "%d%d", supported_opt, preferred_opt); 00371 } 00372 00373 void AT_CellularNetwork::urc_cciotopti() 00374 { 00375 _supported_network_opt = (CIoT_Supported_Opt)_at.read_int(); 00376 00377 if (_ciotopt_network_support_cb) { 00378 _ciotopt_network_support_cb(_supported_network_opt); 00379 } 00380 } 00381 00382 nsapi_error_t AT_CellularNetwork::get_ciot_ue_optimization_config(CIoT_Supported_Opt &supported_opt, 00383 CIoT_Preferred_UE_Opt &preferred_opt) 00384 { 00385 _at.lock(); 00386 00387 _at.cmd_start_stop("+CCIOTOPT", "?"); 00388 00389 _at.resp_start("+CCIOTOPT:"); 00390 _at.read_int(); 00391 if (_at.get_last_error() == NSAPI_ERROR_OK ) { 00392 supported_opt = (CIoT_Supported_Opt)_at.read_int(); 00393 preferred_opt = (CIoT_Preferred_UE_Opt)_at.read_int(); 00394 } 00395 00396 _at.resp_stop(); 00397 00398 return _at.unlock_return_error(); 00399 } 00400 00401 nsapi_error_t AT_CellularNetwork::get_ciot_network_optimization_config(CIoT_Supported_Opt &supported_network_opt) 00402 { 00403 supported_network_opt = _supported_network_opt; 00404 return NSAPI_ERROR_OK ; 00405 } 00406 00407 nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int *ber) 00408 { 00409 _at.lock(); 00410 00411 _at.cmd_start_stop("+CSQ", ""); 00412 00413 _at.resp_start("+CSQ:"); 00414 int t_rssi = _at.read_int(); 00415 int t_ber = _at.read_int(); 00416 _at.resp_stop(); 00417 if (t_rssi < 0 || t_ber < 0) { 00418 _at.unlock(); 00419 return NSAPI_ERROR_DEVICE_ERROR ; 00420 } 00421 00422 // RSSI value is returned in dBm with range from -51 to -113 dBm, see 3GPP TS 27.007 00423 if (t_rssi == 99) { 00424 rssi = SignalQualityUnknown; 00425 } else { 00426 rssi = -113 + 2 * t_rssi; 00427 } 00428 00429 if (ber) { 00430 if (t_ber == 99) { 00431 *ber = SignalQualityUnknown; 00432 } else { 00433 *ber = t_ber; 00434 } 00435 } 00436 00437 return _at.unlock_return_error(); 00438 } 00439 00440 /** Get the last 3GPP error code 00441 * @return see 3GPP TS 27.007 error codes 00442 */ 00443 int AT_CellularNetwork::get_3gpp_error() 00444 { 00445 return _at.get_3gpp_error(); 00446 } 00447 00448 nsapi_error_t AT_CellularNetwork::get_operator_params(int &format, operator_t &operator_params) 00449 { 00450 _at.lock(); 00451 00452 _at.cmd_start_stop("+COPS", "?"); 00453 00454 _at.resp_start("+COPS:"); 00455 _at.read_int(); //ignore mode 00456 format = _at.read_int(); 00457 00458 if (_at.get_last_error() == NSAPI_ERROR_OK ) { 00459 switch (format) { 00460 case 0: 00461 _at.read_string(operator_params.op_long, sizeof(operator_params.op_long)); 00462 break; 00463 case 1: 00464 _at.read_string(operator_params.op_short, sizeof(operator_params.op_short)); 00465 break; 00466 default: 00467 _at.read_string(operator_params.op_num, sizeof(operator_params.op_num)); 00468 break; 00469 } 00470 operator_params.op_rat = (RadioAccessTechnology)_at.read_int(); 00471 } 00472 00473 _at.resp_stop(); 00474 00475 return _at.unlock_return_error(); 00476 } 00477 00478 nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_names) 00479 { 00480 _at.lock(); 00481 00482 _at.cmd_start_stop("+COPN", ""); 00483 00484 _at.resp_start("+COPN:"); 00485 operator_names_t *names = NULL; 00486 while (_at.info_resp()) { 00487 names = op_names.add_new(); 00488 _at.read_string(names->numeric, sizeof(names->numeric)); 00489 _at.read_string(names->alpha, sizeof(names->alpha)); 00490 } 00491 00492 _at.resp_stop(); 00493 return _at.unlock_return_error(); 00494 } 00495 00496 void AT_CellularNetwork::get_context_state_command() 00497 { 00498 _at.cmd_start_stop("+CGACT", "?"); 00499 _at.resp_start("+CGACT:"); 00500 } 00501 00502 bool AT_CellularNetwork::is_active_context(int *number_of_active_contexts, int cid) 00503 { 00504 _at.lock(); 00505 00506 if (number_of_active_contexts) { 00507 *number_of_active_contexts = 0; 00508 } 00509 bool active_found = false; 00510 int context_id; 00511 // read active contexts 00512 get_context_state_command(); 00513 00514 while (_at.info_resp()) { 00515 context_id = _at.read_int(); // discard context id 00516 if (_at.read_int() == 1) { // check state 00517 tr_debug("Found active context"); 00518 if (number_of_active_contexts) { 00519 (*number_of_active_contexts)++; 00520 } 00521 if (cid == -1) { 00522 active_found = true; 00523 } else if (context_id == cid) { 00524 active_found = true; 00525 } 00526 if (!number_of_active_contexts && active_found) { 00527 break; 00528 } 00529 } 00530 } 00531 _at.resp_stop(); 00532 _at.unlock(); 00533 00534 return active_found; 00535 } 00536 00537 nsapi_error_t AT_CellularNetwork::get_registration_params(registration_params_t ®_params) 00538 { 00539 reg_params = _reg_params; 00540 return NSAPI_ERROR_OK ; 00541 } 00542 00543 nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type, registration_params_t ®_params) 00544 { 00545 int i = (int)type; 00546 MBED_ASSERT(i >= 0 && i < C_MAX); 00547 00548 if (!_device.get_property((AT_CellularDevice::CellularProperty)at_reg[i].type)) { 00549 return NSAPI_ERROR_UNSUPPORTED ; 00550 } 00551 00552 _at.lock(); 00553 00554 _at.cmd_start_stop(at_reg[i].cmd, "?"); 00555 00556 _at.resp_start(at_reg[i].urc_prefix); 00557 (void)_at.read_int(); // ignore urc mode subparam 00558 read_reg_params(type, reg_params); 00559 _at.resp_stop(); 00560 00561 _reg_params = reg_params; 00562 00563 return _at.unlock_return_error(); 00564 } 00565 00566 int AT_CellularNetwork::calculate_active_time(const char *active_time_string, int active_time_length) 00567 { 00568 if (active_time_length != ONE_BYTE_BINARY) { 00569 return -1; 00570 } 00571 00572 uint32_t ie_unit = binary_str_to_uint(active_time_string, TIMER_UNIT_LENGTH); 00573 uint32_t ie_value = binary_str_to_uint(active_time_string + TIMER_UNIT_LENGTH, active_time_length - TIMER_UNIT_LENGTH); 00574 00575 switch (ie_unit) { 00576 case 0: // multiples of 2 seconds 00577 return 2 * ie_value; 00578 case 1: // multiples of 1 minute 00579 return 60 * ie_value; 00580 case 2: // multiples of decihours 00581 return 6 * 60 * ie_value; 00582 case 7: // timer is deactivated 00583 return 0; 00584 default: // other values shall be interpreted as multiples of 1 minute 00585 return 60 * ie_value; 00586 } 00587 } 00588 00589 int AT_CellularNetwork::calculate_periodic_tau(const char *periodic_tau_string, int periodic_tau_length) 00590 { 00591 if (periodic_tau_length != ONE_BYTE_BINARY) { 00592 return -1; 00593 } 00594 00595 uint32_t ie_unit = binary_str_to_uint(periodic_tau_string, TIMER_UNIT_LENGTH); 00596 uint32_t ie_value = binary_str_to_uint(periodic_tau_string + TIMER_UNIT_LENGTH, periodic_tau_length - TIMER_UNIT_LENGTH); 00597 00598 switch (ie_unit) { 00599 case 0: // multiples of 10 minutes 00600 return 60 * 10 * ie_value; 00601 case 1: // multiples of 1 hour 00602 return 60 * 60 * ie_value; 00603 case 2: // multiples of 10 hours 00604 return 10 * 60 * 60 * ie_value; 00605 case 3: // multiples of 2 seconds 00606 return 2 * ie_value; 00607 case 4: // multiples of 30 seconds 00608 return 30 * ie_value; 00609 case 5: // multiples of 1 minute 00610 return 60 * ie_value; 00611 case 6: // multiples of 320 hours 00612 return 320 * 60 * 60 * ie_value; 00613 default: // timer is deactivated 00614 return 0; 00615 } 00616 } 00617 00618 nsapi_error_t AT_CellularNetwork::set_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) 00619 { 00620 char edrx[5]; 00621 uint_to_binary_str(edrx_value, edrx, 5, 4); 00622 edrx[4] = '\0'; 00623 00624 return _at.at_cmd_discard("+CEDRXS", "=", "%d%d%s", mode, act_type, edrx); 00625 } 00626 00627 nsapi_error_t AT_CellularNetwork::set_packet_domain_event_reporting(bool on) 00628 { 00629 if (!_device.get_property(AT_CellularDevice::PROPERTY_AT_CGEREP)) { 00630 return NSAPI_ERROR_UNSUPPORTED ; 00631 } 00632 00633 return _at.at_cmd_discard("+CGEREP", "=", "%d", on ? 1 : 0); 00634 } 00635 00636 nsapi_error_t AT_CellularNetwork::clear() 00637 { 00638 tr_info("AT_CellularNetwork::clear"); 00639 00640 _at.lock(); 00641 _at.cmd_start_stop("+CGDCONT", "?"); 00642 _at.resp_start("+CGDCONT:"); 00643 00644 struct context_s { 00645 int id; 00646 context_s *next; 00647 }; 00648 CellularList<context_s> contexts; 00649 while (_at.info_resp()) { 00650 int cid = _at.read_int(); 00651 // clear all but the default context 00652 if (cid <= 0) { 00653 continue; 00654 } else if (cid == 1) { 00655 #ifndef MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN 00656 continue; 00657 #else 00658 char pdp_type_from_context[10]; 00659 int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context)); 00660 if (pdp_type_len > 0) { 00661 char apn[MAX_ACCESSPOINT_NAME_LENGTH]; 00662 int apn_len = _at.read_string(apn, sizeof(apn)); 00663 if (apn_len >= 0) { 00664 if (strcmp(apn, MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) == 0) { 00665 continue; 00666 } 00667 } 00668 } 00669 #endif 00670 } 00671 contexts.add_new()->id = cid; 00672 } 00673 _at.resp_stop(); 00674 00675 if (contexts.get_head()) { 00676 // try to detach from network before deleting contexts 00677 (void)detach(); 00678 context_s *context = contexts.get_head(); 00679 while (context) { 00680 if (_at.at_cmd_discard("+CGDCONT", "=", "%d", context->id) != NSAPI_ERROR_OK ) { 00681 tr_warn("Clear context %d failed", context->id); 00682 } 00683 context = context->next; 00684 } 00685 #ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN 00686 char pdp_type_str[sizeof("IPV4V6")]; 00687 if (_device.get_property(AT_CellularDevice::PROPERTY_IPV4V6_PDP_TYPE) || 00688 (_device.get_property(AT_CellularDevice::PROPERTY_IPV4_PDP_TYPE) && _device.get_property(AT_CellularDevice::PROPERTY_IPV6_PDP_TYPE))) { 00689 strcpy(pdp_type_str, "IPV4V6"); 00690 } else if (_device.get_property(AT_CellularDevice::PROPERTY_IPV6_PDP_TYPE)) { 00691 strcpy(pdp_type_str, "IPV6"); 00692 } else { 00693 strcpy(pdp_type_str, "IP"); 00694 } 00695 _at.at_cmd_discard("+CGDCONT", "=", "%d%s%s", 1, pdp_type_str, MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN); 00696 #endif 00697 } 00698 00699 return _at.unlock_return_error(); 00700 } 00701 00702 ATHandler &AT_CellularNetwork::get_at_handler() 00703 { 00704 return _at; 00705 }
Generated on Tue Jul 12 2022 13:54:02 by
