aboutsummaryrefslogtreecommitdiffstats
path: root/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms')
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.cpp350
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.h90
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.cpp423
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.h97
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/SMSInterface.h67
5 files changed, 1027 insertions, 0 deletions
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.cpp
new file mode 100644
index 000000000..978b3e1e8
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.cpp
@@ -0,0 +1,350 @@
+/* CDMASMSInterface.cpp */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define __DEBUG__ 0
+#ifndef __MODULE__
+#define __MODULE__ "CDMASMSInterface.cpp"
+#endif
+
+#include "core/fwk.h"
+
+#include "CDMASMSInterface.h"
+
+#include <cstdio>
+#include <cstring>
+
+using std::sscanf;
+
+#define DEFAULT_TIMEOUT 10000
+
+CDMASMSInterface::CDMASMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
+{
+}
+
+int CDMASMSInterface::init()
+{
+ m_state = SMS_IDLE;
+
+ DBG("Get number of messages in the different inboxes");
+ int ret = updateInbox();
+ if(ret)
+ {
+ return NET_PROTOCOL;
+ }
+
+ DBG("Initialization done");
+ return OK;
+}
+
+int CDMASMSInterface::send(const char* number, const char* message)
+{
+ if( strlen(number) > 16 )
+ {
+ return NET_INVALID; //Number too long
+ }
+
+ int ret;
+
+ //Prepare infos
+ m_state = SMS_SEND_CMD_SENT;
+
+ bool intlNumber=(number[0]=='+'); //If the number starts with the + sign, replace it with 011 instead (int'l dialing code in the US)
+
+ DBG("Send SM");
+ //Send command
+ char cmd[32+strlen(message)];
+ std::sprintf(cmd, "AT!SSMS=0,%s%s,,\"%s\"",intlNumber?"011":"", intlNumber?(number+1):number, message); //Send with normal priority
+ ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
+
+ if(ret != OK)
+ {
+ WARN("ret %d", ret);
+ m_state = SMS_IDLE;
+ return NET_PROTOCOL;
+ }
+
+ DBG("Check status");
+ m_txState = SMS_PENDING;
+
+ int tries = 10;
+ while(tries--)
+ {
+ m_state = SMS_GET_TX_STATUS_CMD_SENT;
+ ret = m_pIf->execute("AT!SSMS?", this, NULL, DEFAULT_TIMEOUT);
+ if(ret)
+ {
+ m_state = SMS_IDLE;
+ return ret;
+ }
+ m_state = SMS_IDLE;
+ if(m_txState == SMS_PENDING) //Wait more
+ {
+ Thread::wait(1000);
+ continue;
+ }
+ else if(m_txState == SMS_FAILED)
+ {
+ ERR("The modem could not send the SM");
+ return NET_CONN; //Probably a conenction issue, the user can retry
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(!tries)
+ {
+ ERR("The is still trying to send the SM");
+ return NET_TIMEOUT;
+ }
+ return OK;
+}
+
+
+int CDMASMSInterface::get(char* number, char* message, size_t maxLength)
+{
+ if( maxLength < 1 )
+ {
+ return NET_INVALID; //Buffer too short
+ }
+
+ int ret;
+
+ DBG("Get next message");
+ if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0)
+ {
+ DBG("Message list count is 0 and needs updating. Running updateInbox.");
+ ret = updateInbox();
+ if (ret)
+ {
+ return ret;
+ }
+ }
+
+ if( (m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]) == 0)
+ {
+ DBG("Message list count is 0");
+ return NET_EMPTY; //No message to read
+ }
+
+ //Determine which index to use : 3 (read), then 1 (urgent), then 2 (regular)
+ int index;
+ if(m_msgInListsCount[2])
+ {
+ index = 3;
+ }
+ else if(m_msgInListsCount[0])
+ {
+ index = 1;
+ }
+ else //if(m_msgInListsCount[1])
+ {
+ index = 2;
+ }
+
+ //Prepare infos
+ m_state = SMS_GET_CMD_SENT;
+ m_msisdn = (char*) number;
+ m_msg = (char*) message;
+ m_maxMsgLength = maxLength;
+ m_headersToRead = 3;
+
+ m_msisdn[0] = '\0';
+
+ DBG("Get SMS");
+ //Read command
+ char cmd[32];
+ std::sprintf(cmd, "AT!GSMS?%d,1", index); //1 is the oldest message
+ ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
+ if( ret != OK )
+ {
+ WARN("AT!GSMS returned %d", ret);
+ m_state = SMS_IDLE;
+ return NET_PROTOCOL;
+ }
+
+ //If message is not read, it will be put at the end of the read list
+ int item;
+ if( index != 3 )
+ {
+ //Decrement count in relevant list
+ m_msgInListsCount[index-1]--;
+ //Increment count in read list
+ m_msgInListsCount[3-1]++;
+ item = m_msgInListsCount[3-1];
+ //Normally item should be equal to 1 as we'd have read any older messages first
+ if( item != 1 )
+ {
+ WARN("Still some older messages pending in the read inbox");
+ }
+ }
+ else
+ {
+ //The item is still the oldest one
+ item = 1;
+ }
+
+ DBG("Deleting message");
+ //Delete message from inbox
+ std::sprintf(cmd, "AT!DSMS=3"/*,%d", item*/); //FIXME why doesn't that work when specifying the index??
+ ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT);
+ if(ret != OK)
+ {
+ ERR("Could not delete message");
+ }
+ else
+ {
+ //Now we can decrease the number of read messages
+ m_msgInListsCount[3-1]--;
+ }
+
+ if (m_state != SMS_CMD_PROCESSED)
+ {
+ WARN("Message could not be retrieved properly");
+ m_state = SMS_IDLE;
+ return NET_EMPTY;
+ }
+
+ m_state = SMS_IDLE;
+
+ return OK;
+}
+
+
+int CDMASMSInterface::getCount(size_t* pCount)
+{
+ int ret = updateInbox();
+ if(ret)
+ {
+ return NET_PROTOCOL;
+ }
+
+ *pCount = m_msgInListsCount[0] + m_msgInListsCount[1] + m_msgInListsCount[2]; //Urgent messages + regular messages + read messages
+
+ return OK;
+}
+
+
+/*virtual*/ int CDMASMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
+{
+ if(m_state == SMS_SEND_CMD_SENT)
+ {
+ DBG("SMS Send: %s", line);
+ }
+ else if(m_state == SMS_GET_TX_STATUS_CMD_SENT)
+ {
+ if(!strcmp(line, "sent"))
+ {
+ m_txState = SMS_SENT;
+ m_state = SMS_CMD_PROCESSED;
+ }
+ else if(!strcmp(line, "failed"))
+ {
+ m_txState = SMS_FAILED;
+ m_state = SMS_CMD_PROCESSED;
+ }
+ else if(!strcmp(line, "none"))
+ {
+ m_txState = SMS_NONE;
+ m_state = SMS_CMD_PROCESSED;
+ }
+ else if(!strcmp(line, "pending"))
+ {
+ m_txState = SMS_PENDING;
+ m_state = SMS_CMD_PROCESSED;
+ }
+ }
+ else if(m_state == SMS_GET_CMD_SENT)
+ {
+ DBG("Header: %s", line);
+
+ if(m_msisdn[0]=='\0')
+ {
+ sscanf(line, "From: %16s", m_msisdn);
+ }
+
+ m_headersToRead--;
+
+ if(m_headersToRead==0) //End of headers
+ {
+ if(m_msisdn[0]!='\0') //Checks that the incoming number has been retrieved
+ {
+ m_state = SMS_GET_HDR_RECEIVED;
+ }
+ else
+ {
+ m_state = SMS_IDLE; //Error, signal it
+ }
+ }
+ }
+ else if(m_state == SMS_GET_HDR_RECEIVED)
+ {
+ DBG("Message: %s", line);
+ size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 );
+ std::memcpy( m_msg, line, cpyLen );
+ m_msg[cpyLen] = '\0';
+ m_state = SMS_CMD_PROCESSED;
+ }
+ else if(m_state == SMS_GET_COUNT_CMD_SENT)
+ {
+ DBG("Inbox: %s", line);
+ int index;
+ size_t count;
+ if((strlen(line) > 16) && sscanf(line + 16, "{Index = %d}: %d", &index, &count) == 2)
+ {
+ if((index > 0) && (index <=4))
+ {
+ m_msgInListsCount[index-1] = count;
+ }
+ if(index == 4)
+ {
+ m_state = SMS_CMD_PROCESSED;
+ }
+ }
+ }
+ return OK;
+}
+
+/*virtual*/ int CDMASMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
+{
+ return OK;
+}
+
+
+int CDMASMSInterface::updateInbox()
+{
+ //Get number of unread/read messages
+
+ DBG("Updating inbox");
+ m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Reset counts
+
+ //Get counts
+ m_state = SMS_GET_COUNT_CMD_SENT;
+ int ret = m_pIf->execute("AT!CNTSMS", this, NULL, DEFAULT_TIMEOUT);
+ if( ret != OK )
+ {
+ WARN("AT!CNTSMS returned %d", ret);
+ m_msgInListsCount[0] = m_msgInListsCount[1] = m_msgInListsCount[2] = m_msgInListsCount[3] = 0; //Invalidate counts
+ m_state = SMS_IDLE;
+ return NET_PROTOCOL;
+ }
+
+ return OK;
+}
+
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.h
new file mode 100644
index 000000000..6aa4557c3
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/CDMASMSInterface.h
@@ -0,0 +1,90 @@
+/* SMSInterface.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef CDMASMSINTERFACE_H_
+#define CDMASMSINTERFACE_H_
+
+#include "SMSInterface.h"
+
+#define MAX_SM 8
+
+/** Component to use the Short Messages Service (SMS)
+ *
+ */
+class CDMASMSInterface : public ISMSInterface, protected IATCommandsProcessor
+{
+public:
+ /** Create SMSInterface instance
+ @param pIf Pointer to the ATCommandsInterface instance to use
+ */
+ CDMASMSInterface(ATCommandsInterface* pIf);
+
+ /** Initialize interface
+ Configure SMS commands & register for SMS-related unsolicited result codes
+ */
+ virtual int init();
+
+ /** Send a SM
+ @param number The receiver's phone number
+ @param message The message to send
+ @return 0 on success, error code on failure
+ */
+ virtual int send(const char* number, const char* message);
+
+
+ /** Receive a SM
+ @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the space for the null-terminating char)
+ @param message Pointer to a buffer to store the the incoming message
+ @param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
+ @return 0 on success, error code on failure
+ */
+ virtual int get(char* number, char* message, size_t maxLength);
+
+
+ /** Get the number of SMs in the incoming box
+ @param pCount pointer to store the number of unprocessed SMs on
+ @return 0 on success, error code on failure
+ */
+ virtual int getCount(size_t* pCount);
+
+protected:
+ //IATCommandsProcessor
+ virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line);
+ virtual int onNewEntryPrompt(ATCommandsInterface* pInst);
+
+ int updateInbox(); //Update messages count in the different inboxes
+
+private:
+ ATCommandsInterface* m_pIf;
+
+ //Current message
+ char* m_msg;
+ size_t m_maxMsgLength;
+ char* m_msisdn;
+
+ //Messages list
+ size_t m_msgInListsCount[4]; //4 lists
+
+ size_t m_headersToRead;
+
+ enum { SMS_NONE, SMS_SENT, SMS_PENDING, SMS_FAILED } m_txState;
+ enum { SMS_IDLE, SMS_SEND_CMD_SENT, SMS_GET_TX_STATUS_CMD_SENT, SMS_GET_CMD_SENT, SMS_GET_HDR_RECEIVED, SMS_GET_COUNT_CMD_SENT, SMS_CMD_PROCESSED } m_state;
+};
+
+#endif /* CDMASMSINTERFACE_H_ */
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.cpp
new file mode 100644
index 000000000..2ed50ad12
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.cpp
@@ -0,0 +1,423 @@
+/* GSMSMSInterface.cpp */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define __DEBUG__ 2
+#ifndef __MODULE__
+#define __MODULE__ "GSMSMSInterface.cpp"
+#endif
+
+#include "core/fwk.h"
+
+#include "GSMSMSInterface.h"
+
+#include <cstdio>
+#include <cstring>
+
+#define DEFAULT_TIMEOUT 10000
+
+GSMSMSInterface::GSMSMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
+{
+ m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers
+}
+
+int GSMSMSInterface::init()
+{
+ m_msgRefListCount = 0;
+ m_needsUpdate = true;
+ m_state = SMS_IDLE;
+
+ DBG("Set format");
+ //Set Text mode format
+ int ret = m_pIf->executeSimple("AT+CMGF=1", NULL, DEFAULT_TIMEOUT);
+ if(ret != OK)
+ {
+ return NET_PROTOCOL;
+ }
+
+ DBG("Setup new messages indication");
+ //Setup new messages indication
+ ret = m_pIf->executeSimple("AT+CNMI=2,1,0,0,0", NULL, DEFAULT_TIMEOUT);
+ if(ret != OK)
+ {
+ return NET_PROTOCOL;
+ }
+
+ DBG("Try to fetch inbox");
+ m_inboxMtx.lock();
+ if( m_needsUpdate )
+ {
+ ret = updateInbox(); //Fetch existing messages references
+ if(ret)
+ {
+ m_inboxMtx.unlock();
+ return NET_PROTOCOL;
+ }
+ }
+ m_inboxMtx.unlock();
+
+ DBG("Initialization done");
+ return OK;
+}
+
+int GSMSMSInterface::send(const char* number, const char* message)
+{
+ if( strlen(number) > 16 )
+ {
+ return NET_INVALID; //Number too long to match 3GPP spec
+ }
+
+ int ret;
+
+ //Prepare infos
+ m_state = SMS_SEND_CMD_SENT;
+ m_msg = (char*) message;
+
+ DBG("Send SM");
+ //Send command
+ char cmd[32];
+ std::sprintf(cmd, "AT+CMGS=\"%s\"", number);
+ ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
+
+ if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) )
+ {
+ WARN("ret %d, state %d", ret, m_state);
+ m_state = SMS_IDLE;
+ return NET_PROTOCOL;
+ }
+
+ DBG("SM sent");
+ m_state = SMS_IDLE;
+ return OK;
+}
+
+
+int GSMSMSInterface::get(char* number, char* message, size_t maxLength)
+{
+ if( maxLength < 1 )
+ {
+ return NET_INVALID; //Buffer too short
+ }
+
+ int ret;
+
+ DBG("Get next message");
+ m_inboxMtx.lock();
+ if( ((m_msgRefListCount == 0) && m_needsUpdate) || ((m_msgRefListCount > 0) && (m_msgRefList[0] == -1)) )
+ {
+ DBG("Message list count is 0 and needs updating or next index is unknown, calling updateInbox()");
+ ret = updateInbox();
+
+ if (ret)
+ {
+ m_inboxMtx.unlock();
+ return ret;
+ }
+ }
+
+ DBG("%d messages to read", m_msgRefListCount);
+
+ if(m_msgRefListCount == 0)
+ {
+ m_inboxMtx.unlock();
+ DBG("Message list count is 0, I think it's empty and returning.");
+ return NET_EMPTY; //No message to read
+ }
+
+ //Prepare infos
+ m_state = SMS_GET_CMD_SENT;
+ m_msisdn = (char*) number;
+ m_msg = (char*) message;
+ m_maxMsgLength = maxLength;
+
+ DBG("Get SMS");
+ //List command
+ char cmd[32];
+ std::sprintf(cmd, "AT+CMGR=%d", m_msgRefList[0]);
+ ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT);
+ if( ret != OK )
+ {
+ WARN("AT+CMGR returned %d", ret);
+ m_state = SMS_IDLE;
+ m_inboxMtx.unlock();
+ return NET_PROTOCOL;
+ }
+
+ if (m_state != SMS_CMD_PROCESSED)
+ {
+ WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'");
+ }
+
+ DBG("Deleting message from index number: %d", m_msgRefList[0] );
+ //Delete message from outbox
+ std::sprintf(cmd, "AT+CMGD=%d", m_msgRefList[0]);
+ ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT);
+ if(ret != OK)
+ {
+ ERR("Could not delete message");
+ }
+ //Remove message from list
+ std::memmove(&m_msgRefList[0], &m_msgRefList[1], MIN(m_msgRefListCount-1,MAX_SM-1)*sizeof(m_msgRefList[0]));
+ m_msgRefListCount--;
+
+ if(m_msgRefListCount > MAX_SM - 1) //Last message index is unknown, so put -1 to tell the lib to fetch it when needed
+ {
+ DBG("Last message index is unknown, will need to be updated");
+ m_msgRefList[MAX_SM - 1] = -1;
+ }
+
+ DBG("%d messages to read", m_msgRefListCount);
+
+ if (m_state != SMS_CMD_PROCESSED)
+ {
+ m_state = SMS_IDLE;
+ m_inboxMtx.unlock();
+ return NET_EMPTY;
+ }
+
+ m_state = SMS_IDLE;
+ m_inboxMtx.unlock();
+
+ return OK;
+}
+
+
+int GSMSMSInterface::getCount(size_t* pCount)
+{
+ int ret;
+
+ m_inboxMtx.lock();
+ if( m_needsUpdate )
+ {
+ ret = updateInbox();
+ if(ret)
+ {
+ m_inboxMtx.unlock();
+ return NET_PROTOCOL;
+ }
+ }
+
+ *pCount = m_msgRefListCount;
+ m_inboxMtx.unlock();
+
+ return OK;
+}
+
+
+/*virtual*/ int GSMSMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
+{
+ if(m_state == SMS_SEND_CMD_SENT)
+ {
+ if( std::sscanf(line, "+CMGS: %*d") == 0 )
+ {
+ DBG("SM sent");
+ m_state = SMS_CMD_PROCESSED;
+ }
+ }
+ else if(m_state == SMS_GET_CMD_SENT)
+ {
+ DBG("Header: %s", line);
+ if( std::sscanf(line, "+CMGR: %*[^,],\"%16[^\"]\"", m_msisdn) == 1 ) //Get message ref
+ {
+ m_state = SMS_GET_HDR_RECEIVED;
+ }
+ }
+ else if(m_state == SMS_GET_HDR_RECEIVED)
+ {
+ DBG("Message: %s", line);
+ size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 );
+ std::memcpy( m_msg, line, cpyLen );
+ m_msg[cpyLen] = '\0';
+ m_state = SMS_CMD_PROCESSED;
+ }
+ else if(m_state == SMS_GET_COUNT_CMD_SENT)
+ {
+ DBG("Header: %s", line);
+ int msgRef;
+ if( std::sscanf(line, "+CMGL: %d,\"REC", &msgRef) == 1 ) //Filter on REC READ and REC UNREAD messages
+ {
+ m_state = SMS_GET_COUNT_HDR_RECEIVED;
+ //Add message to list
+ if(m_msgRefListCount < MAX_SM)
+ {
+ m_msgRefList[m_msgRefListCount] = msgRef;
+ }
+ m_msgRefListCount++; //Always count message
+ DBG("m_msgRefListCount=%d",m_msgRefListCount);
+ }
+ }
+ else if(m_state == SMS_GET_COUNT_HDR_RECEIVED)
+ {
+ DBG("Message (debug only): %s", line); //For debug only
+ m_state = SMS_GET_COUNT_CMD_SENT;
+ }
+ return OK;
+}
+
+/*virtual*/ int GSMSMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst)
+{
+ if(m_state == SMS_SEND_CMD_SENT)
+ {
+ char* crPtr = strchr(m_msg, CR);
+ if(crPtr != NULL)
+ {
+ int crPos = crPtr - m_msg;
+ //Replace m_inputBuf[crPos] with null-terminating char
+ m_msg[crPos] = '\x0';
+
+ //If there is a CR char, split message there
+
+ //Do print the message
+ int ret = pInst->sendData(m_msg);
+ if(ret)
+ {
+ return ret;
+ }
+
+ char cr[2] = {CR, '\0'};
+ ret = pInst->sendData(cr);
+ if(ret)
+ {
+ return ret;
+ }
+
+ m_msg += crPos;
+
+ if(m_msg[0] == LF)
+ {
+ m_msg++; //Discard LF char as well
+ }
+
+ return NET_MOREINFO;
+ }
+ else
+ {
+ //Do print the message
+ pInst->sendData(m_msg);
+ return OK;
+ }
+ }
+
+ return OK;
+}
+
+/*virtual*/ bool GSMSMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled
+{
+ DBG("AT code is %s", atCode);
+ if( strcmp("+CMTI", atCode) == 0 )
+ {
+ return true;
+ }
+
+ DBG("Not handled");
+ return false;
+}
+
+/*virtual*/ void GSMSMSInterface::onDispatchStart()
+{
+
+}
+
+/*virtual*/ void GSMSMSInterface::onDispatchStop()
+{
+
+}
+
+/*virtual*/ char* GSMSMSInterface::getEventsEnableCommand()
+{
+ return "AT+CNMI=2,1,0,0,0";
+}
+
+/*virtual*/ char* GSMSMSInterface::getEventsDisableCommand()
+{
+ return "AT+CNMI=0,0,0,0,0"; //Indications will be buffered within the modem and flushed back when the former command is executed
+}
+
+/*virtual*/ void GSMSMSInterface::onEvent(const char* atCode, const char* evt)
+{
+ if( strcmp("+CMTI", atCode) != 0 )
+ {
+ return; //Not supported
+ }
+
+ DBG("Unsollicited result code: %s - %s", atCode, evt);
+
+ //Get index
+ int msgRef;
+ if(( std::sscanf(evt, "\"SM\",%d", &msgRef) == 1 ) ||
+ ( std::sscanf(evt, "\"ME\",%d", &msgRef) == 1 ))
+ {
+ DBG("Adding message to list (ref %d)", msgRef);
+ if(m_inboxMtx.trylock())
+ {
+ //Add message to list
+ if(m_msgRefListCount < MAX_SM)
+ {
+ m_msgRefList[m_msgRefListCount] = msgRef;
+ }
+ m_msgRefListCount++; //Always count message
+ m_inboxMtx.unlock();
+ }
+ else
+ {
+ WARN("Could not get lock");
+ m_needsUpdate = true;
+ }
+ }
+}
+
+int GSMSMSInterface::updateInbox()
+{
+ //Get memory indexes of unread messages
+
+ DBG("Updating inbox");
+ m_msgRefListCount = 0; //Reset list
+ m_needsUpdate = false; //Assume we won't need update after this routine (can be set to true by an incoming SM event)
+
+ //First list the "REC READ" messages that were not processed in the previous session
+ m_state = SMS_GET_COUNT_CMD_SENT;
+ int ret = m_pIf->execute("AT+CMGL=\"REC READ\"", this, NULL, DEFAULT_TIMEOUT);
+ if( ret != OK )
+ {
+ WARN("AT+CMGL returned %d", ret);
+ m_state = SMS_IDLE;
+ m_msgRefListCount = 0; //List could be invalid
+ m_needsUpdate = true;
+ return NET_PROTOCOL;
+ }
+
+ //Now list the "REC UNREAD" messages that were received by the modem since
+ m_state = SMS_GET_COUNT_CMD_SENT;
+ ret = m_pIf->execute("AT+CMGL=\"REC UNREAD\"", this, NULL, DEFAULT_TIMEOUT);
+ if( ret != OK )
+ {
+ WARN("AT+CMGL returned %d", ret);
+ m_state = SMS_IDLE;
+ m_msgRefListCount = 0; //List could be invalid
+ m_needsUpdate = true;
+ return NET_PROTOCOL;
+ }
+
+ DBG("%d incoming messages in inbox", m_msgRefListCount);
+
+ m_state = SMS_IDLE;
+
+ return OK;
+}
+
+
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.h
new file mode 100644
index 000000000..446a73e51
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/GSMSMSInterface.h
@@ -0,0 +1,97 @@
+/* SMSInterface.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GSMSMSINTERFACE_H_
+#define GSMSMSINTERFACE_H_
+
+#include "SMSInterface.h"
+
+/** Component to use the Short Messages Service (SMS)
+ *
+ */
+class GSMSMSInterface : public ISMSInterface, protected IATCommandsProcessor, IATEventsHandler
+{
+public:
+ /** Create SMSInterface instance
+ @param pIf Pointer to the ATCommandsInterface instance to use
+ */
+ GSMSMSInterface(ATCommandsInterface* pIf);
+
+ /** Initialize interface
+ Configure SMS commands & register for SMS-related unsolicited result codes
+ */
+ virtual int init();
+
+ /** Send a SM
+ @param number The receiver's phone number
+ @param message The message to send
+ @return 0 on success, error code on failure
+ */
+ virtual int send(const char* number, const char* message);
+
+
+ /** Receive a SM
+ @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the space for the null-terminating char)
+ @param message Pointer to a buffer to store the the incoming message
+ @param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
+ @return 0 on success, error code on failure
+ */
+ virtual int get(char* number, char* message, size_t maxLength);
+
+
+ /** Get the number of SMs in the incoming box
+ @param pCount pointer to store the number of unprocessed SMs on
+ @return 0 on success, error code on failure
+ */
+ virtual int getCount(size_t* pCount);
+
+protected:
+ //IATCommandsProcessor
+ virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line);
+ virtual int onNewEntryPrompt(ATCommandsInterface* pInst);
+
+ //IATEventsHandler
+ virtual bool isATCodeHandled(const char* atCode); //Is this AT code handled
+ virtual void onDispatchStart();
+ virtual void onDispatchStop();
+ virtual char* getEventsEnableCommand();
+ virtual char* getEventsDisableCommand();
+ virtual void onEvent(const char* atCode, const char* evt);
+
+ //Updates messages count/references
+ int updateInbox();
+
+private:
+ ATCommandsInterface* m_pIf;
+
+ //Current message
+ char* m_msg;
+ size_t m_maxMsgLength;
+ char* m_msisdn;
+
+ //Messages list
+ int m_msgRefList[MAX_SM];
+ size_t m_msgRefListCount;
+ bool m_needsUpdate;
+ Mutex m_inboxMtx; //To protect concurrent accesses btw the user's thread and the AT thread
+
+ enum { SMS_IDLE, SMS_SEND_CMD_SENT, SMS_GET_CMD_SENT, SMS_GET_HDR_RECEIVED, SMS_GET_COUNT_CMD_SENT, SMS_GET_COUNT_HDR_RECEIVED, SMS_CMD_PROCESSED } m_state;
+};
+
+#endif /* GSMSMSINTERFACE_H_ */
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/SMSInterface.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/SMSInterface.h
new file mode 100644
index 000000000..df226709d
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/sms/SMSInterface.h
@@ -0,0 +1,67 @@
+/* SMSInterface.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ISMSINTERFACE_H_
+#define ISMSINTERFACE_H_
+
+#include "core/fwk.h"
+
+#include "rtos.h"
+
+#include "at/ATCommandsInterface.h"
+
+#define MAX_SM 8
+
+/** Component to use the Short Messages Service (SMS)
+ *
+ */
+class ISMSInterface
+{
+public:
+ /** Initialize interface
+ Configure SMS commands & register for SMS-related unsolicited result codes
+ */
+ virtual int init() = 0;
+
+
+ /** Send a SM
+ @param number The receiver's phone number
+ @param message The message to send
+ @return 0 on success, error code on failure
+ */
+ virtual int send(const char* number, const char* message) = 0;
+
+
+ /** Receive a SM
+ @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the space for the null-terminating char)
+ @param message Pointer to a buffer to store the the incoming message
+ @param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
+ @return 0 on success, error code on failure
+ */
+ virtual int get(char* number, char* message, size_t maxLength) = 0;
+
+
+ /** Get the number of SMs in the incoming box
+ @param pCount pointer to store the number of unprocessed SMs on
+ @return 0 on success, error code on failure
+ */
+ virtual int getCount(size_t* pCount) = 0;
+};
+
+#endif /* ISMSINTERFACE_H_ */