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