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

/media/uploads/phsfan/sma01_003.png

Committer:
phsfan
Date:
Wed Feb 18 14:11:24 2015 +0000
Revision:
97:7d9cc95e2ea7
Child:
99:514e67a69ad6
support sms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phsfan 97:7d9cc95e2ea7 1 /* SMSInterface.cpp */
phsfan 97:7d9cc95e2ea7 2 /* Modified by 2015 phsfan
phsfan 97:7d9cc95e2ea7 3 * for ABIT SMA-01
phsfan 97:7d9cc95e2ea7 4 */
phsfan 97:7d9cc95e2ea7 5 /* Copyright (C) 2012 mbed.org, MIT License
phsfan 97:7d9cc95e2ea7 6 *
phsfan 97:7d9cc95e2ea7 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
phsfan 97:7d9cc95e2ea7 8 * and associated documentation files (the "Software"), to deal in the Software without restriction,
phsfan 97:7d9cc95e2ea7 9 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
phsfan 97:7d9cc95e2ea7 10 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
phsfan 97:7d9cc95e2ea7 11 * furnished to do so, subject to the following conditions:
phsfan 97:7d9cc95e2ea7 12 *
phsfan 97:7d9cc95e2ea7 13 * The above copyright notice and this permission notice shall be included in all copies or
phsfan 97:7d9cc95e2ea7 14 * substantial portions of the Software.
phsfan 97:7d9cc95e2ea7 15 *
phsfan 97:7d9cc95e2ea7 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
phsfan 97:7d9cc95e2ea7 17 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
phsfan 97:7d9cc95e2ea7 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
phsfan 97:7d9cc95e2ea7 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
phsfan 97:7d9cc95e2ea7 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
phsfan 97:7d9cc95e2ea7 21 */
phsfan 97:7d9cc95e2ea7 22
phsfan 97:7d9cc95e2ea7 23 #define __DEBUG__ 0
phsfan 97:7d9cc95e2ea7 24 #ifndef __MODULE__
phsfan 97:7d9cc95e2ea7 25 #define __MODULE__ "SMSInterface.cpp"
phsfan 97:7d9cc95e2ea7 26 #endif
phsfan 97:7d9cc95e2ea7 27
phsfan 97:7d9cc95e2ea7 28 #include "core/fwk.h"
phsfan 97:7d9cc95e2ea7 29
phsfan 97:7d9cc95e2ea7 30 #include "SMSInterface.h"
phsfan 97:7d9cc95e2ea7 31
phsfan 97:7d9cc95e2ea7 32 #include <cstdio>
phsfan 97:7d9cc95e2ea7 33 #include <cstring>
phsfan 97:7d9cc95e2ea7 34
phsfan 97:7d9cc95e2ea7 35 #define DEFAULT_TIMEOUT 10000
phsfan 97:7d9cc95e2ea7 36
phsfan 97:7d9cc95e2ea7 37 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
phsfan 97:7d9cc95e2ea7 38 {
phsfan 97:7d9cc95e2ea7 39 DBG("registering sms");
phsfan 97:7d9cc95e2ea7 40 m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers
phsfan 97:7d9cc95e2ea7 41 }
phsfan 97:7d9cc95e2ea7 42
phsfan 97:7d9cc95e2ea7 43 int SMSInterface::init()
phsfan 97:7d9cc95e2ea7 44 {
phsfan 97:7d9cc95e2ea7 45 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 46
phsfan 97:7d9cc95e2ea7 47 DBG("Enable sms");
phsfan 97:7d9cc95e2ea7 48 //Enable sms
phsfan 97:7d9cc95e2ea7 49 int ret = m_pIf->executeSimple("AT#P1", NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 50 if(ret != OK)
phsfan 97:7d9cc95e2ea7 51 {
phsfan 97:7d9cc95e2ea7 52 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 53 }
phsfan 97:7d9cc95e2ea7 54
phsfan 97:7d9cc95e2ea7 55 DBG("Initialization done");
phsfan 97:7d9cc95e2ea7 56 return OK;
phsfan 97:7d9cc95e2ea7 57 }
phsfan 97:7d9cc95e2ea7 58
phsfan 97:7d9cc95e2ea7 59 int SMSInterface::send(const char* number, const char* message)
phsfan 97:7d9cc95e2ea7 60 {
phsfan 97:7d9cc95e2ea7 61 if( strlen(number) != 11 )
phsfan 97:7d9cc95e2ea7 62 {
phsfan 97:7d9cc95e2ea7 63 return NET_INVALID; //Number too long to match 3GPP spec
phsfan 97:7d9cc95e2ea7 64 }
phsfan 97:7d9cc95e2ea7 65
phsfan 97:7d9cc95e2ea7 66 int ret;
phsfan 97:7d9cc95e2ea7 67
phsfan 97:7d9cc95e2ea7 68 DBG("Send SM");
phsfan 97:7d9cc95e2ea7 69 //Send command
phsfan 97:7d9cc95e2ea7 70 char cmd[300];
phsfan 97:7d9cc95e2ea7 71 // set S register
phsfan 97:7d9cc95e2ea7 72 strcpy(cmd, "ATS202=128145000013");
phsfan 97:7d9cc95e2ea7 73 for (int i = 0; i < strlen(message); i ++) {
phsfan 97:7d9cc95e2ea7 74 std::sprintf(&cmd[strlen(cmd)], "%03d", (unsigned char)message[i]);
phsfan 97:7d9cc95e2ea7 75 }
phsfan 97:7d9cc95e2ea7 76 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 77
phsfan 97:7d9cc95e2ea7 78 if( ret != OK )
phsfan 97:7d9cc95e2ea7 79 {
phsfan 97:7d9cc95e2ea7 80 WARN("ret %d, state %d", ret, m_state);
phsfan 97:7d9cc95e2ea7 81 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 82 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 83 }
phsfan 97:7d9cc95e2ea7 84
phsfan 97:7d9cc95e2ea7 85 m_state = SMS_SEND_CMD_SENT;
phsfan 97:7d9cc95e2ea7 86 // send light mail
phsfan 97:7d9cc95e2ea7 87 std::sprintf(cmd, "ATDI%s##0", number);
phsfan 97:7d9cc95e2ea7 88 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 89 Thread::wait(500);
phsfan 97:7d9cc95e2ea7 90
phsfan 97:7d9cc95e2ea7 91 if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) )
phsfan 97:7d9cc95e2ea7 92 {
phsfan 97:7d9cc95e2ea7 93 WARN("ret %d, state %d", ret, m_state);
phsfan 97:7d9cc95e2ea7 94 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 95 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 96 }
phsfan 97:7d9cc95e2ea7 97
phsfan 97:7d9cc95e2ea7 98 DBG("SM sent");
phsfan 97:7d9cc95e2ea7 99 // since unsolicited events are blocked during send SM events,it makes sense to update the mailbox
phsfan 97:7d9cc95e2ea7 100 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 101 return OK;
phsfan 97:7d9cc95e2ea7 102 }
phsfan 97:7d9cc95e2ea7 103
phsfan 97:7d9cc95e2ea7 104
phsfan 97:7d9cc95e2ea7 105 int SMSInterface::get(char* number, char* message, size_t maxLength)
phsfan 97:7d9cc95e2ea7 106 {
phsfan 97:7d9cc95e2ea7 107 if( maxLength < 1 )
phsfan 97:7d9cc95e2ea7 108 {
phsfan 97:7d9cc95e2ea7 109 return NET_INVALID; //Buffer too short
phsfan 97:7d9cc95e2ea7 110 }
phsfan 97:7d9cc95e2ea7 111
phsfan 97:7d9cc95e2ea7 112 int ret;
phsfan 97:7d9cc95e2ea7 113
phsfan 97:7d9cc95e2ea7 114 DBG("Get next message");
phsfan 97:7d9cc95e2ea7 115
phsfan 97:7d9cc95e2ea7 116 //Prepare infos
phsfan 97:7d9cc95e2ea7 117 m_state = SMS_GET_CMD_SENT;
phsfan 97:7d9cc95e2ea7 118 m_msisdn = (char*) number;
phsfan 97:7d9cc95e2ea7 119 m_msg = (char*) message;
phsfan 97:7d9cc95e2ea7 120 m_maxMsgLength = maxLength;
phsfan 97:7d9cc95e2ea7 121
phsfan 97:7d9cc95e2ea7 122 DBG("Get SMS");
phsfan 97:7d9cc95e2ea7 123 //List command
phsfan 97:7d9cc95e2ea7 124 char cmd[32] = "ATS211?";
phsfan 97:7d9cc95e2ea7 125 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 126 if( ret != OK )
phsfan 97:7d9cc95e2ea7 127 {
phsfan 97:7d9cc95e2ea7 128 WARN("ATS211 returned %d", ret);
phsfan 97:7d9cc95e2ea7 129 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 130 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 131 }
phsfan 97:7d9cc95e2ea7 132
phsfan 97:7d9cc95e2ea7 133 if (m_state != SMS_CMD_PROCESSED)
phsfan 97:7d9cc95e2ea7 134 {
phsfan 97:7d9cc95e2ea7 135 WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'");
phsfan 97:7d9cc95e2ea7 136 }
phsfan 97:7d9cc95e2ea7 137
phsfan 97:7d9cc95e2ea7 138 m_msisdn[0] = 0;
phsfan 97:7d9cc95e2ea7 139 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 140
phsfan 97:7d9cc95e2ea7 141 return OK;
phsfan 97:7d9cc95e2ea7 142 }
phsfan 97:7d9cc95e2ea7 143
phsfan 97:7d9cc95e2ea7 144
phsfan 97:7d9cc95e2ea7 145 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
phsfan 97:7d9cc95e2ea7 146 {
phsfan 97:7d9cc95e2ea7 147 if(m_state == SMS_SEND_CMD_SENT)
phsfan 97:7d9cc95e2ea7 148 {
phsfan 97:7d9cc95e2ea7 149 if( strncmp(line, "ALERT", 5) == 0 ) {
phsfan 97:7d9cc95e2ea7 150 DBG("SM sent");
phsfan 97:7d9cc95e2ea7 151 m_state = SMS_CMD_PROCESSED;
phsfan 97:7d9cc95e2ea7 152 } else
phsfan 97:7d9cc95e2ea7 153 if( strncmp(line, "BUSY", 5) == 0 ) {
phsfan 97:7d9cc95e2ea7 154 DBG("SM sent");
phsfan 97:7d9cc95e2ea7 155 m_state = SMS_CMD_BUSY;
phsfan 97:7d9cc95e2ea7 156 }
phsfan 97:7d9cc95e2ea7 157 }
phsfan 97:7d9cc95e2ea7 158 else if(m_state == SMS_GET_CMD_SENT)
phsfan 97:7d9cc95e2ea7 159 {
phsfan 97:7d9cc95e2ea7 160 DBG("Header: %s", line);
phsfan 97:7d9cc95e2ea7 161 if( strncmp(line, "128145000013", 12) == 0 ) {
phsfan 97:7d9cc95e2ea7 162 int j = 0, c = 0, len = 0;
phsfan 97:7d9cc95e2ea7 163 for (int i = 12; i < strlen(line); i ++) {
phsfan 97:7d9cc95e2ea7 164 c = (c * 10) + (line[i] - '0');
phsfan 97:7d9cc95e2ea7 165 j ++;
phsfan 97:7d9cc95e2ea7 166 if (j >=3) {
phsfan 97:7d9cc95e2ea7 167 m_msg[len] = c;
phsfan 97:7d9cc95e2ea7 168 len ++;
phsfan 97:7d9cc95e2ea7 169 if (len >= m_maxMsgLength - 1) break;
phsfan 97:7d9cc95e2ea7 170 j = 0;
phsfan 97:7d9cc95e2ea7 171 c = 0;
phsfan 97:7d9cc95e2ea7 172 }
phsfan 97:7d9cc95e2ea7 173 }
phsfan 97:7d9cc95e2ea7 174 m_msg[len] = 0;
phsfan 97:7d9cc95e2ea7 175 m_state = SMS_CMD_PROCESSED;
phsfan 97:7d9cc95e2ea7 176 }
phsfan 97:7d9cc95e2ea7 177 }
phsfan 97:7d9cc95e2ea7 178 return OK;
phsfan 97:7d9cc95e2ea7 179 }
phsfan 97:7d9cc95e2ea7 180
phsfan 97:7d9cc95e2ea7 181 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
phsfan 97:7d9cc95e2ea7 182 {
phsfan 97:7d9cc95e2ea7 183 if(m_state == SMS_SEND_CMD_SENT)
phsfan 97:7d9cc95e2ea7 184 {
phsfan 97:7d9cc95e2ea7 185 char* crPtr = strchr(m_msg, CR);
phsfan 97:7d9cc95e2ea7 186 if(crPtr != NULL)
phsfan 97:7d9cc95e2ea7 187 {
phsfan 97:7d9cc95e2ea7 188 int crPos = crPtr - m_msg;
phsfan 97:7d9cc95e2ea7 189 //Replace m_inputBuf[crPos] with null-terminating char
phsfan 97:7d9cc95e2ea7 190 m_msg[crPos] = '\0';
phsfan 97:7d9cc95e2ea7 191
phsfan 97:7d9cc95e2ea7 192 //If there is a CR char, split message there
phsfan 97:7d9cc95e2ea7 193
phsfan 97:7d9cc95e2ea7 194 //Do print the message
phsfan 97:7d9cc95e2ea7 195 int ret = pInst->sendData(m_msg);
phsfan 97:7d9cc95e2ea7 196 if(ret)
phsfan 97:7d9cc95e2ea7 197 {
phsfan 97:7d9cc95e2ea7 198 return ret;
phsfan 97:7d9cc95e2ea7 199 }
phsfan 97:7d9cc95e2ea7 200
phsfan 97:7d9cc95e2ea7 201 char cr[2] = {CR, '\0'};
phsfan 97:7d9cc95e2ea7 202 ret = pInst->sendData(cr);
phsfan 97:7d9cc95e2ea7 203 if(ret)
phsfan 97:7d9cc95e2ea7 204 {
phsfan 97:7d9cc95e2ea7 205 return ret;
phsfan 97:7d9cc95e2ea7 206 }
phsfan 97:7d9cc95e2ea7 207
phsfan 97:7d9cc95e2ea7 208 m_msg += crPos;
phsfan 97:7d9cc95e2ea7 209
phsfan 97:7d9cc95e2ea7 210 if(m_msg[0] == LF)
phsfan 97:7d9cc95e2ea7 211 {
phsfan 97:7d9cc95e2ea7 212 m_msg++; //Discard LF char as well
phsfan 97:7d9cc95e2ea7 213 }
phsfan 97:7d9cc95e2ea7 214
phsfan 97:7d9cc95e2ea7 215 return NET_MOREINFO;
phsfan 97:7d9cc95e2ea7 216 }
phsfan 97:7d9cc95e2ea7 217 else
phsfan 97:7d9cc95e2ea7 218 {
phsfan 97:7d9cc95e2ea7 219 //Do print the message
phsfan 97:7d9cc95e2ea7 220 pInst->sendData(m_msg);
phsfan 97:7d9cc95e2ea7 221 return OK;
phsfan 97:7d9cc95e2ea7 222 }
phsfan 97:7d9cc95e2ea7 223 }
phsfan 97:7d9cc95e2ea7 224
phsfan 97:7d9cc95e2ea7 225 return OK;
phsfan 97:7d9cc95e2ea7 226 }
phsfan 97:7d9cc95e2ea7 227
phsfan 97:7d9cc95e2ea7 228 /*virtual*/ bool SMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled
phsfan 97:7d9cc95e2ea7 229 {
phsfan 97:7d9cc95e2ea7 230 return false;
phsfan 97:7d9cc95e2ea7 231 }
phsfan 97:7d9cc95e2ea7 232
phsfan 97:7d9cc95e2ea7 233 /*virtual*/ void SMSInterface::onDispatchStart()
phsfan 97:7d9cc95e2ea7 234 {
phsfan 97:7d9cc95e2ea7 235
phsfan 97:7d9cc95e2ea7 236 }
phsfan 97:7d9cc95e2ea7 237
phsfan 97:7d9cc95e2ea7 238 /*virtual*/ void SMSInterface::onDispatchStop()
phsfan 97:7d9cc95e2ea7 239 {
phsfan 97:7d9cc95e2ea7 240
phsfan 97:7d9cc95e2ea7 241 }
phsfan 97:7d9cc95e2ea7 242
phsfan 97:7d9cc95e2ea7 243 /*virtual*/ char* SMSInterface::getEventsEnableCommand()
phsfan 97:7d9cc95e2ea7 244 {
phsfan 97:7d9cc95e2ea7 245 return NULL;
phsfan 97:7d9cc95e2ea7 246 }
phsfan 97:7d9cc95e2ea7 247
phsfan 97:7d9cc95e2ea7 248 /*virtual*/ char* SMSInterface::getEventsDisableCommand()
phsfan 97:7d9cc95e2ea7 249 {
phsfan 97:7d9cc95e2ea7 250 return NULL;
phsfan 97:7d9cc95e2ea7 251 }
phsfan 97:7d9cc95e2ea7 252
phsfan 97:7d9cc95e2ea7 253 /*virtual*/ void SMSInterface::onEvent(const char* atCode, const char* evt)
phsfan 97:7d9cc95e2ea7 254 {
phsfan 97:7d9cc95e2ea7 255 }