USB Host Library for Sprint Dongles

Dependencies:   Socket USBHostWANDongleSprint lwip-sys lwip

Dependents:   SprintUSBModemWebsocketTest SprintUSBModemHTTPClientTest SprintUSBModemNTPClientTest SprintUSBModemSMSTest ... more

Fork of SprintUSBModem_bleedingedge by Donatien Garnier

Committer:
donatien
Date:
Mon Dec 10 18:23:49 2012 +0000
Revision:
14:f6f17843e5ef
Parent:
7:098c2adcc17a
Separate USB/Sprint dev flows, fix regression in mbed rev. 41+ lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:8f57713b2147 1 /* SMSInterface.cpp */
donatien 0:8f57713b2147 2 /* Copyright (C) 2012 mbed.org, MIT License
donatien 0:8f57713b2147 3 *
donatien 0:8f57713b2147 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
donatien 0:8f57713b2147 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
donatien 0:8f57713b2147 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
donatien 0:8f57713b2147 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
donatien 0:8f57713b2147 8 * furnished to do so, subject to the following conditions:
donatien 0:8f57713b2147 9 *
donatien 0:8f57713b2147 10 * The above copyright notice and this permission notice shall be included in all copies or
donatien 0:8f57713b2147 11 * substantial portions of the Software.
donatien 0:8f57713b2147 12 *
donatien 0:8f57713b2147 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
donatien 0:8f57713b2147 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
donatien 0:8f57713b2147 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
donatien 0:8f57713b2147 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 0:8f57713b2147 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
donatien 0:8f57713b2147 18 */
donatien 0:8f57713b2147 19
donatien 6:56000fe39df9 20 #define __DEBUG__ 0
donatien 0:8f57713b2147 21 #ifndef __MODULE__
donatien 0:8f57713b2147 22 #define __MODULE__ "SMSInterface.cpp"
donatien 0:8f57713b2147 23 #endif
donatien 0:8f57713b2147 24
donatien 0:8f57713b2147 25 #include "core/fwk.h"
donatien 0:8f57713b2147 26
donatien 0:8f57713b2147 27 #include "SMSInterface.h"
donatien 0:8f57713b2147 28
donatien 0:8f57713b2147 29 #include <cstdio>
donatien 0:8f57713b2147 30
donatien 0:8f57713b2147 31 #define DEFAULT_TIMEOUT 10000
donatien 0:8f57713b2147 32
donatien 4:23100b0757d6 33 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
donatien 0:8f57713b2147 34 {
donatien 0:8f57713b2147 35 }
donatien 0:8f57713b2147 36
donatien 0:8f57713b2147 37 int SMSInterface::init()
donatien 0:8f57713b2147 38 {
donatien 4:23100b0757d6 39 m_state = SMS_IDLE;
donatien 4:23100b0757d6 40
donatien 6:56000fe39df9 41 DBG("Get number of messages in the different inboxes");
donatien 6:56000fe39df9 42 int ret = updateInbox();
donatien 6:56000fe39df9 43 if(ret)
donatien 0:8f57713b2147 44 {
donatien 0:8f57713b2147 45 return NET_PROTOCOL;
donatien 0:8f57713b2147 46 }
donatien 6:56000fe39df9 47
donatien 0:8f57713b2147 48 DBG("Initialization done");
donatien 0:8f57713b2147 49 return OK;
donatien 0:8f57713b2147 50 }
donatien 0:8f57713b2147 51
donatien 0:8f57713b2147 52 int SMSInterface::send(const char* number, const char* message)
donatien 0:8f57713b2147 53 {
donatien 0:8f57713b2147 54 if( strlen(number) > 16 )
donatien 0:8f57713b2147 55 {
donatien 6:56000fe39df9 56 return NET_INVALID; //Number too long
donatien 0:8f57713b2147 57 }
donatien 0:8f57713b2147 58
donatien 0:8f57713b2147 59 int ret;
donatien 0:8f57713b2147 60
donatien 0:8f57713b2147 61 //Prepare infos
donatien 0:8f57713b2147 62 m_state = SMS_SEND_CMD_SENT;
donatien 6:56000fe39df9 63
donatien 6:56000fe39df9 64 bool intlNumber=(number[0]=='+'); //If the number starts with the + sign, replace it with 011 instead (int'l dialing code in the US)
donatien 0:8f57713b2147 65
donatien 0:8f57713b2147 66 DBG("Send SM");
donatien 0:8f57713b2147 67 //Send command
donatien 6:56000fe39df9 68 char cmd[32+strlen(message)];
donatien 6:56000fe39df9 69 std::sprintf(cmd, "AT!SSMS=0,%s%s,,\"%s\"",intlNumber?"011":"", intlNumber?(number+1):number, message); //Send with normal priority
donatien 0:8f57713b2147 70 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
donatien 0:8f57713b2147 71
donatien 6:56000fe39df9 72 if(ret != OK)
donatien 0:8f57713b2147 73 {
donatien 6:56000fe39df9 74 WARN("ret %d", ret);
donatien 0:8f57713b2147 75 m_state = SMS_IDLE;
donatien 0:8f57713b2147 76 return NET_PROTOCOL;
donatien 0:8f57713b2147 77 }
donatien 0:8f57713b2147 78
donatien 6:56000fe39df9 79 DBG("Check status");
donatien 6:56000fe39df9 80 m_txState = SMS_PENDING;
donatien 6:56000fe39df9 81
donatien 6:56000fe39df9 82 int tries = 10;
donatien 6:56000fe39df9 83 while(tries--)
donatien 6:56000fe39df9 84 {
donatien 6:56000fe39df9 85 m_state = SMS_GET_TX_STATUS_CMD_SENT;
donatien 6:56000fe39df9 86 ret = m_pIf->execute("AT!SSMS?", this, NULL, DEFAULT_TIMEOUT);
donatien 6:56000fe39df9 87 if(ret)
donatien 6:56000fe39df9 88 {
donatien 6:56000fe39df9 89 m_state = SMS_IDLE;
donatien 6:56000fe39df9 90 return ret;
donatien 6:56000fe39df9 91 }
donatien 6:56000fe39df9 92 m_state = SMS_IDLE;
donatien 6:56000fe39df9 93 if(m_txState == SMS_PENDING) //Wait more
donatien 6:56000fe39df9 94 {
donatien 6:56000fe39df9 95 Thread::wait(1000);
donatien 6:56000fe39df9 96 continue;
donatien 6:56000fe39df9 97 }
donatien 6:56000fe39df9 98 else if(m_txState == SMS_FAILED)
donatien 6:56000fe39df9 99 {
donatien 6:56000fe39df9 100 ERR("The modem could not send the SM");
donatien 6:56000fe39df9 101 return NET_CONN; //Probably a conenction issue, the user can retry
donatien 6:56000fe39df9 102 }
donatien 6:56000fe39df9 103 else
donatien 6:56000fe39df9 104 {
donatien 6:56000fe39df9 105 break;
donatien 6:56000fe39df9 106 }
donatien 6:56000fe39df9 107 }
donatien 6:56000fe39df9 108 if(!tries)
donatien 6:56000fe39df9 109 {
donatien 6:56000fe39df9 110 ERR("The is still trying to send the SM");
donatien 6:56000fe39df9 111 return NET_TIMEOUT;
donatien 6:56000fe39df9 112 }
donatien 0:8f57713b2147 113 return OK;
donatien 0:8f57713b2147 114 }
donatien 0:8f57713b2147 115
donatien 0:8f57713b2147 116
donatien 0:8f57713b2147 117 int SMSInterface::get(char* number, char* message, size_t maxLength)
donatien 0:8f57713b2147 118 {
donatien 0:8f57713b2147 119 if( maxLength < 1 )
donatien 0:8f57713b2147 120 {
donatien 0:8f57713b2147 121 return NET_INVALID; //Buffer too short
donatien 0:8f57713b2147 122 }
donatien 0:8f57713b2147 123
donatien 0:8f57713b2147 124 int ret;
donatien 0:8f57713b2147 125
donatien 0:8f57713b2147 126 DBG("Get next message");
donatien 6:56000fe39df9 127 if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0)
donatien 0:8f57713b2147 128 {
donatien 4:23100b0757d6 129 DBG("Message list count is 0 and needs updating. Running updateInbox.");
donatien 0:8f57713b2147 130 ret = updateInbox();
donatien 0:8f57713b2147 131 if (ret)
donatien 0:8f57713b2147 132 {
donatien 0:8f57713b2147 133 return ret;
donatien 0:8f57713b2147 134 }
donatien 0:8f57713b2147 135 }
donatien 0:8f57713b2147 136
donatien 6:56000fe39df9 137 if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0)
donatien 6:56000fe39df9 138 {
donatien 6:56000fe39df9 139 DBG("Message list count is 0");
donatien 6:56000fe39df9 140 return NET_EMPTY; //No message to read
donatien 6:56000fe39df9 141 }
donatien 6:56000fe39df9 142
donatien 6:56000fe39df9 143 //Determine which index to use : 3 (read), then 1 (urgent), then 2 (regular)
donatien 6:56000fe39df9 144 int index;
donatien 6:56000fe39df9 145 if(m_msgInListsCount[2])
donatien 0:8f57713b2147 146 {
donatien 6:56000fe39df9 147 index = 3;
donatien 6:56000fe39df9 148 }
donatien 6:56000fe39df9 149 else if(m_msgInListsCount[0])
donatien 6:56000fe39df9 150 {
donatien 6:56000fe39df9 151 index = 1;
donatien 6:56000fe39df9 152 }
donatien 6:56000fe39df9 153 else //if(m_msgInListsCount[1])
donatien 6:56000fe39df9 154 {
donatien 6:56000fe39df9 155 index = 2;
donatien 0:8f57713b2147 156 }
donatien 0:8f57713b2147 157
donatien 0:8f57713b2147 158 //Prepare infos
donatien 0:8f57713b2147 159 m_state = SMS_GET_CMD_SENT;
donatien 0:8f57713b2147 160 m_msisdn = (char*) number;
donatien 0:8f57713b2147 161 m_msg = (char*) message;
donatien 0:8f57713b2147 162 m_maxMsgLength = maxLength;
donatien 6:56000fe39df9 163 m_headersToRead = 3;
donatien 6:56000fe39df9 164
donatien 6:56000fe39df9 165 m_msisdn[0] = '\0';
donatien 0:8f57713b2147 166
donatien 0:8f57713b2147 167 DBG("Get SMS");
donatien 6:56000fe39df9 168 //Read command
donatien 0:8f57713b2147 169 char cmd[32];
donatien 6:56000fe39df9 170 std::sprintf(cmd, "AT!GSMS?%d,1", index); //1 is the oldest message
donatien 0:8f57713b2147 171 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
donatien 0:8f57713b2147 172 if( ret != OK )
donatien 0:8f57713b2147 173 {
donatien 6:56000fe39df9 174 WARN("AT!GSMS returned %d", ret);
donatien 0:8f57713b2147 175 m_state = SMS_IDLE;
donatien 0:8f57713b2147 176 return NET_PROTOCOL;
donatien 0:8f57713b2147 177 }
donatien 6:56000fe39df9 178
donatien 6:56000fe39df9 179 //If message is not read, it will be put at the end of the read list
donatien 6:56000fe39df9 180 int item;
donatien 6:56000fe39df9 181 if( index != 3 )
donatien 0:8f57713b2147 182 {
donatien 6:56000fe39df9 183 //Decrement count in relevant list
donatien 6:56000fe39df9 184 m_msgInListsCount[index-1]--;
donatien 6:56000fe39df9 185 //Increment count in read list
donatien 6:56000fe39df9 186 m_msgInListsCount[3-1]++;
donatien 6:56000fe39df9 187 item = m_msgInListsCount[3-1];
donatien 6:56000fe39df9 188 //Normally item should be equal to 1 as we'd have read any older messages first
donatien 6:56000fe39df9 189 if( item != 1 )
donatien 6:56000fe39df9 190 {
donatien 6:56000fe39df9 191 WARN("Still some older messages pending in the read inbox");
donatien 6:56000fe39df9 192 }
donatien 0:8f57713b2147 193 }
donatien 6:56000fe39df9 194 else
donatien 6:56000fe39df9 195 {
donatien 6:56000fe39df9 196 //The item is still the oldest one
donatien 6:56000fe39df9 197 item = 1;
donatien 6:56000fe39df9 198 }
donatien 6:56000fe39df9 199
donatien 6:56000fe39df9 200 DBG("Deleting message");
donatien 6:56000fe39df9 201 //Delete message from inbox
donatien 7:098c2adcc17a 202 std::sprintf(cmd, "AT!DSMS=3"/*,%d", item*/); //FIXME why doesn't that work when specifying the index??
donatien 0:8f57713b2147 203 ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT);
donatien 0:8f57713b2147 204 if(ret != OK)
donatien 0:8f57713b2147 205 {
donatien 4:23100b0757d6 206 ERR("Could not delete message");
donatien 0:8f57713b2147 207 }
donatien 6:56000fe39df9 208 else
donatien 6:56000fe39df9 209 {
donatien 6:56000fe39df9 210 //Now we can decrease the number of read messages
donatien 6:56000fe39df9 211 m_msgInListsCount[3-1]--;
donatien 6:56000fe39df9 212 }
donatien 4:23100b0757d6 213
donatien 4:23100b0757d6 214 if (m_state != SMS_CMD_PROCESSED)
donatien 4:23100b0757d6 215 {
donatien 6:56000fe39df9 216 WARN("Message could not be retrieved properly");
donatien 4:23100b0757d6 217 m_state = SMS_IDLE;
donatien 4:23100b0757d6 218 return NET_EMPTY;
donatien 4:23100b0757d6 219 }
donatien 4:23100b0757d6 220
donatien 4:23100b0757d6 221 m_state = SMS_IDLE;
donatien 0:8f57713b2147 222
donatien 0:8f57713b2147 223 return OK;
donatien 0:8f57713b2147 224 }
donatien 0:8f57713b2147 225
donatien 0:8f57713b2147 226
donatien 0:8f57713b2147 227 int SMSInterface::getCount(size_t* pCount)
donatien 0:8f57713b2147 228 {
donatien 6:56000fe39df9 229 int ret = updateInbox();
donatien 6:56000fe39df9 230 if(ret)
donatien 0:8f57713b2147 231 {
donatien 0:8f57713b2147 232 return NET_PROTOCOL;
donatien 0:8f57713b2147 233 }
donatien 0:8f57713b2147 234
donatien 6:56000fe39df9 235 *pCount = m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]; //Urgent messages + regular messages + read messages
donatien 0:8f57713b2147 236
donatien 0:8f57713b2147 237 return OK;
donatien 0:8f57713b2147 238 }
donatien 0:8f57713b2147 239
donatien 0:8f57713b2147 240
donatien 0:8f57713b2147 241 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
donatien 0:8f57713b2147 242 {
donatien 0:8f57713b2147 243 if(m_state == SMS_SEND_CMD_SENT)
donatien 0:8f57713b2147 244 {
donatien 6:56000fe39df9 245 DBG("SMS Send: %s", line);
donatien 6:56000fe39df9 246 }
donatien 6:56000fe39df9 247 else if(m_state == SMS_GET_TX_STATUS_CMD_SENT)
donatien 6:56000fe39df9 248 {
donatien 6:56000fe39df9 249 if(!strcmp(line, "sent"))
donatien 6:56000fe39df9 250 {
donatien 6:56000fe39df9 251 m_txState = SMS_SENT;
donatien 6:56000fe39df9 252 m_state = SMS_CMD_PROCESSED;
donatien 6:56000fe39df9 253 }
donatien 6:56000fe39df9 254 else if(!strcmp(line, "failed"))
donatien 0:8f57713b2147 255 {
donatien 6:56000fe39df9 256 m_txState = SMS_FAILED;
donatien 6:56000fe39df9 257 m_state = SMS_CMD_PROCESSED;
donatien 6:56000fe39df9 258 }
donatien 6:56000fe39df9 259 else if(!strcmp(line, "none"))
donatien 6:56000fe39df9 260 {
donatien 6:56000fe39df9 261 m_txState = SMS_NONE;
donatien 6:56000fe39df9 262 m_state = SMS_CMD_PROCESSED;
donatien 6:56000fe39df9 263 }
donatien 6:56000fe39df9 264 else if(!strcmp(line, "pending"))
donatien 6:56000fe39df9 265 {
donatien 6:56000fe39df9 266 m_txState = SMS_PENDING;
donatien 0:8f57713b2147 267 m_state = SMS_CMD_PROCESSED;
donatien 0:8f57713b2147 268 }
donatien 0:8f57713b2147 269 }
donatien 0:8f57713b2147 270 else if(m_state == SMS_GET_CMD_SENT)
donatien 0:8f57713b2147 271 {
donatien 0:8f57713b2147 272 DBG("Header: %s", line);
donatien 6:56000fe39df9 273
donatien 6:56000fe39df9 274 if(m_msisdn[0]=='\0')
donatien 0:8f57713b2147 275 {
donatien 6:56000fe39df9 276 sscanf(line, "From: %16s", m_msisdn);
donatien 6:56000fe39df9 277 }
donatien 6:56000fe39df9 278
donatien 6:56000fe39df9 279 m_headersToRead--;
donatien 6:56000fe39df9 280
donatien 6:56000fe39df9 281 if(m_headersToRead==0) //End of headers
donatien 6:56000fe39df9 282 {
donatien 6:56000fe39df9 283 if(m_msisdn[0]!='\0') //Checks that the incoming number has been retrieved
donatien 6:56000fe39df9 284 {
donatien 6:56000fe39df9 285 m_state = SMS_GET_HDR_RECEIVED;
donatien 6:56000fe39df9 286 }
donatien 6:56000fe39df9 287 else
donatien 6:56000fe39df9 288 {
donatien 6:56000fe39df9 289 m_state = SMS_IDLE; //Error, signal it
donatien 6:56000fe39df9 290 }
donatien 0:8f57713b2147 291 }
donatien 0:8f57713b2147 292 }
donatien 0:8f57713b2147 293 else if(m_state == SMS_GET_HDR_RECEIVED)
donatien 0:8f57713b2147 294 {
donatien 0:8f57713b2147 295 DBG("Message: %s", line);
donatien 0:8f57713b2147 296 size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 );
donatien 0:8f57713b2147 297 std::memcpy( m_msg, line, cpyLen );
donatien 0:8f57713b2147 298 m_msg[cpyLen] = '\0';
donatien 0:8f57713b2147 299 m_state = SMS_CMD_PROCESSED;
donatien 0:8f57713b2147 300 }
donatien 0:8f57713b2147 301 else if(m_state == SMS_GET_COUNT_CMD_SENT)
donatien 0:8f57713b2147 302 {
donatien 6:56000fe39df9 303 DBG("Inbox: %s", line);
donatien 6:56000fe39df9 304 int index;
donatien 6:56000fe39df9 305 size_t count;
donatien 6:56000fe39df9 306 if((strlen(line) > 16) && sscanf(line + 16, "{Index = %d}: %d", &index, &count) == 2)
donatien 0:8f57713b2147 307 {
donatien 6:56000fe39df9 308 if((index > 0) && (index <=4))
donatien 0:8f57713b2147 309 {
donatien 6:56000fe39df9 310 m_msgInListsCount[index-1] = count;
donatien 0:8f57713b2147 311 }
donatien 6:56000fe39df9 312 if(index == 4)
donatien 6:56000fe39df9 313 {
donatien 6:56000fe39df9 314 m_state = SMS_CMD_PROCESSED;
donatien 6:56000fe39df9 315 }
donatien 0:8f57713b2147 316 }
donatien 0:8f57713b2147 317 }
donatien 0:8f57713b2147 318 return OK;
donatien 0:8f57713b2147 319 }
donatien 0:8f57713b2147 320
donatien 0:8f57713b2147 321 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
donatien 0:8f57713b2147 322 {
donatien 6:56000fe39df9 323 return OK;
donatien 6:56000fe39df9 324 }
donatien 6:56000fe39df9 325
donatien 0:8f57713b2147 326
donatien 6:56000fe39df9 327 int SMSInterface::updateInbox()
donatien 6:56000fe39df9 328 {
donatien 6:56000fe39df9 329 //Get number of unread/read messages
donatien 0:8f57713b2147 330
donatien 6:56000fe39df9 331 DBG("Updating inbox");
donatien 6:56000fe39df9 332 m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Reset counts
donatien 0:8f57713b2147 333
donatien 6:56000fe39df9 334 //Get counts
donatien 6:56000fe39df9 335 m_state = SMS_GET_COUNT_CMD_SENT;
donatien 6:56000fe39df9 336 int ret = m_pIf->execute("AT!CNTSMS", this, NULL, DEFAULT_TIMEOUT);
donatien 6:56000fe39df9 337 if( ret != OK )
donatien 6:56000fe39df9 338 {
donatien 6:56000fe39df9 339 WARN("AT!CNTSMS returned %d", ret);
donatien 6:56000fe39df9 340 m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Invalidate counts
donatien 6:56000fe39df9 341 m_state = SMS_IDLE;
donatien 6:56000fe39df9 342 return NET_PROTOCOL;
donatien 0:8f57713b2147 343 }
donatien 0:8f57713b2147 344
donatien 0:8f57713b2147 345 return OK;
donatien 0:8f57713b2147 346 }
donatien 0:8f57713b2147 347