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 25 14:34:13 2015 +0000
Revision:
99:514e67a69ad6
Parent:
97:7d9cc95e2ea7
supported 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 99:514e67a69ad6 36 #define SHORT_MAIL_CODE "128145000013"
phsfan 97:7d9cc95e2ea7 37
phsfan 97:7d9cc95e2ea7 38 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
phsfan 97:7d9cc95e2ea7 39 {
phsfan 97:7d9cc95e2ea7 40 DBG("registering sms");
phsfan 97:7d9cc95e2ea7 41 m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers
phsfan 99:514e67a69ad6 42 m_caller[0] = 0;
phsfan 97:7d9cc95e2ea7 43 }
phsfan 97:7d9cc95e2ea7 44
phsfan 97:7d9cc95e2ea7 45 int SMSInterface::init()
phsfan 97:7d9cc95e2ea7 46 {
phsfan 97:7d9cc95e2ea7 47 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 48
phsfan 97:7d9cc95e2ea7 49 DBG("Enable sms");
phsfan 97:7d9cc95e2ea7 50 //Enable sms
phsfan 97:7d9cc95e2ea7 51 int ret = m_pIf->executeSimple("AT#P1", NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 52 if(ret != OK)
phsfan 97:7d9cc95e2ea7 53 {
phsfan 97:7d9cc95e2ea7 54 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 55 }
phsfan 99:514e67a69ad6 56 //Enable caller id
phsfan 99:514e67a69ad6 57 ret = m_pIf->executeSimple("AT#B1", NULL, DEFAULT_TIMEOUT);
phsfan 99:514e67a69ad6 58 if(ret != OK)
phsfan 99:514e67a69ad6 59 {
phsfan 99:514e67a69ad6 60 return NET_PROTOCOL;
phsfan 99:514e67a69ad6 61 }
phsfan 97:7d9cc95e2ea7 62
phsfan 97:7d9cc95e2ea7 63 DBG("Initialization done");
phsfan 97:7d9cc95e2ea7 64 return OK;
phsfan 97:7d9cc95e2ea7 65 }
phsfan 97:7d9cc95e2ea7 66
phsfan 97:7d9cc95e2ea7 67 int SMSInterface::send(const char* number, const char* message)
phsfan 97:7d9cc95e2ea7 68 {
phsfan 97:7d9cc95e2ea7 69 if( strlen(number) != 11 )
phsfan 97:7d9cc95e2ea7 70 {
phsfan 97:7d9cc95e2ea7 71 return NET_INVALID; //Number too long to match 3GPP spec
phsfan 97:7d9cc95e2ea7 72 }
phsfan 97:7d9cc95e2ea7 73
phsfan 97:7d9cc95e2ea7 74 int ret;
phsfan 97:7d9cc95e2ea7 75
phsfan 97:7d9cc95e2ea7 76 DBG("Send SM");
phsfan 97:7d9cc95e2ea7 77 //Send command
phsfan 97:7d9cc95e2ea7 78 char cmd[300];
phsfan 97:7d9cc95e2ea7 79 // set S register
phsfan 99:514e67a69ad6 80 strcpy(cmd, "ATS202=" SHORT_MAIL_CODE);
phsfan 97:7d9cc95e2ea7 81 for (int i = 0; i < strlen(message); i ++) {
phsfan 97:7d9cc95e2ea7 82 std::sprintf(&cmd[strlen(cmd)], "%03d", (unsigned char)message[i]);
phsfan 97:7d9cc95e2ea7 83 }
phsfan 97:7d9cc95e2ea7 84 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 85
phsfan 97:7d9cc95e2ea7 86 if( ret != OK )
phsfan 97:7d9cc95e2ea7 87 {
phsfan 97:7d9cc95e2ea7 88 WARN("ret %d, state %d", ret, m_state);
phsfan 97:7d9cc95e2ea7 89 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 90 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 91 }
phsfan 97:7d9cc95e2ea7 92
phsfan 97:7d9cc95e2ea7 93 m_state = SMS_SEND_CMD_SENT;
phsfan 97:7d9cc95e2ea7 94 // send light mail
phsfan 97:7d9cc95e2ea7 95 std::sprintf(cmd, "ATDI%s##0", number);
phsfan 97:7d9cc95e2ea7 96 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 97 Thread::wait(500);
phsfan 97:7d9cc95e2ea7 98
phsfan 97:7d9cc95e2ea7 99 if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) )
phsfan 97:7d9cc95e2ea7 100 {
phsfan 97:7d9cc95e2ea7 101 WARN("ret %d, state %d", ret, m_state);
phsfan 97:7d9cc95e2ea7 102 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 103 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 104 }
phsfan 97:7d9cc95e2ea7 105
phsfan 97:7d9cc95e2ea7 106 DBG("SM sent");
phsfan 97:7d9cc95e2ea7 107 // since unsolicited events are blocked during send SM events,it makes sense to update the mailbox
phsfan 97:7d9cc95e2ea7 108 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 109 return OK;
phsfan 97:7d9cc95e2ea7 110 }
phsfan 97:7d9cc95e2ea7 111
phsfan 97:7d9cc95e2ea7 112
phsfan 97:7d9cc95e2ea7 113 int SMSInterface::get(char* number, char* message, size_t maxLength)
phsfan 97:7d9cc95e2ea7 114 {
phsfan 97:7d9cc95e2ea7 115 if( maxLength < 1 )
phsfan 97:7d9cc95e2ea7 116 {
phsfan 97:7d9cc95e2ea7 117 return NET_INVALID; //Buffer too short
phsfan 97:7d9cc95e2ea7 118 }
phsfan 99:514e67a69ad6 119 if (m_caller[0] == 0) {
phsfan 99:514e67a69ad6 120 return NET_INVALID; //No sms
phsfan 99:514e67a69ad6 121 }
phsfan 97:7d9cc95e2ea7 122
phsfan 97:7d9cc95e2ea7 123 int ret;
phsfan 97:7d9cc95e2ea7 124
phsfan 97:7d9cc95e2ea7 125 DBG("Get next message");
phsfan 97:7d9cc95e2ea7 126
phsfan 97:7d9cc95e2ea7 127 //Prepare infos
phsfan 97:7d9cc95e2ea7 128 m_state = SMS_GET_CMD_SENT;
phsfan 97:7d9cc95e2ea7 129 m_msisdn = (char*) number;
phsfan 97:7d9cc95e2ea7 130 m_msg = (char*) message;
phsfan 97:7d9cc95e2ea7 131 m_maxMsgLength = maxLength;
phsfan 97:7d9cc95e2ea7 132
phsfan 97:7d9cc95e2ea7 133 DBG("Get SMS");
phsfan 99:514e67a69ad6 134 //Show register
phsfan 97:7d9cc95e2ea7 135 char cmd[32] = "ATS211?";
phsfan 97:7d9cc95e2ea7 136 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
phsfan 97:7d9cc95e2ea7 137 if( ret != OK )
phsfan 97:7d9cc95e2ea7 138 {
phsfan 97:7d9cc95e2ea7 139 WARN("ATS211 returned %d", ret);
phsfan 97:7d9cc95e2ea7 140 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 141 return NET_PROTOCOL;
phsfan 97:7d9cc95e2ea7 142 }
phsfan 97:7d9cc95e2ea7 143
phsfan 97:7d9cc95e2ea7 144 if (m_state != SMS_CMD_PROCESSED)
phsfan 97:7d9cc95e2ea7 145 {
phsfan 97:7d9cc95e2ea7 146 WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'");
phsfan 97:7d9cc95e2ea7 147 }
phsfan 97:7d9cc95e2ea7 148
phsfan 99:514e67a69ad6 149 strcpy(m_msisdn, m_caller);
phsfan 99:514e67a69ad6 150 m_caller[0] = 0;
phsfan 97:7d9cc95e2ea7 151 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 152
phsfan 97:7d9cc95e2ea7 153 return OK;
phsfan 97:7d9cc95e2ea7 154 }
phsfan 97:7d9cc95e2ea7 155
phsfan 97:7d9cc95e2ea7 156
phsfan 97:7d9cc95e2ea7 157 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
phsfan 97:7d9cc95e2ea7 158 {
phsfan 97:7d9cc95e2ea7 159 if(m_state == SMS_SEND_CMD_SENT)
phsfan 97:7d9cc95e2ea7 160 {
phsfan 97:7d9cc95e2ea7 161 if( strncmp(line, "ALERT", 5) == 0 ) {
phsfan 99:514e67a69ad6 162 DBG("SM send ALERT");
phsfan 97:7d9cc95e2ea7 163 m_state = SMS_CMD_PROCESSED;
phsfan 97:7d9cc95e2ea7 164 } else
phsfan 97:7d9cc95e2ea7 165 if( strncmp(line, "BUSY", 5) == 0 ) {
phsfan 99:514e67a69ad6 166 DBG("SM send BUSY");
phsfan 97:7d9cc95e2ea7 167 m_state = SMS_CMD_BUSY;
phsfan 99:514e67a69ad6 168 } else
phsfan 99:514e67a69ad6 169 if( strncmp(line, "NO CARRIER", 10) == 0 ) {
phsfan 99:514e67a69ad6 170 DBG("SM send NO CARRIER");
phsfan 99:514e67a69ad6 171 m_state = SMS_IDLE;
phsfan 97:7d9cc95e2ea7 172 }
phsfan 97:7d9cc95e2ea7 173 }
phsfan 97:7d9cc95e2ea7 174 else if(m_state == SMS_GET_CMD_SENT)
phsfan 97:7d9cc95e2ea7 175 {
phsfan 99:514e67a69ad6 176 DBG("SM recv: %s", line);
phsfan 99:514e67a69ad6 177 if( strncmp(line, SHORT_MAIL_CODE, 12) == 0 ) { // light mail code
phsfan 97:7d9cc95e2ea7 178 int j = 0, c = 0, len = 0;
phsfan 97:7d9cc95e2ea7 179 for (int i = 12; i < strlen(line); i ++) {
phsfan 97:7d9cc95e2ea7 180 c = (c * 10) + (line[i] - '0');
phsfan 97:7d9cc95e2ea7 181 j ++;
phsfan 97:7d9cc95e2ea7 182 if (j >=3) {
phsfan 97:7d9cc95e2ea7 183 m_msg[len] = c;
phsfan 97:7d9cc95e2ea7 184 len ++;
phsfan 97:7d9cc95e2ea7 185 if (len >= m_maxMsgLength - 1) break;
phsfan 97:7d9cc95e2ea7 186 j = 0;
phsfan 97:7d9cc95e2ea7 187 c = 0;
phsfan 97:7d9cc95e2ea7 188 }
phsfan 97:7d9cc95e2ea7 189 }
phsfan 97:7d9cc95e2ea7 190 m_msg[len] = 0;
phsfan 99:514e67a69ad6 191 DBG("message '%s'", m_msg);
phsfan 97:7d9cc95e2ea7 192 m_state = SMS_CMD_PROCESSED;
phsfan 97:7d9cc95e2ea7 193 }
phsfan 97:7d9cc95e2ea7 194 }
phsfan 97:7d9cc95e2ea7 195 return OK;
phsfan 97:7d9cc95e2ea7 196 }
phsfan 97:7d9cc95e2ea7 197
phsfan 97:7d9cc95e2ea7 198 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
phsfan 97:7d9cc95e2ea7 199 {
phsfan 97:7d9cc95e2ea7 200 if(m_state == SMS_SEND_CMD_SENT)
phsfan 97:7d9cc95e2ea7 201 {
phsfan 97:7d9cc95e2ea7 202 char* crPtr = strchr(m_msg, CR);
phsfan 97:7d9cc95e2ea7 203 if(crPtr != NULL)
phsfan 97:7d9cc95e2ea7 204 {
phsfan 97:7d9cc95e2ea7 205 int crPos = crPtr - m_msg;
phsfan 97:7d9cc95e2ea7 206 //Replace m_inputBuf[crPos] with null-terminating char
phsfan 97:7d9cc95e2ea7 207 m_msg[crPos] = '\0';
phsfan 97:7d9cc95e2ea7 208
phsfan 97:7d9cc95e2ea7 209 //If there is a CR char, split message there
phsfan 97:7d9cc95e2ea7 210
phsfan 97:7d9cc95e2ea7 211 //Do print the message
phsfan 97:7d9cc95e2ea7 212 int ret = pInst->sendData(m_msg);
phsfan 97:7d9cc95e2ea7 213 if(ret)
phsfan 97:7d9cc95e2ea7 214 {
phsfan 97:7d9cc95e2ea7 215 return ret;
phsfan 97:7d9cc95e2ea7 216 }
phsfan 97:7d9cc95e2ea7 217
phsfan 97:7d9cc95e2ea7 218 char cr[2] = {CR, '\0'};
phsfan 97:7d9cc95e2ea7 219 ret = pInst->sendData(cr);
phsfan 97:7d9cc95e2ea7 220 if(ret)
phsfan 97:7d9cc95e2ea7 221 {
phsfan 97:7d9cc95e2ea7 222 return ret;
phsfan 97:7d9cc95e2ea7 223 }
phsfan 97:7d9cc95e2ea7 224
phsfan 97:7d9cc95e2ea7 225 m_msg += crPos;
phsfan 97:7d9cc95e2ea7 226
phsfan 97:7d9cc95e2ea7 227 if(m_msg[0] == LF)
phsfan 97:7d9cc95e2ea7 228 {
phsfan 97:7d9cc95e2ea7 229 m_msg++; //Discard LF char as well
phsfan 97:7d9cc95e2ea7 230 }
phsfan 97:7d9cc95e2ea7 231
phsfan 97:7d9cc95e2ea7 232 return NET_MOREINFO;
phsfan 97:7d9cc95e2ea7 233 }
phsfan 97:7d9cc95e2ea7 234 else
phsfan 97:7d9cc95e2ea7 235 {
phsfan 97:7d9cc95e2ea7 236 //Do print the message
phsfan 97:7d9cc95e2ea7 237 pInst->sendData(m_msg);
phsfan 97:7d9cc95e2ea7 238 return OK;
phsfan 97:7d9cc95e2ea7 239 }
phsfan 97:7d9cc95e2ea7 240 }
phsfan 97:7d9cc95e2ea7 241
phsfan 97:7d9cc95e2ea7 242 return OK;
phsfan 97:7d9cc95e2ea7 243 }
phsfan 97:7d9cc95e2ea7 244
phsfan 97:7d9cc95e2ea7 245 /*virtual*/ bool SMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled
phsfan 97:7d9cc95e2ea7 246 {
phsfan 99:514e67a69ad6 247 if(m_state == SMS_IDLE) {
phsfan 99:514e67a69ad6 248 if( strncmp(atCode, "RING", 4) == 0 ) {
phsfan 99:514e67a69ad6 249 m_caller[0] = 0;
phsfan 99:514e67a69ad6 250 DBG("RING");
phsfan 99:514e67a69ad6 251 m_state = SMS_RING;
phsfan 99:514e67a69ad6 252 }
phsfan 99:514e67a69ad6 253 return true;
phsfan 99:514e67a69ad6 254 } else
phsfan 99:514e67a69ad6 255 if(m_state == SMS_RING) {
phsfan 99:514e67a69ad6 256 if( strncmp(atCode, "ID=", 3) == 0 ) {
phsfan 99:514e67a69ad6 257 strncpy(m_caller, &atCode[3], sizeof(m_caller));
phsfan 99:514e67a69ad6 258 m_caller[11] = 0;
phsfan 99:514e67a69ad6 259 DBG("ID %s", m_caller);
phsfan 99:514e67a69ad6 260 } else
phsfan 99:514e67a69ad6 261 if( strncmp(atCode, "NO CARRIER", 10) == 0 ) {
phsfan 99:514e67a69ad6 262 DBG("NO CARRIER");
phsfan 99:514e67a69ad6 263 m_state = SMS_IDLE;
phsfan 99:514e67a69ad6 264 }
phsfan 99:514e67a69ad6 265 return true;
phsfan 99:514e67a69ad6 266 }
phsfan 97:7d9cc95e2ea7 267 return false;
phsfan 97:7d9cc95e2ea7 268 }
phsfan 97:7d9cc95e2ea7 269
phsfan 97:7d9cc95e2ea7 270 /*virtual*/ void SMSInterface::onDispatchStart()
phsfan 97:7d9cc95e2ea7 271 {
phsfan 97:7d9cc95e2ea7 272
phsfan 97:7d9cc95e2ea7 273 }
phsfan 97:7d9cc95e2ea7 274
phsfan 97:7d9cc95e2ea7 275 /*virtual*/ void SMSInterface::onDispatchStop()
phsfan 97:7d9cc95e2ea7 276 {
phsfan 97:7d9cc95e2ea7 277
phsfan 97:7d9cc95e2ea7 278 }
phsfan 97:7d9cc95e2ea7 279
phsfan 97:7d9cc95e2ea7 280 /*virtual*/ char* SMSInterface::getEventsEnableCommand()
phsfan 97:7d9cc95e2ea7 281 {
phsfan 97:7d9cc95e2ea7 282 return NULL;
phsfan 97:7d9cc95e2ea7 283 }
phsfan 97:7d9cc95e2ea7 284
phsfan 97:7d9cc95e2ea7 285 /*virtual*/ char* SMSInterface::getEventsDisableCommand()
phsfan 97:7d9cc95e2ea7 286 {
phsfan 97:7d9cc95e2ea7 287 return NULL;
phsfan 97:7d9cc95e2ea7 288 }
phsfan 97:7d9cc95e2ea7 289
phsfan 97:7d9cc95e2ea7 290 /*virtual*/ void SMSInterface::onEvent(const char* atCode, const char* evt)
phsfan 97:7d9cc95e2ea7 291 {
phsfan 97:7d9cc95e2ea7 292 }