local fork
Dependencies: Socket USBHostWANDongle_bleedingedge lwip-sys lwip
Fork of VodafoneUSBModem_bleedingedge by
USSDInterface.cpp
00001 /* USSDInterface.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__ "USSDInterface.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include "USSDInterface.h" 00028 00029 #include <cstdio> 00030 00031 #define DEFAULT_TIMEOUT 10000 00032 #define USSD_TIMEOUT 15000 00033 00034 USSDInterface::USSDInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_responseMtx(), m_responseSphre(1), m_result(NULL), m_maxResultLength(0) 00035 { 00036 m_responseSphre.wait(0); //Take ownership of the semaphore 00037 DBG("events handler reg ussd"); 00038 m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers 00039 } 00040 00041 int USSDInterface::init() 00042 { 00043 DBG("Initialization done"); 00044 return OK; 00045 } 00046 00047 int USSDInterface::send(const char* command, char* result, size_t maxLength) 00048 { 00049 if (strlen(command) > 20) //Prevent buffer overflow XXX shouldn't this be 19 as the AT+CUSD=1,"" is 12 00050 { 00051 return NET_TOOSMALL; 00052 } 00053 00054 m_responseMtx.lock(); 00055 m_result = result; 00056 m_maxResultLength = maxLength; 00057 m_responseMtx.unlock(); 00058 00059 m_responseSphre.wait(0); //Make sure there is not a pending result that needs to be discarded 00060 00061 DBG("Send USSD command & register for unsolicited result codes"); 00062 //Send USSD command to the network 00063 char cmd[32]; 00064 std::sprintf(cmd, "AT+CUSD=1,\"%s\"", command); 00065 int ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); 00066 if( ret != OK ) 00067 { 00068 return NET_PROTOCOL; 00069 } 00070 00071 //Did we already get a response (3GPP rev < 6) ? 00072 00073 //Now wait for response 00074 int res = m_responseSphre.wait(USSD_TIMEOUT); 00075 00076 //Reset data 00077 m_responseMtx.lock(); 00078 m_result = NULL; 00079 m_maxResultLength = 0; 00080 m_responseMtx.unlock(); 00081 00082 if(res <= 0) 00083 { 00084 DBG("No result received"); 00085 ret = m_pIf->executeSimple("AT+CUSD=2", NULL, DEFAULT_TIMEOUT); //Cancel command 00086 if( ret != OK ) 00087 { 00088 return NET_PROTOCOL; 00089 } 00090 return NET_TIMEOUT; 00091 } 00092 00093 DBG("Result received: %s", result); 00094 00095 return OK; 00096 } 00097 00098 /*virtual*/ int USSDInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00099 { 00100 const char* pSemicol = strchr(line, ':'); 00101 if( ( (pSemicol - line) != strlen("+CUSD") ) || ( memcmp(line, "+CUSD", strlen("+CUSD")) != 0) ) 00102 { 00103 WARN("Unknown code"); 00104 return OK; 00105 } 00106 00107 const char* pData = NULL; 00108 if( pSemicol != NULL ) //Split the identifier & the result code (if it exists) 00109 { 00110 pData = pSemicol + 1; 00111 if(pData[0]==' ') 00112 { 00113 pData++; //Suppress whitespace 00114 } 00115 processResult(pData); 00116 } 00117 return OK; 00118 } 00119 00120 /*virtual*/ int USSDInterface::onNewEntryPrompt(ATCommandsInterface* pInst) 00121 { 00122 return OK; 00123 } 00124 00125 /*virtual*/ bool USSDInterface::isATCodeHandled(const char* atCode) //Is this AT code handled 00126 { 00127 DBG("AT code is %s", atCode); 00128 if( strcmp("+CUSD", atCode) == 0 ) 00129 { 00130 return true; 00131 } 00132 00133 DBG("Not handled"); 00134 return false; 00135 } 00136 00137 /*virtual*/ void USSDInterface::onDispatchStart() 00138 { 00139 00140 00141 } 00142 00143 /*virtual*/ void USSDInterface::onDispatchStop() 00144 { 00145 00146 } 00147 00148 /*virtual*/ char* USSDInterface::getEventsEnableCommand() 00149 { 00150 return NULL; //No need to disable events here 00151 } 00152 00153 /*virtual*/ char* USSDInterface::getEventsDisableCommand() 00154 { 00155 return NULL; //No need to re-enable events here 00156 } 00157 00158 /*virtual*/ void USSDInterface::onEvent(const char* atCode, const char* evt) 00159 { 00160 if( strcmp("+CUSD", atCode) != 0 ) 00161 { 00162 WARN("Wrong AT Code"); 00163 return; //Not supported 00164 } 00165 00166 processResult(evt); 00167 } 00168 00169 void USSDInterface::processResult(const char* data) 00170 { 00171 char* pStart = (char*) strchr(data,'\"'); 00172 if(pStart==NULL) 00173 { 00174 WARN("Could not find opening quote"); 00175 return; //Invalid/incomplete response 00176 } 00177 pStart++; //Point to first char of response 00178 char* pEnd = (char*) strchr(pStart,'\"'); 00179 if(pEnd==NULL) 00180 { 00181 WARN("Could not find closing quote"); 00182 return; //Invalid/incomplete response 00183 } 00184 m_responseMtx.lock(); 00185 if(m_maxResultLength == 0) //No pending command 00186 { 00187 WARN("No pending command"); 00188 m_responseMtx.unlock(); 00189 return; 00190 } 00191 size_t cpyLen = MIN( pEnd - pStart, m_maxResultLength - 1 ); 00192 DBG("cpyLen: %d",cpyLen); 00193 memcpy((void*)m_result, pStart, cpyLen); 00194 m_result[cpyLen] = '\0'; 00195 DBG("Got USSD response: %s", m_result); 00196 m_responseMtx.unlock(); 00197 m_responseSphre.release(); //Signal user thread that response is ready 00198 }
Generated on Tue Jul 12 2022 21:41:40 by 1.7.2