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
UBLOX_AT_CellularContext.cpp
00001 /* 00002 * Copyright (c) 2018, 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 #include "UBLOX_AT_CellularContext.h" 00018 #include "UBLOX_AT_CellularStack.h" 00019 #include "APN_db.h" 00020 #include "CellularLog.h" 00021 #include "rtos/ThisThread.h" 00022 00023 namespace mbed { 00024 00025 UBLOX_AT_CellularContext::UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) : 00026 AT_CellularContext(at, device, apn, cp_req, nonip_req) 00027 { 00028 // The authentication to use 00029 _auth = NOAUTH; 00030 } 00031 00032 UBLOX_AT_CellularContext::~UBLOX_AT_CellularContext() 00033 { 00034 } 00035 00036 NetworkStack *UBLOX_AT_CellularContext::get_stack() 00037 { 00038 if (_pdp_type == NON_IP_PDP_TYPE || _cp_in_use) { 00039 tr_error("Requesting stack for NON-IP context! Should request control plane netif: get_cp_netif()"); 00040 return NULL; 00041 } 00042 if (!_stack) { 00043 _stack = new UBLOX_AT_CellularStack(_at, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device()); 00044 } 00045 00046 return _stack; 00047 } 00048 00049 void UBLOX_AT_CellularContext::do_connect() 00050 { 00051 _at.lock(); 00052 _cb_data.error = NSAPI_ERROR_NO_CONNECTION ; 00053 00054 // Attempt to establish a connection 00055 #ifndef UBX_MDM_SARA_R41XM 00056 _cb_data.error = define_context(); 00057 #elif UBX_MDM_SARA_R410M 00058 _at.cmd_start_stop("+CGACT", "?"); 00059 _at.resp_start("+CGACT:"); 00060 _cid = _at.read_int(); 00061 _at.skip_param(1); 00062 _at.resp_stop(); 00063 00064 _is_connected = true; 00065 _is_context_active = true; 00066 _is_context_activated = true; 00067 _cb_data.error = NSAPI_ERROR_OK ; 00068 #elif UBX_MDM_SARA_R412M 00069 CellularNetwork::RadioAccessTechnology rat = read_radio_technology(); 00070 if (rat == CellularNetwork::RadioAccessTechnology::RAT_EGPRS) { 00071 if (!_is_context_active) { 00072 _at.set_at_timeout(150 * 1000); 00073 _at.at_cmd_discard("+CGACT", "=", "%d%d", 1, 1); 00074 00075 _at.cmd_start_stop("+CGACT", "?"); 00076 _at.resp_start("+CGACT:"); 00077 _at.skip_param(1); 00078 _is_context_activated = _at.read_int(); 00079 _at.resp_stop(); 00080 _at.restore_at_timeout(); 00081 if (_is_context_activated == true) { 00082 _cid = 1; 00083 _is_connected = true; 00084 _is_context_active = true; 00085 _cb_data.error = NSAPI_ERROR_OK ; 00086 } 00087 } 00088 } else if (rat == CellularNetwork::RadioAccessTechnology::RAT_CATM1 || rat == CellularNetwork::RadioAccessTechnology::RAT_NB1) { 00089 _at.cmd_start_stop("+CGACT", "?"); 00090 _at.resp_start("+CGACT:"); 00091 _cid = _at.read_int(); 00092 _at.skip_param(1); 00093 _at.resp_stop(); 00094 00095 _is_connected = true; 00096 _is_context_active = true; 00097 _is_context_activated = true; 00098 _cb_data.error = NSAPI_ERROR_OK ; 00099 } 00100 #endif 00101 if (_cb_data.error != NSAPI_ERROR_OK ) { 00102 // If new PSD context was created and failed to activate, delete it 00103 if (_new_context_set) { 00104 disconnect_modem_stack(); 00105 } 00106 _connect_status = NSAPI_STATUS_DISCONNECTED ; 00107 } else { 00108 _connect_status = NSAPI_STATUS_GLOBAL_UP ; 00109 } 00110 _at.unlock(); 00111 00112 if (_status_cb) { 00113 _status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , _connect_status); 00114 } 00115 } 00116 00117 #ifndef UBX_MDM_SARA_R41XM 00118 nsapi_error_t UBLOX_AT_CellularContext::define_context() 00119 { 00120 bool success = false; 00121 int active = 0; 00122 char *config = NULL; 00123 nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION ; 00124 char imsi[MAX_IMSI_LENGTH + 1]; 00125 00126 // do check for stack to validate that we have support for stack 00127 _stack = get_stack(); 00128 if (!_stack) { 00129 return err; 00130 } 00131 00132 _at.lock(); 00133 _at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 8); 00134 _at.resp_start("+UPSND:"); 00135 _at.skip_param(2); 00136 active = _at.read_int(); 00137 _at.resp_stop(); 00138 _at.unlock(); 00139 00140 if (active == 0) { 00141 // If the caller hasn't entered an APN, try to find it 00142 if (_apn == NULL) { 00143 err = get_imsi(imsi); 00144 if (err == NSAPI_ERROR_OK ) { 00145 config = (char *)apnconfig(imsi); 00146 } 00147 } 00148 00149 // Attempt to connect 00150 do { 00151 get_next_credentials(&config); 00152 if (_uname && _pwd) { 00153 _auth = (*_uname && *_pwd) ? _authentication_type : NOAUTH; 00154 } else { 00155 _auth = NOAUTH; 00156 } 00157 success = activate_profile(_apn, _uname, _pwd, _auth); 00158 } while (!success && config && *config); 00159 } else { 00160 // If the profile is already active, we're good 00161 success = true; 00162 } 00163 00164 err = (_at.get_last_error() == NSAPI_ERROR_OK ) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION ; 00165 00166 return err; 00167 } 00168 00169 bool UBLOX_AT_CellularContext::activate_profile(const char *apn, 00170 const char *username, 00171 const char *password, 00172 AuthenticationType auth) 00173 { 00174 bool activated = false; 00175 bool success = false; 00176 00177 // Set up the APN 00178 if (apn) { 00179 success = false; 00180 if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 1, apn) == NSAPI_ERROR_OK ) { 00181 success = true; 00182 } 00183 } 00184 // Set up the UserName 00185 if (success && username) { 00186 success = false; 00187 if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 2, username) == NSAPI_ERROR_OK ) { 00188 success = true; 00189 } 00190 } 00191 // Set up the Password 00192 if (success && password) { 00193 success = false; 00194 if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 3, password) == NSAPI_ERROR_OK ) { 00195 success = true; 00196 } 00197 } 00198 00199 if (success) { 00200 _at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 7, "0.0.0.0"); 00201 00202 if (_at.at_cmd_discard("+UPSD", "=", "%d%d%d", PROFILE, 6, nsapi_security_to_modem_security(auth)) == NSAPI_ERROR_OK ) { 00203 // Activate, wait upto 30 seconds for the connection to be made 00204 _at.set_at_timeout(30000); 00205 00206 nsapi_error_t err = _at.at_cmd_discard("+UPSDA", "=", "%d%d", PROFILE, 3); 00207 00208 _at.restore_at_timeout(); 00209 00210 if (err == NSAPI_ERROR_OK ) { 00211 Timer t1; 00212 t1.start(); 00213 while (!(t1.read() >= 180)) { 00214 _at.lock(); 00215 _at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 8); 00216 _at.resp_start("+UPSND:"); 00217 _at.skip_param(2); 00218 _at.read_int() ? activated = true : activated = false; 00219 _at.resp_stop(); 00220 _at.unlock(); 00221 00222 if (activated) { //If context is activated, exit while loop and return status 00223 break; 00224 } 00225 rtos::ThisThread::sleep_for(5000); //Wait for 5 seconds and then try again 00226 } 00227 t1.stop(); 00228 } 00229 } 00230 } 00231 00232 return activated; 00233 } 00234 #endif 00235 00236 // Convert nsapi_security_t to the modem security numbers 00237 int UBLOX_AT_CellularContext::nsapi_security_to_modem_security(AuthenticationType nsapi_security) 00238 { 00239 int modem_security = 3; 00240 00241 switch (nsapi_security) { 00242 case NOAUTH: 00243 modem_security = 0; 00244 break; 00245 case PAP: 00246 modem_security = 1; 00247 break; 00248 case CHAP: 00249 modem_security = 2; 00250 break; 00251 #ifndef UBX_MDM_SARA_R41XM 00252 case AUTOMATIC: 00253 modem_security = 3; 00254 break; 00255 default: 00256 modem_security = 3; 00257 break; 00258 #else 00259 default: 00260 modem_security = 0; 00261 break; 00262 #endif 00263 } 00264 00265 return modem_security; 00266 } 00267 00268 // Disconnect the on board IP stack of the modem. 00269 bool UBLOX_AT_CellularContext::disconnect_modem_stack() 00270 { 00271 SocketAddress addr; 00272 if (get_ip_address(&addr) == NSAPI_ERROR_OK ) { 00273 if (_at.at_cmd_discard("+UPSDA", "=", "%d%d", PROFILE, 4) == NSAPI_ERROR_OK ) { 00274 return true; 00275 } 00276 } 00277 00278 return false; 00279 } 00280 00281 nsapi_error_t UBLOX_AT_CellularContext::get_imsi(char *imsi) 00282 { 00283 _at.lock(); 00284 _at.cmd_start_stop("+CIMI", ""); 00285 _at.resp_start(); 00286 _at.read_string(imsi, MAX_IMSI_LENGTH + 1); 00287 _at.resp_stop(); 00288 00289 return _at.unlock_return_error(); 00290 } 00291 00292 // Get the next set of credentials, based on IMSI. 00293 void UBLOX_AT_CellularContext::get_next_credentials(char **config) 00294 { 00295 if (*config) { 00296 _apn = _APN_GET(*config); 00297 _uname = _APN_GET(*config); 00298 _pwd = _APN_GET(*config); 00299 } 00300 } 00301 00302 const char *UBLOX_AT_CellularContext::get_gateway() 00303 { 00304 return get_ip_address(); 00305 } 00306 00307 nsapi_error_t UBLOX_AT_CellularContext::get_gateway(SocketAddress *addr) 00308 { 00309 return get_ip_address(addr); 00310 } 00311 00312 const char *UBLOX_AT_CellularContext::get_apn() 00313 { 00314 return _apn; 00315 } 00316 00317 const char *UBLOX_AT_CellularContext::get_uname() 00318 { 00319 return _uname; 00320 } 00321 00322 const char *UBLOX_AT_CellularContext::get_pwd() 00323 { 00324 return _pwd; 00325 } 00326 00327 CellularContext::AuthenticationType UBLOX_AT_CellularContext::get_auth() 00328 { 00329 return _authentication_type; 00330 } 00331 00332 #ifdef UBX_MDM_SARA_R412M 00333 CellularNetwork::RadioAccessTechnology UBLOX_AT_CellularContext::read_radio_technology() 00334 { 00335 int act; 00336 CellularNetwork::RadioAccessTechnology rat; 00337 00338 _at.at_cmd_int("+URAT", "?", act); 00339 00340 switch (act) { 00341 case 0: 00342 rat = CellularNetwork::RadioAccessTechnology::RAT_GSM; 00343 break; 00344 case 1: 00345 rat = CellularNetwork::RadioAccessTechnology::RAT_GSM; 00346 break; 00347 case 2: 00348 rat = CellularNetwork::RadioAccessTechnology::RAT_UTRAN; 00349 break; 00350 case 7: 00351 rat = CellularNetwork::RadioAccessTechnology::RAT_CATM1; 00352 break; 00353 case 8: 00354 rat = CellularNetwork::RadioAccessTechnology::RAT_NB1; 00355 break; 00356 case 9: 00357 rat = CellularNetwork::RadioAccessTechnology::RAT_EGPRS; 00358 break; 00359 default: 00360 rat = CellularNetwork::RadioAccessTechnology::RAT_UNKNOWN; 00361 break; 00362 } 00363 00364 return rat; 00365 } 00366 #endif // #ifdef UBX_MDM_SARA_R412M 00367 00368 } /* namespace mbed */
Generated on Tue Jul 12 2022 13:55:01 by
