takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UBLOX_AT_CellularNetwork.cpp Source File

UBLOX_AT_CellularNetwork.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 
00018 #include "UBLOX_AT_CellularNetwork.h"
00019 #include "UBLOX_AT_CellularStack.h"
00020 
00021 using namespace mbed;
00022 
00023 UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
00024 {
00025     _op_act = RAT_UNKNOWN;
00026     // The authentication to use
00027     _auth = NSAPI_SECURITY_UNKNOWN ;
00028 }
00029 
00030 UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork()
00031 {
00032     if (_connection_status_cb) {
00033         _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_ERROR_CONNECTION_LOST );
00034     }
00035 }
00036 
00037 NetworkStack *UBLOX_AT_CellularNetwork::get_stack()
00038 {
00039     if (!_stack) {
00040         _stack = new UBLOX_AT_CellularStack(_at, _cid, _ip_stack_type);
00041     }
00042     return _stack;
00043 }
00044 
00045 bool UBLOX_AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
00046 {
00047     return requested_stack == IPV4_STACK ? true : false;
00048 }
00049 
00050 AT_CellularNetwork::RegistrationMode UBLOX_AT_CellularNetwork::has_registration(RegistrationType reg_type)
00051 {
00052     return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
00053 }
00054 
00055 nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
00056 {
00057     switch(opRat) {
00058 #if defined(TARGET_UBLOX_C030_U201) || defined(TARGET_UBLOX_C027)
00059         case RAT_GSM:
00060         case RAT_GSM_COMPACT:
00061             break;
00062         case RAT_EGPRS:
00063             break;
00064 #elif defined(TARGET_UBLOX_C030_U201)
00065         case RAT_UTRAN:
00066             break;
00067         case RAT_HSDPA:
00068             break;
00069         case RAT_HSUPA:
00070             break;
00071         case RAT_HSDPA_HSUPA:
00072             break;
00073 #elif defined(TARGET_UBLOX_C030_R410M)
00074         case RAT_CATM1:
00075             break;
00076 #elif defined(TARGET_UBLOX_C030_R410M) || defined(TARGET_UBLOX_C030_N211)
00077         case RAT_NB1:
00078             break;
00079 #endif
00080         default: {
00081             _op_act = RAT_UNKNOWN;
00082             return NSAPI_ERROR_UNSUPPORTED ;
00083         }
00084     }
00085 
00086     return NSAPI_ERROR_OK ;
00087 }
00088 
00089 nsapi_error_t UBLOX_AT_CellularNetwork::connect()
00090 {
00091     _at.lock();
00092     nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION ;
00093 
00094     // Attempt to establish a connection
00095 #ifdef TARGET_UBLOX_C030_R410M
00096     err = NSAPI_ERROR_OK ;
00097 #else
00098     err = open_data_channel();
00099 #endif
00100     if (err != NSAPI_ERROR_OK ) {
00101         // If new PSD context was created and failed to activate, delete it
00102         if (_new_context_set) {
00103             disconnect_modem_stack();
00104         }
00105         _connect_status = NSAPI_STATUS_DISCONNECTED ;
00106     } else {
00107         _connect_status = NSAPI_STATUS_GLOBAL_UP ;
00108     }
00109     _at.unlock();
00110 
00111     if (_connection_status_cb) {
00112         _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , _connect_status);
00113     }
00114 
00115     return err;
00116 }
00117 
00118 nsapi_error_t UBLOX_AT_CellularNetwork::open_data_channel()
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.cmd_start("AT+UPSND=" PROFILE ",8");
00133     _at.cmd_stop();
00134     _at.resp_start("+UPSND:");
00135     _at.read_int();
00136     _at.read_int();
00137     active = _at.read_int();
00138     _at.resp_stop();
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) ? _auth : NSAPI_SECURITY_NONE ;
00154             } else {
00155                 _auth = NSAPI_SECURITY_NONE ;
00156             }
00157             success = activate_profile(_apn, _uname, _pwd);
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_CellularNetwork::activate_profile(const char* apn,
00170         const char* username,
00171         const char* password)
00172 {
00173     bool activated = false;
00174     bool success = false;
00175 
00176     // Set up the APN
00177     if (apn) {
00178         success = false;
00179         _at.cmd_start("AT+UPSD=0,1,");
00180         _at.write_string(apn);
00181         _at.cmd_stop();
00182         _at.resp_start();
00183         _at.resp_stop();
00184 
00185         if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00186             success = true;
00187         }
00188     }
00189     // Set up the UserName
00190     if (success && username) {
00191         success = false;
00192         _at.cmd_start("AT+UPSD=" PROFILE ",2,");
00193         _at.write_string(username);
00194         _at.cmd_stop();
00195         _at.resp_start();
00196         _at.resp_stop();
00197 
00198         if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00199             success = true;
00200         }
00201     }
00202     // Set up the Password
00203     if (success && password) {
00204         success = false;
00205         _at.cmd_start("AT+UPSD=" PROFILE ",3,");
00206         _at.write_string(password);
00207         _at.cmd_stop();
00208         _at.resp_start();
00209         _at.resp_stop();
00210 
00211         if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00212             success = true;
00213         }
00214     }
00215 
00216     if (success) {
00217         _at.cmd_start("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"");
00218         _at.cmd_stop();
00219         _at.resp_start();
00220         _at.resp_stop();
00221 
00222         // Set up the authentication protocol
00223         // 0 = none
00224         // 1 = PAP (Password Authentication Protocol)
00225         // 2 = CHAP (Challenge Handshake Authentication Protocol)
00226         for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE );
00227                 success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP )); protocol++) {
00228             if ((_auth == NSAPI_SECURITY_UNKNOWN ) || (nsapi_security_to_modem_security(_auth) == protocol)) {
00229                 _at.cmd_start("AT+UPSD=0,6,");
00230                 _at.write_int(protocol);
00231                 _at.cmd_stop();
00232                 _at.resp_start();
00233                 _at.resp_stop();
00234 
00235                 if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00236                     // Activate, wait upto 30 seconds for the connection to be made
00237                     _at.set_at_timeout(30000);
00238                     _at.cmd_start("AT+UPSDA=0,3");
00239                     _at.cmd_stop();
00240                     _at.resp_start();
00241                     _at.resp_stop();
00242                     _at.restore_at_timeout();
00243 
00244                     if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00245                         activated = true;
00246                     }
00247                 }
00248             }
00249         }
00250     }
00251 
00252     return activated;
00253 }
00254 
00255 // Convert nsapi_security_t to the modem security numbers
00256 int UBLOX_AT_CellularNetwork::nsapi_security_to_modem_security(nsapi_security_t nsapi_security)
00257 {
00258     int modem_security = 3;
00259 
00260     switch (nsapi_security) {
00261         case NSAPI_SECURITY_NONE :
00262             modem_security = 0;
00263             break;
00264         case NSAPI_SECURITY_PAP :
00265             modem_security = 1;
00266             break;
00267         case NSAPI_SECURITY_CHAP :
00268             modem_security = 2;
00269             break;
00270         case NSAPI_SECURITY_UNKNOWN :
00271             modem_security = 3;
00272             break;
00273         default:
00274             modem_security = 3;
00275             break;
00276     }
00277 
00278     return modem_security;
00279 }
00280 
00281 // Disconnect the on board IP stack of the modem.
00282 bool UBLOX_AT_CellularNetwork::disconnect_modem_stack()
00283 {
00284     bool success = false;
00285 
00286     if (get_ip_address() != NULL) {
00287         _at.cmd_start("AT+UPSDA=" PROFILE ",4");
00288         _at.cmd_stop();
00289         _at.resp_start();
00290         _at.resp_stop();
00291 
00292         if (_at.get_last_error() == NSAPI_ERROR_OK ) {
00293             success = true;
00294         }
00295     }
00296 
00297     return success;
00298 }
00299 
00300 nsapi_error_t UBLOX_AT_CellularNetwork::get_imsi(char* imsi)
00301 {
00302     _at.lock();
00303     _at.cmd_start("AT+CIMI");
00304     _at.cmd_stop();
00305     _at.resp_start();
00306     int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
00307     if (len > 0) {
00308         imsi[len] = '\0';
00309     }
00310     _at.resp_stop();
00311 
00312     return _at.unlock_return_error();
00313 }
00314 
00315 // Get the next set of credentials, based on IMSI.
00316 void UBLOX_AT_CellularNetwork::get_next_credentials(char ** config)
00317 {
00318     if (*config) {
00319         _apn    = _APN_GET(*config);
00320         _uname  = _APN_GET(*config);
00321         _pwd    = _APN_GET(*config);
00322     }
00323 }
00324 
00325 const char *UBLOX_AT_CellularNetwork::get_gateway()
00326 {
00327     return get_ip_address();
00328 }