Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SprintUSBModemHTTPClientTest by
SMSInterface.cpp
00001 /* SMSInterface.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__ "SMSInterface.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include "SMSInterface.h" 00028 00029 #include <cstdio> 00030 00031 #define DEFAULT_TIMEOUT 10000 00032 00033 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL) 00034 { 00035 } 00036 00037 int SMSInterface::init() 00038 { 00039 m_state = SMS_IDLE; 00040 00041 DBG("Get number of messages in the different inboxes"); 00042 int ret = updateInbox(); 00043 if(ret) 00044 { 00045 return NET_PROTOCOL; 00046 } 00047 00048 DBG("Initialization done"); 00049 return OK; 00050 } 00051 00052 int SMSInterface::send(const char* number, const char* message) 00053 { 00054 if( strlen(number) > 16 ) 00055 { 00056 return NET_INVALID; //Number too long 00057 } 00058 00059 int ret; 00060 00061 //Prepare infos 00062 m_state = SMS_SEND_CMD_SENT; 00063 00064 bool intlNumber=(number[0]=='+'); //If the number starts with the + sign, replace it with 011 instead (int'l dialing code in the US) 00065 00066 DBG("Send SM"); 00067 //Send command 00068 char cmd[32+strlen(message)]; 00069 std::sprintf(cmd, "AT!SSMS=0,%s%s,,\"%s\"",intlNumber?"011":"", intlNumber?(number+1):number, message); //Send with normal priority 00070 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); 00071 00072 if(ret != OK) 00073 { 00074 WARN("ret %d", ret); 00075 m_state = SMS_IDLE; 00076 return NET_PROTOCOL; 00077 } 00078 00079 DBG("Check status"); 00080 m_txState = SMS_PENDING; 00081 00082 int tries = 10; 00083 while(tries--) 00084 { 00085 m_state = SMS_GET_TX_STATUS_CMD_SENT; 00086 ret = m_pIf->execute("AT!SSMS?", this, NULL, DEFAULT_TIMEOUT); 00087 if(ret) 00088 { 00089 m_state = SMS_IDLE; 00090 return ret; 00091 } 00092 m_state = SMS_IDLE; 00093 if(m_txState == SMS_PENDING) //Wait more 00094 { 00095 Thread::wait(1000); 00096 continue; 00097 } 00098 else if(m_txState == SMS_FAILED) 00099 { 00100 ERR("The modem could not send the SM"); 00101 return NET_CONN; //Probably a conenction issue, the user can retry 00102 } 00103 else 00104 { 00105 break; 00106 } 00107 } 00108 if(!tries) 00109 { 00110 ERR("The is still trying to send the SM"); 00111 return NET_TIMEOUT; 00112 } 00113 return OK; 00114 } 00115 00116 00117 int SMSInterface::get(char* number, char* message, size_t maxLength) 00118 { 00119 if( maxLength < 1 ) 00120 { 00121 return NET_INVALID; //Buffer too short 00122 } 00123 00124 int ret; 00125 00126 DBG("Get next message"); 00127 if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0) 00128 { 00129 DBG("Message list count is 0 and needs updating. Running updateInbox."); 00130 ret = updateInbox(); 00131 if (ret) 00132 { 00133 return ret; 00134 } 00135 } 00136 00137 if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0) 00138 { 00139 DBG("Message list count is 0"); 00140 return NET_EMPTY; //No message to read 00141 } 00142 00143 //Determine which index to use : 3 (read), then 1 (urgent), then 2 (regular) 00144 int index; 00145 if(m_msgInListsCount[2]) 00146 { 00147 index = 3; 00148 } 00149 else if(m_msgInListsCount[0]) 00150 { 00151 index = 1; 00152 } 00153 else //if(m_msgInListsCount[1]) 00154 { 00155 index = 2; 00156 } 00157 00158 //Prepare infos 00159 m_state = SMS_GET_CMD_SENT; 00160 m_msisdn = (char*) number; 00161 m_msg = (char*) message; 00162 m_maxMsgLength = maxLength; 00163 m_headersToRead = 3; 00164 00165 m_msisdn[0] = '\0'; 00166 00167 DBG("Get SMS"); 00168 //Read command 00169 char cmd[32]; 00170 std::sprintf(cmd, "AT!GSMS?%d,1", index); //1 is the oldest message 00171 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); 00172 if( ret != OK ) 00173 { 00174 WARN("AT!GSMS returned %d", ret); 00175 m_state = SMS_IDLE; 00176 return NET_PROTOCOL; 00177 } 00178 00179 //If message is not read, it will be put at the end of the read list 00180 int item; 00181 if( index != 3 ) 00182 { 00183 //Decrement count in relevant list 00184 m_msgInListsCount[index-1]--; 00185 //Increment count in read list 00186 m_msgInListsCount[3-1]++; 00187 item = m_msgInListsCount[3-1]; 00188 //Normally item should be equal to 1 as we'd have read any older messages first 00189 if( item != 1 ) 00190 { 00191 WARN("Still some older messages pending in the read inbox"); 00192 } 00193 } 00194 else 00195 { 00196 //The item is still the oldest one 00197 item = 1; 00198 } 00199 00200 DBG("Deleting message"); 00201 //Delete message from inbox 00202 std::sprintf(cmd, "AT!DSMS=3"/*,%d", item*/); //FIXME why doesn't that work when specifying the index?? 00203 ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT); 00204 if(ret != OK) 00205 { 00206 ERR("Could not delete message"); 00207 } 00208 else 00209 { 00210 //Now we can decrease the number of read messages 00211 m_msgInListsCount[3-1]--; 00212 } 00213 00214 if (m_state != SMS_CMD_PROCESSED) 00215 { 00216 WARN("Message could not be retrieved properly"); 00217 m_state = SMS_IDLE; 00218 return NET_EMPTY; 00219 } 00220 00221 m_state = SMS_IDLE; 00222 00223 return OK; 00224 } 00225 00226 00227 int SMSInterface::getCount(size_t* pCount) 00228 { 00229 int ret = updateInbox(); 00230 if(ret) 00231 { 00232 return NET_PROTOCOL; 00233 } 00234 00235 *pCount = m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]; //Urgent messages + regular messages + read messages 00236 00237 return OK; 00238 } 00239 00240 00241 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00242 { 00243 if(m_state == SMS_SEND_CMD_SENT) 00244 { 00245 DBG("SMS Send: %s", line); 00246 } 00247 else if(m_state == SMS_GET_TX_STATUS_CMD_SENT) 00248 { 00249 if(!strcmp(line, "sent")) 00250 { 00251 m_txState = SMS_SENT; 00252 m_state = SMS_CMD_PROCESSED; 00253 } 00254 else if(!strcmp(line, "failed")) 00255 { 00256 m_txState = SMS_FAILED; 00257 m_state = SMS_CMD_PROCESSED; 00258 } 00259 else if(!strcmp(line, "none")) 00260 { 00261 m_txState = SMS_NONE; 00262 m_state = SMS_CMD_PROCESSED; 00263 } 00264 else if(!strcmp(line, "pending")) 00265 { 00266 m_txState = SMS_PENDING; 00267 m_state = SMS_CMD_PROCESSED; 00268 } 00269 } 00270 else if(m_state == SMS_GET_CMD_SENT) 00271 { 00272 DBG("Header: %s", line); 00273 00274 if(m_msisdn[0]=='\0') 00275 { 00276 sscanf(line, "From: %16s", m_msisdn); 00277 } 00278 00279 m_headersToRead--; 00280 00281 if(m_headersToRead==0) //End of headers 00282 { 00283 if(m_msisdn[0]!='\0') //Checks that the incoming number has been retrieved 00284 { 00285 m_state = SMS_GET_HDR_RECEIVED; 00286 } 00287 else 00288 { 00289 m_state = SMS_IDLE; //Error, signal it 00290 } 00291 } 00292 } 00293 else if(m_state == SMS_GET_HDR_RECEIVED) 00294 { 00295 DBG("Message: %s", line); 00296 size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 ); 00297 std::memcpy( m_msg, line, cpyLen ); 00298 m_msg[cpyLen] = '\0'; 00299 m_state = SMS_CMD_PROCESSED; 00300 } 00301 else if(m_state == SMS_GET_COUNT_CMD_SENT) 00302 { 00303 DBG("Inbox: %s", line); 00304 int index; 00305 size_t count; 00306 if((strlen(line) > 16) && sscanf(line + 16, "{Index = %d}: %d", &index, &count) == 2) 00307 { 00308 if((index > 0) && (index <=4)) 00309 { 00310 m_msgInListsCount[index-1] = count; 00311 } 00312 if(index == 4) 00313 { 00314 m_state = SMS_CMD_PROCESSED; 00315 } 00316 } 00317 } 00318 return OK; 00319 } 00320 00321 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst) 00322 { 00323 return OK; 00324 } 00325 00326 00327 int SMSInterface::updateInbox() 00328 { 00329 //Get number of unread/read messages 00330 00331 DBG("Updating inbox"); 00332 m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Reset counts 00333 00334 //Get counts 00335 m_state = SMS_GET_COUNT_CMD_SENT; 00336 int ret = m_pIf->execute("AT!CNTSMS", this, NULL, DEFAULT_TIMEOUT); 00337 if( ret != OK ) 00338 { 00339 WARN("AT!CNTSMS returned %d", ret); 00340 m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Invalidate counts 00341 m_state = SMS_IDLE; 00342 return NET_PROTOCOL; 00343 } 00344 00345 return OK; 00346 } 00347
Generated on Tue Jul 12 2022 13:16:06 by
1.7.2
