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.
SMSInterface.cpp
00001 /* SMSInterface.cpp */ 00002 /* 00003 Copyright (C) 2012 ARM Limited. 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy of 00006 this software and associated documentation files (the "Software"), to deal in 00007 the Software without restriction, including without limitation the rights to 00008 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 00009 of the Software, and to permit persons to whom the Software is furnished to do 00010 so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in all 00013 copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00021 SOFTWARE. 00022 */ 00023 00024 #define __DEBUG__ 4 00025 #ifndef __MODULE__ 00026 #define __MODULE__ "SMSInterface.cpp" 00027 #endif 00028 00029 #include "core/fwk.h" 00030 00031 #include "SMSInterface.h" 00032 00033 #include <cstdio> 00034 00035 #define DEFAULT_TIMEOUT 10000 00036 00037 SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL), /*m_msgCount(0),*/ 00038 m_msgRefListCount(0), m_needsUpdate(true), m_state(SMS_IDLE) 00039 { 00040 m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers 00041 } 00042 00043 int SMSInterface::init() 00044 { 00045 DBG("Set format"); 00046 //Set Text mode format 00047 int ret = m_pIf->executeSimple("AT+CMGF=1", NULL, DEFAULT_TIMEOUT); 00048 if(ret != OK) 00049 { 00050 return NET_PROTOCOL; 00051 } 00052 00053 DBG("Setup new messages indication"); 00054 //Setup new messages indication 00055 ret = m_pIf->executeSimple("AT+CNMI=2,1,0,0,0", NULL, DEFAULT_TIMEOUT); 00056 if(ret != OK) 00057 { 00058 return NET_PROTOCOL; 00059 } 00060 00061 DBG("Try to fetch inbox"); 00062 m_inboxMtx.lock(); 00063 if( m_needsUpdate ) 00064 { 00065 ret = updateInbox(); //Fetch existing messages references 00066 if(ret) 00067 { 00068 m_inboxMtx.unlock(); 00069 return NET_PROTOCOL; 00070 } 00071 } 00072 m_inboxMtx.unlock(); 00073 00074 DBG("Initialization done"); 00075 return OK; 00076 } 00077 00078 int SMSInterface::send(const char* number, const char* message) 00079 { 00080 if( strlen(number) > 16 ) 00081 { 00082 return NET_INVALID; //Number too long to match 3GPP spec 00083 } 00084 00085 int ret; 00086 00087 //Prepare infos 00088 m_state = SMS_SEND_CMD_SENT; 00089 m_msg = (char*) message; 00090 00091 DBG("Send SM"); 00092 //Send command 00093 char cmd[32]; 00094 std::sprintf(cmd, "AT+CMGS=\"%s\"", number); 00095 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); 00096 00097 if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) ) 00098 { 00099 WARN("ret %d, state %d", ret, m_state); 00100 m_state = SMS_IDLE; 00101 return NET_PROTOCOL; 00102 } 00103 00104 DBG("SM sent"); 00105 m_state = SMS_IDLE; 00106 return OK; 00107 } 00108 00109 00110 int SMSInterface::get(char* number, char* message, size_t maxLength) 00111 { 00112 if( maxLength < 1 ) 00113 { 00114 return NET_INVALID; //Buffer too short 00115 } 00116 00117 int ret; 00118 00119 DBG("Get next message"); 00120 m_inboxMtx.lock(); 00121 if(m_msgRefListCount == 0 && m_needsUpdate) 00122 { 00123 ret = updateInbox(); 00124 if (ret) 00125 { 00126 m_inboxMtx.unlock(); 00127 return ret; 00128 } 00129 } 00130 00131 if(m_msgRefListCount == 0) 00132 { 00133 m_inboxMtx.unlock(); 00134 return NET_EMPTY; //No message to read 00135 } 00136 00137 //Prepare infos 00138 m_state = SMS_GET_CMD_SENT; 00139 m_msisdn = (char*) number; 00140 m_msg = (char*) message; 00141 m_maxMsgLength = maxLength; 00142 00143 DBG("Get SMS"); 00144 //List command 00145 char cmd[32]; 00146 std::sprintf(cmd, "AT+CMGR=%d", m_msgRefList[0]); 00147 ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); 00148 if( ret != OK ) 00149 { 00150 WARN("AT+CMGR returned %d", ret); 00151 m_state = SMS_IDLE; 00152 m_inboxMtx.unlock(); 00153 return NET_PROTOCOL; 00154 } 00155 00156 if (m_state != SMS_CMD_PROCESSED) 00157 { 00158 m_state = SMS_IDLE; 00159 m_inboxMtx.unlock(); 00160 return NET_EMPTY; 00161 } 00162 00163 m_state = SMS_IDLE; 00164 00165 DBG("Deleting message"); 00166 //Delete message from outbox 00167 std::sprintf(cmd, "AT+CMGD=%d", m_msgRefList[0]); 00168 ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT); 00169 if(ret != OK) 00170 { 00171 m_inboxMtx.unlock(); 00172 WARN("Could not delete message"); 00173 } 00174 00175 //Remove message from list 00176 std::memmove(m_msgRefList, m_msgRefList+1, m_msgRefListCount-1); 00177 m_msgRefListCount--; 00178 00179 m_inboxMtx.unlock(); 00180 00181 return OK; 00182 } 00183 00184 00185 int SMSInterface::getCount(size_t* pCount) 00186 { 00187 int ret; 00188 00189 m_inboxMtx.lock(); 00190 if( m_needsUpdate ) 00191 { 00192 ret = updateInbox(); 00193 if(ret) 00194 { 00195 m_inboxMtx.unlock(); 00196 return NET_PROTOCOL; 00197 } 00198 } 00199 00200 *pCount = m_msgRefListCount; 00201 m_inboxMtx.unlock(); 00202 00203 return OK; 00204 } 00205 00206 00207 /*virtual*/ int SMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00208 { 00209 if(m_state == SMS_SEND_CMD_SENT) 00210 { 00211 if( std::sscanf(line, "+CMGS: %*d") == 0 ) 00212 { 00213 DBG("SM sent"); 00214 m_state = SMS_CMD_PROCESSED; 00215 } 00216 } 00217 else if(m_state == SMS_GET_CMD_SENT) 00218 { 00219 DBG("Header: %s", line); 00220 if( std::sscanf(line, "+CMGR: %*[^,],\"%16[^\"]\"", m_msisdn) == 1 ) //Get message ref 00221 { 00222 m_state = SMS_GET_HDR_RECEIVED; 00223 } 00224 } 00225 else if(m_state == SMS_GET_HDR_RECEIVED) 00226 { 00227 DBG("Message: %s", line); 00228 size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 ); 00229 std::memcpy( m_msg, line, cpyLen ); 00230 m_msg[cpyLen] = '\0'; 00231 m_state = SMS_CMD_PROCESSED; 00232 } 00233 else if(m_state == SMS_GET_COUNT_CMD_SENT) 00234 { 00235 DBG("Header: %s", line); 00236 int msgRef; 00237 if( std::sscanf(line, "+CMGL: %d", &msgRef) == 1 ) 00238 { 00239 m_state = SMS_GET_COUNT_HDR_RECEIVED; 00240 //Add message to list 00241 if(m_msgRefListCount < MAX_SM) 00242 { 00243 m_msgRefList[m_msgRefListCount] = msgRef; 00244 } 00245 m_msgRefListCount++; //Always count message 00246 DBG("m_msgRefListCount=%d",m_msgRefListCount); 00247 } 00248 } 00249 else if(m_state == SMS_GET_COUNT_HDR_RECEIVED) 00250 { 00251 DBG("Message (debug only): %s", line); //For debug only 00252 m_state = SMS_GET_COUNT_CMD_SENT; 00253 } 00254 return OK; 00255 } 00256 00257 /*virtual*/ int SMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst) 00258 { 00259 if(m_state == SMS_SEND_CMD_SENT) 00260 { 00261 char* crPtr = strchr(m_msg, CR); 00262 if(crPtr != NULL) 00263 { 00264 int crPos = crPtr - m_msg; 00265 //Replace m_inputBuf[crPos] with null-terminating char 00266 m_msg[crPos] = '\x0'; 00267 00268 //If there is a CR char, split message there 00269 00270 //Do print the message 00271 int ret = pInst->sendData(m_msg); 00272 if(ret) 00273 { 00274 return ret; 00275 } 00276 00277 char cr[2] = {CR, '\0'}; 00278 ret = pInst->sendData(cr); 00279 if(ret) 00280 { 00281 return ret; 00282 } 00283 00284 m_msg += crPos; 00285 00286 if(m_msg[0] == LF) 00287 { 00288 m_msg++; //Discard LF char as well 00289 } 00290 00291 return NET_MOREINFO; 00292 } 00293 else 00294 { 00295 //Do print the message 00296 pInst->sendData(m_msg); 00297 return OK; 00298 } 00299 } 00300 00301 return OK; 00302 } 00303 00304 /*virtual*/ bool SMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled 00305 { 00306 DBG("AT code is %s", atCode); 00307 if( strcmp("+CMTI", atCode) == 0 ) 00308 { 00309 return true; 00310 } 00311 00312 DBG("Not handled"); 00313 return false; 00314 } 00315 00316 /*virtual*/ void SMSInterface::onDispatchStart() 00317 { 00318 00319 00320 } 00321 00322 /*virtual*/ void SMSInterface::onDispatchStop() 00323 { 00324 00325 } 00326 00327 /*virtual*/ void SMSInterface::onEvent(const char* atCode, const char* evt) 00328 { 00329 if( strcmp("+CMTI", atCode) != 0 ) 00330 { 00331 return; //Not supported 00332 } 00333 00334 DBG("Unsollicited result code: %s - %s", atCode, evt); 00335 00336 //Get index 00337 int msgRef; 00338 if( std::sscanf(evt, "\"SM\",%d", &msgRef) == 1 ) 00339 { 00340 DBG("Adding message to list (ref %d)", msgRef); 00341 m_inboxMtx.lock(); 00342 //Add message to list 00343 if(m_msgRefListCount < MAX_SM) 00344 { 00345 m_msgRefList[m_msgRefListCount] = msgRef; 00346 } 00347 else 00348 { 00349 m_needsUpdate = true; 00350 } 00351 m_msgRefListCount++; //Always count message 00352 m_inboxMtx.unlock(); 00353 } 00354 } 00355 00356 int SMSInterface::updateInbox() 00357 { 00358 //Get memory indexes of unread messages 00359 m_state = SMS_GET_COUNT_CMD_SENT; 00360 00361 DBG("Updating inbox"); 00362 m_msgRefListCount = 0; //Reset list 00363 00364 int ret = m_pIf->execute("AT+CMGL=\"REC UNREAD\"", this, NULL, DEFAULT_TIMEOUT); 00365 if( ret != OK ) 00366 { 00367 WARN("AT+CMGL returned %d", ret); 00368 m_state = SMS_IDLE; 00369 m_msgRefListCount = 0; //List could be invalid 00370 m_needsUpdate = true; 00371 return NET_PROTOCOL; 00372 } 00373 00374 DBG("%d incoming messages in inbox", m_msgRefListCount); 00375 00376 if( m_msgRefListCount > MAX_SM ) 00377 { 00378 m_needsUpdate = true; 00379 } 00380 else 00381 { 00382 m_needsUpdate = false; 00383 } 00384 00385 m_state = SMS_IDLE; 00386 00387 return OK; 00388 } 00389 00390
Generated on Tue Jul 12 2022 17:50:56 by
