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.
EasyCellularConnection.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 "CellularTargets.h" 00019 #ifdef CELLULAR_DEVICE 00020 00021 #if NSAPI_PPP_AVAILABLE 00022 #include "nsapi_ppp.h" 00023 #endif 00024 00025 #include "CellularConnectionFSM.h" 00026 #include "CellularUtil.h" 00027 00028 #include "EasyCellularConnection.h" 00029 #include "CellularLog.h" 00030 #include "mbed_wait_api.h" 00031 00032 #if USE_APN_LOOKUP 00033 #include "APN_db.h" 00034 #endif //USE_APN_LOOKUP 00035 00036 namespace mbed { 00037 00038 bool EasyCellularConnection::cellular_status(int state, int next_state) 00039 { 00040 tr_info("cellular_status: %s ==> %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)state), 00041 _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_state)); 00042 00043 if (_target_state == state) { 00044 tr_info("Target state reached: %s", _cellularConnectionFSM.get_state_string(_target_state)); 00045 MBED_ASSERT(_cellularSemaphore.release() == osOK); 00046 return false; // return false -> state machine is halted 00047 } 00048 return true; 00049 } 00050 00051 void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr) 00052 { 00053 if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE ) { 00054 if (ptr == NSAPI_STATUS_GLOBAL_UP ) { 00055 _is_connected = true; 00056 } else { 00057 _is_connected = false; 00058 } 00059 } 00060 if (_status_cb) { 00061 _status_cb(ev, ptr); 00062 } 00063 } 00064 00065 EasyCellularConnection::EasyCellularConnection(bool debug) : 00066 _is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial( 00067 MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(), _credentials_err( 00068 NSAPI_ERROR_OK ), _status_cb(0) 00069 { 00070 tr_info("EasyCellularConnection()"); 00071 #if USE_APN_LOOKUP 00072 _credentials_set = false; 00073 #endif // #if USE_APN_LOOKUP 00074 modem_debug_on(debug); 00075 } 00076 00077 EasyCellularConnection::~EasyCellularConnection() 00078 { 00079 _cellularConnectionFSM.stop(); 00080 } 00081 00082 nsapi_error_t EasyCellularConnection::init() 00083 { 00084 nsapi_error_t err = NSAPI_ERROR_OK ; 00085 if (!_is_initialized) { 00086 #if defined (MDMRTS) && defined (MDMCTS) 00087 _cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); 00088 #endif 00089 _cellularConnectionFSM.set_serial(&_cellularSerial); 00090 _cellularConnectionFSM.set_callback(callback(this, &EasyCellularConnection::cellular_status)); 00091 00092 err = _cellularConnectionFSM.init(); 00093 00094 if (err == NSAPI_ERROR_OK ) { 00095 err = _cellularConnectionFSM.start_dispatch(); 00096 _cellularConnectionFSM.attach(callback(this, &EasyCellularConnection::network_callback)); 00097 } 00098 _is_initialized = true; 00099 } 00100 00101 return err; 00102 } 00103 00104 void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd) 00105 { 00106 if (apn && strlen(apn) > 0) { 00107 _credentials_err = init(); 00108 00109 if (_credentials_err) { 00110 return; 00111 } 00112 CellularNetwork * network = _cellularConnectionFSM.get_network(); 00113 if (network) { 00114 _credentials_err = network->set_credentials(apn, uname, pwd); 00115 #if USE_APN_LOOKUP 00116 if (_credentials_err == NSAPI_ERROR_OK ) { 00117 _credentials_set = true; 00118 } 00119 #endif // #if USE_APN_LOOKUP 00120 } else { 00121 tr_error("NO Network..."); 00122 } 00123 } 00124 } 00125 00126 void EasyCellularConnection::set_sim_pin(const char *sim_pin) 00127 { 00128 if (sim_pin) { 00129 _cellularConnectionFSM.set_sim_pin(sim_pin); 00130 } 00131 } 00132 00133 nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) 00134 { 00135 if (_is_connected) { 00136 return NSAPI_ERROR_IS_CONNECTED ; 00137 } 00138 00139 set_credentials(apn, uname, pwd); 00140 if (_credentials_err) { 00141 return _credentials_err; 00142 } 00143 00144 if (sim_pin) { 00145 _cellularConnectionFSM.set_sim_pin(sim_pin); 00146 } 00147 00148 return connect(); 00149 } 00150 00151 nsapi_error_t EasyCellularConnection::check_connect() 00152 { 00153 if (_is_connected) { 00154 return NSAPI_ERROR_IS_CONNECTED ; 00155 } 00156 00157 // there was an error while setting credentials but it's a void function so check error here... 00158 if (_credentials_err) { 00159 return _credentials_err; 00160 } 00161 00162 nsapi_error_t err = init(); 00163 if (err) { 00164 return err; 00165 } 00166 00167 return NSAPI_ERROR_OK ; 00168 } 00169 00170 nsapi_error_t EasyCellularConnection::connect() 00171 { 00172 nsapi_error_t err = check_connect(); 00173 if (err) { 00174 return err; 00175 } 00176 #if USE_APN_LOOKUP 00177 if (!_credentials_set) { 00178 _target_state = CellularConnectionFSM::STATE_SIM_PIN; 00179 err = _cellularConnectionFSM.continue_to_state(_target_state); 00180 if (err == NSAPI_ERROR_OK ) { 00181 int sim_wait = _cellularSemaphore.wait(60*1000); // reserve 60 seconds to access to SIM 00182 if (sim_wait != 1) { 00183 tr_error("NO SIM ACCESS"); 00184 err = NSAPI_ERROR_NO_CONNECTION ; 00185 } else { 00186 char imsi[MAX_IMSI_LENGTH+1]; 00187 wait(1); // need to wait to access SIM in some modems 00188 err = _cellularConnectionFSM.get_sim()->get_imsi(imsi); 00189 if (err == NSAPI_ERROR_OK ) { 00190 const char *apn_config = apnconfig(imsi); 00191 if (apn_config) { 00192 const char* apn = _APN_GET(apn_config); 00193 const char* uname = _APN_GET(apn_config); 00194 const char* pwd = _APN_GET(apn_config); 00195 tr_info("Looked up APN %s", apn); 00196 err = _cellularConnectionFSM.get_network()->set_credentials(apn, uname, pwd); 00197 } 00198 } 00199 } 00200 } 00201 if (err) { 00202 tr_info("APN lookup failed"); 00203 return err; 00204 } 00205 } 00206 #endif // USE_APN_LOOKUP 00207 00208 _target_state = CellularConnectionFSM::STATE_CONNECTED; 00209 err = _cellularConnectionFSM.continue_to_state(_target_state); 00210 if (err == NSAPI_ERROR_OK ) { 00211 int ret_wait = _cellularSemaphore.wait(10 * 60 * 1000); // cellular network searching may take several minutes 00212 if (ret_wait != 1) { 00213 tr_info("No cellular connection"); 00214 err = NSAPI_ERROR_NO_CONNECTION ; 00215 } 00216 } 00217 00218 return err; 00219 } 00220 00221 nsapi_error_t EasyCellularConnection::disconnect() 00222 { 00223 _credentials_err = NSAPI_ERROR_OK ; 00224 _is_connected = false; 00225 #if USE_APN_LOOKUP 00226 _credentials_set = false; 00227 #endif // #if USE_APN_LOOKUP 00228 if (!_cellularConnectionFSM.get_network()) { 00229 return NSAPI_ERROR_NO_CONNECTION ; 00230 } 00231 return _cellularConnectionFSM.get_network()->disconnect(); 00232 } 00233 00234 bool EasyCellularConnection::is_connected() 00235 { 00236 return _is_connected; 00237 } 00238 00239 const char *EasyCellularConnection::get_ip_address() 00240 { 00241 CellularNetwork *network = _cellularConnectionFSM.get_network(); 00242 if (!network) { 00243 return NULL; 00244 } 00245 return _cellularConnectionFSM.get_network()->get_ip_address(); 00246 } 00247 00248 const char *EasyCellularConnection::get_netmask() 00249 { 00250 CellularNetwork *network = _cellularConnectionFSM.get_network(); 00251 if (!network) { 00252 return NULL; 00253 } 00254 00255 return network->get_netmask(); 00256 } 00257 00258 const char *EasyCellularConnection::get_gateway() 00259 { 00260 CellularNetwork *network = _cellularConnectionFSM.get_network(); 00261 if (!network) { 00262 return NULL; 00263 } 00264 00265 return network->get_gateway(); 00266 } 00267 00268 void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) 00269 { 00270 _status_cb = status_cb; 00271 } 00272 00273 void EasyCellularConnection::modem_debug_on(bool on) 00274 { 00275 CellularDevice *dev = _cellularConnectionFSM.get_device(); 00276 if (dev) { 00277 dev->modem_debug_on(on); 00278 } 00279 } 00280 00281 NetworkStack *EasyCellularConnection::get_stack() 00282 { 00283 return _cellularConnectionFSM.get_stack(); 00284 } 00285 00286 } // namespace 00287 00288 #endif // CELLULAR_DEVICE
Generated on Tue Jul 12 2022 15:17:19 by
1.7.2