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.
Fork of CNManager by
CNManager.cpp
00001 #include "CNManager.h" 00002 00003 #include "CNData.h" 00004 #include "CNUtil.h" 00005 #include "CNLib.h" 00006 #include "CNReg.h" 00007 00008 //! Manager internal state 00009 typedef enum { 00010 MNG_NOT_INIT = 0, //!< not initiated 00011 MNG_RADIO_OFF, //!< radio is off 00012 MNG_RADIO_ON, //!< radio is on 00013 MNG_IDLE, //!< idle 00014 MNG_DATA_UP, //!< data connection is active 00015 MNG_ERROR_RESET, //!< reset 00016 MNG_ERROR_STUCK //!< unrecoverable error 00017 } MngState; 00018 00019 static MngState state = MNG_NOT_INIT; //!< Manager state 00020 static bool moduleOn; //!< Module power requested power status 00021 static bool dataOn; 00022 static CNLib* cnLib; //!< Pointer to CN library 00023 static char simPin[10]; //!< Sim Pin 00024 static int errorCounter; //!< Error counter 00025 static evMngHandler mngHandler; //!< Function point handler 00026 static void* paramDataHandler; //!< Pointer to pass to the handler 00027 static int respError; 00028 00029 static CNResp radioSwitchOn(CNLib*& lib); 00030 static CNResp radioSwitchOff(CNLib*& lib); 00031 static CNResp simInit(CNLib* lib, char* simPin); 00032 00033 bool cnInit(bool powerOn /*=true*/, bool dataEnabled /*=true*/, bool roomingEnabled /*=true*/){ 00034 mngHandler = NULL; 00035 paramDataHandler = NULL; 00036 state = MNG_RADIO_OFF; 00037 moduleOn = powerOn; 00038 errorCounter = 0; 00039 respError = 0; 00040 cnRegInit(); 00041 cnDataInit(); 00042 dataOn = dataEnabled; 00043 cnRegSetRoaming(roomingEnabled); 00044 return true; 00045 } 00046 00047 void cnRegHandler(evMngHandler handler, void* param/*=NULL*/) 00048 { 00049 mngHandler = handler; 00050 paramDataHandler = param; 00051 } 00052 00053 MDMSerial* cnGetMDM(){ 00054 return (MDMSerial*) cnLib; 00055 } 00056 00057 void cnSetPower(bool on){ 00058 moduleOn = on; 00059 } 00060 00061 void cnSetDataEnabled(bool hasDataConnToBeEnabled){ 00062 TRACE("%s enter \r\n", __FUNCTION__); 00063 dataOn = hasDataConnToBeEnabled; 00064 cnDataEnable(dataOn); 00065 } 00066 00067 void cnSetRoamingOn(bool isRoomingEnabled){ 00068 cnRegSetRoaming(isRoomingEnabled); 00069 } 00070 00071 void cnSetApn(const char *apn,const char* username/*= NULL*/,const char* password/*= NULL*/){ 00072 cnDataSetupApn(apn, username, password); 00073 } 00074 00075 void cnSetSimPin(const char* pin){ 00076 if (pin) 00077 strncpy(simPin,pin, sizeof(simPin)); 00078 } 00079 00080 bool cnIsDataUp(){ 00081 return (state == MNG_DATA_UP)? true : false; 00082 } 00083 00084 bool cnSetDebug(int level){ 00085 if (!setUtilDebugLevel(level)) 00086 return false; 00087 return true; 00088 } 00089 00090 int cnLoop(){ 00091 int ret; 00092 MngState oldState = state; 00093 00094 TRACE("%s enter \r\n", __FUNCTION__); 00095 //check if init has been called 00096 if (state == MNG_NOT_INIT){ 00097 ERROR("%s Module has not been initiated\r\n", __FUNCTION__); 00098 return false; 00099 } 00100 //switch on 00101 if (state == MNG_RADIO_OFF && moduleOn ){ 00102 INFO("%s: Switching ON radio \r\n", __FUNCTION__); 00103 cnDataEnable(dataOn); 00104 ret = radioSwitchOn(cnLib); 00105 state = (ret == RES_OK) ? MNG_RADIO_ON : MNG_ERROR_RESET; 00106 00107 } 00108 //switch off 00109 if (state != MNG_RADIO_OFF && !moduleOn){ 00110 INFO("%s: Switching OFF radio \r\n", __FUNCTION__); 00111 if (state == MNG_DATA_UP) 00112 //disable data 00113 cnDataEnable(false); 00114 else if (state == MNG_IDLE){ 00115 //switching off 00116 cnDataReset(); 00117 cnRegReset(); 00118 radioSwitchOff(cnLib); 00119 state = MNG_RADIO_OFF; 00120 } 00121 } 00122 //sim initialization 00123 if (state == MNG_RADIO_ON ){ 00124 ret = simInit(cnLib, simPin); 00125 state = (ret == RES_OK) ? MNG_IDLE : MNG_ERROR_RESET; 00126 if (state == MNG_IDLE && mngHandler) 00127 mngHandler(MNG_EV_IDLE, paramDataHandler); 00128 } 00129 //cycle the registration and data service 00130 if (state == MNG_IDLE || state == MNG_DATA_UP){ 00131 RegStatus regStatus; 00132 int res; 00133 DataConnStatus dataStatus; 00134 //Tick the registration service 00135 res = cnRegLoop(cnLib, ®Status); 00136 if (res != RES_OK && ++respError > MEX_RESP_ERROR) 00137 state = MNG_ERROR_RESET; 00138 //Tick Data service 00139 cnDataLoop(cnLib, regStatus, &dataStatus); 00140 //manage data status 00141 if (dataStatus == DATA_IS_CONNECTED){ 00142 state = MNG_DATA_UP; 00143 if (mngHandler) mngHandler(MNG_EV_DATA_UP, paramDataHandler); 00144 } else if (dataStatus == DATA_IS_DISCONNECTED){ 00145 state = MNG_IDLE; 00146 if (mngHandler) mngHandler(MNG_EV_DATA_DOWN, paramDataHandler); 00147 } 00148 } 00149 //error management 00150 if (state == MNG_ERROR_RESET){ 00151 //block state machine when errors reach a max value counter 00152 if (++errorCounter > MAX_ERROR_RETRIES) 00153 state = MNG_ERROR_STUCK; 00154 else{ 00155 //otherwise start reset procedure 00156 ERROR("%s: State machine is in Error state, doing Reset.\r\n", __FUNCTION__); 00157 respError=0; 00158 cnDataReset(); 00159 cnRegReset(); 00160 radioSwitchOff(cnLib); 00161 state = MNG_RADIO_OFF; 00162 } 00163 } 00164 //when the state is stuck stay here forever 00165 if (state == MNG_ERROR_STUCK){ 00166 ERROR("%s: State machine is in Blocked state, please change setting.\r\n", __FUNCTION__); 00167 return false; 00168 } 00169 //dump info 00170 if (getUtilDebugLevel() > 1 && oldState != state){ 00171 INFO("CNManager Dump\r\n"); 00172 const char* txtState[] = { "Not Initiated", "Radio is Off", "Radio is On", \ 00173 "Idle", "Connected", "Reset Error", "Blocked Error"}; 00174 if (state < sizeof(txtState)/sizeof(*txtState)) 00175 INFO(" Internal State: %s\r\n", txtState[state]); 00176 } 00177 return true; 00178 } 00179 00180 /** Switch On Radio 00181 \param lib pointer to library 00182 */ 00183 CNResp radioSwitchOn(CNLib*& lib) 00184 { 00185 TRACE("%s enter \r\n", __FUNCTION__); 00186 lib = new CNLib(); 00187 if (lib == NULL){ 00188 ERROR("%s: Error on allocating lib\r\n", __FUNCTION__); 00189 goto error; 00190 } 00191 lib->setDebug(getUtilDebugLevel()); 00192 //power on the module and detect if alive 00193 if (!RESPOK(lib->powerOnModem())){ 00194 ERROR("%s: Error on detecting the modem\r\n", __FUNCTION__); 00195 goto error; 00196 } 00197 //init generic modem 00198 if (!RESPOK(lib->initModem())){ 00199 ERROR("%s: Error on init device\r\n", __FUNCTION__); 00200 goto error; 00201 } 00202 //handle unknown device 00203 if (lib->getDev()->dev == MDMParser::DEV_UNKNOWN){ 00204 ERROR("%s: Device is unknown\r\n", __FUNCTION__); 00205 goto error; 00206 } 00207 return RES_OK; 00208 00209 error: 00210 return RES_ERROR; 00211 00212 } 00213 00214 /** Switch off the radio 00215 \param lib pointer to CN library 00216 */ 00217 CNResp radioSwitchOff(CNLib*& lib){ 00218 TRACE("%s enter \r\n", __FUNCTION__); 00219 if (lib != NULL){ 00220 lib->powerOff(); 00221 delete lib; 00222 } 00223 return RES_OK; 00224 } 00225 00226 /** Sim Pin initialization 00227 \param lib pointer to CN library 00228 \param simPin sim pin 00229 */ 00230 CNResp simEnterPin(CNLib* lib, char* simPin){ 00231 int res; 00232 00233 if (simPin == NULL){ 00234 ERROR("%s: Sim Pin is required but not provided\r\n", __FUNCTION__); 00235 return RES_ERROR_STUCK; 00236 } 00237 res = lib->simInit(simPin); 00238 if (RESPOK(res) ) 00239 return RES_OK; 00240 if (lib->getDev()->sim == MDMParser::WRONG_PIN){ 00241 ERROR("%s: Sim pin, %s ,provided is wrong\r\n", simPin); 00242 return RES_ERROR_STUCK; 00243 } 00244 return RES_ERROR; 00245 } 00246 00247 /** Sim initialization 00248 \param lib pointer to CN library 00249 \param simPin sim pin 00250 */ 00251 CNResp simInit(CNLib* lib, char* simPin) 00252 { 00253 CNResp res = RES_ERROR; 00254 int _simWaitCounter=0; 00255 TRACE("CNLib::%s enter\r\n", __FUNCTION__); 00256 00257 do{ 00258 if (RESPOK(lib->simInit(NULL))) 00259 break; 00260 wait_ms(10); 00261 } while(_simWaitCounter++ < SIM_WAIT_MAX_CYCLE); 00262 INFO("Sim status is %d \r\n", lib->getDev()->sim); 00263 //handle sim status 00264 switch (lib->getDev()->sim){ 00265 case MDMParser::SIM_READY: 00266 INFO("%s: Sim has been initiated correctly\r\n", __FUNCTION__); 00267 res = RES_OK; 00268 break; 00269 case MDMParser::SIM_PIN: 00270 INFO("%s: Sim Pin is requested\r\n"); 00271 res = simEnterPin(lib, simPin); 00272 break; 00273 case MDMParser::SIM_MISSING: 00274 ERROR("%s: Sim has not been inserted, HALT\r\n", __FUNCTION__); 00275 res = RES_ERROR; 00276 break; 00277 case MDMParser::SIM_PUK: 00278 ERROR("%s: Sim Puk is required, HALT\r\n", __FUNCTION__); 00279 res = RES_ERROR_STUCK; 00280 break; 00281 case MDMParser::SIM_UNKNOWN: 00282 ERROR("%s: Sim Unknown state\r\n", __FUNCTION__); 00283 res = RES_ERROR_STUCK; 00284 break; 00285 case MDMParser::WRONG_PIN: 00286 ERROR("%s: Wrong sim pin provided, HALT\r\n", __FUNCTION__); 00287 res = RES_ERROR_STUCK; 00288 break; 00289 } 00290 //sim has been successfully initialized 00291 if (res == RES_OK){ 00292 lib->getSimInfo(); 00293 } 00294 return res; 00295 } 00296 00297 void getNetStatus(MDMParser::NetStatus* net){ 00298 if (net && cnLib) 00299 memcpy(net, cnLib->getNet(), sizeof(MDMParser::NetStatus)); 00300 } 00301 void getDevStatus(MDMParser::DevStatus* dev){ 00302 if (dev && cnLib) 00303 memcpy(dev, cnLib->getDev(), sizeof(MDMParser::DevStatus)); 00304 }
Generated on Fri Jul 15 2022 21:42:35 by
1.7.2
