Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UBLOX_AT_CellularContext.cpp Source File

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 */