local fork

Dependencies:   Socket USBHostWANDongle_bleedingedge lwip-sys lwip

Dependents:   Encrypted

Fork of VodafoneUSBModem_bleedingedge by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USSDInterface.cpp Source File

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 }