Base library for cellular modem implementations
Dependencies: Socket lwip-sys lwip
Dependents: CellularUSBModem CellularUSBModem
LinkMonitor.cpp
00001 /* LinkMonitor.cpp */ 00002 /* Copyright (C) 2012 mbed.org, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 #define __DEBUG__ 0 00021 #ifndef __MODULE__ 00022 #define __MODULE__ "LinkMonitor.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include "LinkMonitor.h" 00028 00029 #include <cstdio> 00030 using std::sscanf; 00031 00032 #define DEFAULT_TIMEOUT 10000 00033 00034 LinkMonitor::LinkMonitor(ATCommandsInterface* pIf) : m_pIf(pIf), m_rssi(0), m_registrationState(REGISTRATION_STATE_UNKNOWN), m_bearer(BEARER_UNKNOWN) 00035 { 00036 m_gsm = true; 00037 } 00038 00039 int LinkMonitor::init(bool gsm) 00040 { 00041 m_gsm = gsm; 00042 if (m_gsm) 00043 { 00044 // we need to make sure that we setup the operator selection to be in 'numeric' format. 00045 // i.e. it is made up of a network and country code when returned by the modem e.g. Operator = 23415. This allows easy logic parsing for 00046 // setting up other network parameters in future. 00047 DBG("LinkMonitor::init() being called. This should only happen once: executinging AT+COPS=0,2"); 00048 int ret = m_pIf->executeSimple("AT+COPS=0,2", NULL, DEFAULT_TIMEOUT); //Configure to set the operator string to Country Code and mobile network code 00049 if(ret != OK) 00050 { 00051 WARN(" NET_PROTOCOL error from sending the AT+COPS command to the modem. "); 00052 return NET_PROTOCOL; 00053 } 00054 } 00055 return OK; 00056 } 00057 00058 /*virtual*/ int LinkMonitor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00059 { 00060 DBG("Line is %s", line); 00061 char n[32] = ""; 00062 char s[32] = ""; 00063 int v; 00064 if( sscanf(line, "+CREG: %*d,%d", &v) >= 1 ) //Reg state is valid 00065 { 00066 DBG("+CREG %d", v); 00067 switch( v ) 00068 { 00069 case 0: 00070 m_registrationState = REGISTRATION_STATE_UNKNOWN; 00071 break; 00072 case 1: 00073 m_registrationState = REGISTRATION_STATE_HOME_NETWORK; 00074 break; 00075 case 2: 00076 m_registrationState = REGISTRATION_STATE_REGISTERING; 00077 break; 00078 case 3: 00079 m_registrationState = REGISTRATION_STATE_DENIED; 00080 break; 00081 case 4: 00082 m_registrationState = REGISTRATION_STATE_NO_SIGNAL; 00083 break; 00084 case 5: 00085 m_registrationState = REGISTRATION_STATE_ROAMING; 00086 break; 00087 default: 00088 m_registrationState = REGISTRATION_STATE_UNKNOWN; 00089 break; 00090 } 00091 } 00092 else if( sscanf(line, "+COPS: %*d,%*d,\"%*[^\"]\",%d", &v) >= 1 ) 00093 { 00094 DBG("+COPS %d", v); 00095 switch( v ) 00096 { 00097 case 0: 00098 m_bearer = BEARER_GSM; 00099 break; 00100 case 2: 00101 m_bearer = BEARER_UMTS; 00102 break; 00103 case 3: 00104 m_bearer = BEARER_EDGE; 00105 break; 00106 case 4: //HSDPA 00107 case 5: //HSUPA 00108 case 6: //HSDPA + HSUPA 00109 m_bearer = BEARER_HSPA; 00110 break; 00111 case 7: 00112 m_bearer = BEARER_LTE; 00113 break; 00114 case 1: //GSM Compact 00115 default: 00116 m_bearer = BEARER_UNKNOWN; 00117 break; 00118 } 00119 } 00120 else if( sscanf(line, "+CSQ: %d,%*d", &v) >= 1 ) 00121 { 00122 DBG("+CSQ %d", v); 00123 if(v == 99) //Unknown 00124 { 00125 m_rssi = 0; //Unknown 00126 } 00127 else 00128 { 00129 m_rssi = -113 + 2*v; 00130 } 00131 } 00132 else if ( (sscanf(line, "+CNUM: \"%[^\"]\",\"%[^\"]\",%d", n, s, &v) == 3) || 00133 (sscanf(line, "+CNUM: \"\",\"%[^\"]\",%d", s, &v) == 2) ) 00134 { 00135 if (*s && ((v == 145/*number includes + */) || (v == 129/*otherwise*/))) { 00136 strcpy(m_phoneNumber, s); 00137 } 00138 } 00139 return OK; 00140 } 00141 00142 /*virtual*/ int LinkMonitor::onNewEntryPrompt(ATCommandsInterface* pInst) 00143 { 00144 return OK; 00145 } 00146 00147 int LinkMonitor::getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BEARER* pBearer) 00148 { 00149 m_rssi = 0; 00150 m_registrationState = REGISTRATION_STATE_UNKNOWN; 00151 m_bearer = BEARER_UNKNOWN; 00152 int ret = m_pIf->execute(m_gsm ? "AT+CREG?;+COPS?;+CSQ" : "AT+CREG?;+CSQ", this, NULL, DEFAULT_TIMEOUT); //Configure to get registration info & get it; get signal quality 00153 if(ret != OK) 00154 { 00155 return NET_PROTOCOL; 00156 } 00157 *pRssi = m_rssi; 00158 *pRegistrationState = m_registrationState; 00159 *pBearer = m_bearer; 00160 return OK; 00161 } 00162 00163 int LinkMonitor::getPhoneNumber(char* phoneNumber) 00164 { 00165 *m_phoneNumber = '\0'; 00166 if (m_gsm) { 00167 int ret = m_pIf->execute("AT+CNUM", this, NULL, DEFAULT_TIMEOUT); 00168 if(ret != OK) 00169 { 00170 return NET_PROTOCOL; 00171 } 00172 } 00173 strcpy(phoneNumber, m_phoneNumber); 00174 return OK; 00175 }
Generated on Tue Jul 26 2022 09:42:59 by 1.7.2