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