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