PHS module SMA-01 library. see: https://developer.mbed.org/users/phsfan/notebook/abitusbmodem/

Dependencies:   Socket lwip-sys lwip

Dependents:   AbitUSBModem_HTTPTest AbitUSBModem_MQTTTest AbitUSBModem_WebsocketTest AbitUSBModem_SMSTest

Fork of VodafoneUSBModem by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SMSInterface.cpp Source File

SMSInterface.cpp

00001 /* SMSInterface.cpp */
00002 /* Modified by 2015 phsfan
00003  *  for ABIT SMA-01
00004  */
00005 /* Copyright (C) 2012 mbed.org, MIT License
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00008  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00009  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00010  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be included in all copies or
00014  * substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00017  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00018  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #define __DEBUG__ 0
00024 #ifndef __MODULE__
00025 #define __MODULE__ "SMSInterface.cpp"
00026 #endif
00027 
00028 #include "core/fwk.h"
00029 
00030 #include "SMSInterface.h"
00031 
00032 #include <cstdio>
00033 #include <cstring>
00034 
00035 #define DEFAULT_TIMEOUT 10000
00036 #define SHORT_MAIL_CODE "128145000013"
00037 
00038 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
00039 {
00040   DBG("registering sms");
00041   m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers
00042   m_caller[0] = 0;
00043 }
00044 
00045 int SMSInterface::init()
00046 {
00047   m_state = SMS_IDLE;
00048 
00049   DBG("Enable sms");
00050   //Enable sms
00051   int ret = m_pIf->executeSimple("AT#P1", NULL, DEFAULT_TIMEOUT);
00052   if(ret != OK)
00053   {
00054     return NET_PROTOCOL;
00055   }
00056   //Enable caller id
00057   ret = m_pIf->executeSimple("AT#B1", NULL, DEFAULT_TIMEOUT);
00058   if(ret != OK)
00059   {
00060     return NET_PROTOCOL;
00061   }
00062 
00063   DBG("Initialization done");
00064   return OK;
00065 }
00066 
00067 int SMSInterface::send(const char* number, const char* message)
00068 {
00069   if( strlen(number) != 11 )
00070   {
00071     return NET_INVALID; //Number too long to match 3GPP spec
00072   }
00073 
00074   int ret;
00075 
00076   DBG("Send SM");
00077   //Send command
00078   char cmd[300];
00079   // set S register
00080   strcpy(cmd, "ATS202=" SHORT_MAIL_CODE);
00081   for (int i = 0; i < strlen(message); i ++) {
00082     std::sprintf(&cmd[strlen(cmd)], "%03d", (unsigned char)message[i]);
00083   }
00084   ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
00085 
00086   if( ret != OK )
00087   {
00088     WARN("ret %d, state %d", ret, m_state);
00089     m_state = SMS_IDLE;
00090     return NET_PROTOCOL;
00091   }
00092 
00093   m_state = SMS_SEND_CMD_SENT;
00094   // send light mail
00095   std::sprintf(cmd, "ATDI%s##0", number);
00096   ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
00097   Thread::wait(500);
00098 
00099   if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) )
00100   {
00101     WARN("ret %d, state %d", ret, m_state);
00102     m_state = SMS_IDLE;
00103     return NET_PROTOCOL;
00104   }
00105 
00106   DBG("SM sent");
00107   // since unsolicited events are blocked during send SM events,it makes sense to update the mailbox
00108   m_state = SMS_IDLE;
00109   return OK;
00110 }
00111 
00112 
00113 int SMSInterface::get(char* number, char* message, size_t maxLength)
00114 {
00115   if( maxLength < 1  )
00116   {
00117     return NET_INVALID; //Buffer too short
00118   }
00119   if (m_caller[0] == 0) {
00120     return NET_INVALID; //No sms
00121   }
00122 
00123   int ret;
00124 
00125   DBG("Get next message");
00126 
00127   //Prepare infos
00128   m_state = SMS_GET_CMD_SENT;
00129   m_msisdn = (char*) number;
00130   m_msg = (char*) message;
00131   m_maxMsgLength = maxLength;
00132 
00133   DBG("Get SMS");
00134   //Show register
00135   char cmd[32] = "ATS211?";
00136   ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
00137   if( ret != OK )
00138   {
00139     WARN("ATS211 returned %d", ret);
00140     m_state = SMS_IDLE;
00141     return NET_PROTOCOL;
00142   }
00143 
00144   if (m_state != SMS_CMD_PROCESSED)
00145   {
00146     WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'");
00147   }
00148 
00149   strcpy(m_msisdn, m_caller);
00150   m_caller[0] = 0;
00151   m_state = SMS_IDLE;
00152 
00153   return OK;
00154 }
00155 
00156 
00157 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
00158 {
00159   if(m_state == SMS_SEND_CMD_SENT)
00160   {
00161     if( strncmp(line, "ALERT", 5) == 0 ) {
00162       DBG("SM send ALERT");
00163       m_state = SMS_CMD_PROCESSED;
00164     } else
00165     if( strncmp(line, "BUSY", 5) == 0 ) {
00166       DBG("SM send BUSY");
00167       m_state = SMS_CMD_BUSY;
00168     } else
00169     if( strncmp(line, "NO CARRIER", 10) == 0 ) {
00170       DBG("SM send NO CARRIER");
00171       m_state = SMS_IDLE;
00172     }
00173   }
00174   else if(m_state == SMS_GET_CMD_SENT)
00175   {
00176     DBG("SM recv: %s", line);
00177     if( strncmp(line, SHORT_MAIL_CODE, 12) == 0 ) { // light mail code
00178       int j = 0, c = 0, len = 0;
00179       for (int i = 12; i < strlen(line); i ++) {
00180         c = (c * 10) + (line[i] - '0');
00181         j ++;
00182         if (j >=3) {
00183           m_msg[len] = c;
00184           len ++;
00185           if (len >= m_maxMsgLength - 1) break;
00186           j = 0;
00187           c = 0;
00188         }
00189       }
00190       m_msg[len] = 0;
00191       DBG("message '%s'", m_msg);
00192       m_state = SMS_CMD_PROCESSED;
00193     }
00194   }
00195   return OK;
00196 }
00197 
00198 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
00199 {
00200   if(m_state == SMS_SEND_CMD_SENT)
00201   {
00202     char* crPtr = strchr(m_msg, CR);
00203     if(crPtr != NULL)
00204     {
00205       int crPos = crPtr - m_msg;
00206       //Replace m_inputBuf[crPos] with null-terminating char
00207       m_msg[crPos] = '\0';
00208 
00209       //If there is a CR char, split message there
00210 
00211       //Do print the message
00212       int ret = pInst->sendData(m_msg);
00213       if(ret)
00214       {
00215         return ret;
00216       }
00217 
00218       char cr[2] = {CR, '\0'};
00219       ret = pInst->sendData(cr);
00220       if(ret)
00221       {
00222         return ret;
00223       }
00224 
00225       m_msg += crPos;
00226 
00227       if(m_msg[0] == LF)
00228       {
00229         m_msg++; //Discard LF char as well
00230       }
00231 
00232       return NET_MOREINFO;
00233     }
00234     else
00235     {
00236       //Do print the message
00237       pInst->sendData(m_msg);
00238       return OK;
00239     }
00240   }
00241 
00242   return OK;
00243 }
00244 
00245 /*virtual*/ bool SMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled
00246 {
00247     if(m_state == SMS_IDLE) {
00248         if( strncmp(atCode, "RING", 4) == 0 ) {
00249             m_caller[0] = 0;
00250             DBG("RING");
00251             m_state = SMS_RING;
00252         }
00253         return true;
00254     } else
00255     if(m_state == SMS_RING) {
00256         if( strncmp(atCode, "ID=", 3) == 0 ) {
00257             strncpy(m_caller, &atCode[3], sizeof(m_caller));
00258             m_caller[11] = 0;
00259             DBG("ID %s", m_caller);
00260         } else
00261         if( strncmp(atCode, "NO CARRIER", 10) == 0 ) {
00262             DBG("NO CARRIER");
00263             m_state = SMS_IDLE;
00264         }
00265         return true;
00266     }
00267     return false;
00268 }
00269 
00270 /*virtual*/ void SMSInterface::onDispatchStart()
00271 {
00272     
00273 }
00274 
00275 /*virtual*/ void SMSInterface::onDispatchStop()
00276 {
00277     
00278 }
00279 
00280 /*virtual*/ char* SMSInterface::getEventsEnableCommand()
00281 {
00282     return NULL;
00283 }
00284 
00285 /*virtual*/ char* SMSInterface::getEventsDisableCommand()
00286 {
00287     return NULL;
00288 }
00289 
00290 /*virtual*/ void SMSInterface::onEvent(const char* atCode, const char* evt)
00291 {
00292 }