Base library for cellular modem implementations
Dependencies: Socket lwip-sys lwip
Dependents: CellularUSBModem CellularUSBModem
Deprecated
This is an mbed 2 networking library. For mbed 5, the networking libraries have been revised to better support additional network stacks and thread safety here.
sms/GSMSMSInterface.cpp@8:944cd194963e, 2014-05-08 (annotated)
- Committer:
- mbed_official
- Date:
- Thu May 08 11:00:26 2014 +0100
- Revision:
- 8:944cd194963e
- Parent:
- 1:4a23efdf0da9
Synchronized with git revision df12bf01ac7dbb50751e2b16a351c894994e1dcf
Full URL: https://github.com/mbedmicro/mbed/commit/df12bf01ac7dbb50751e2b16a351c894994e1dcf/
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bogdanm | 1:4a23efdf0da9 | 1 | /* GSMSMSInterface.cpp */ |
bogdanm | 1:4a23efdf0da9 | 2 | /* Copyright (C) 2012 mbed.org, MIT License |
bogdanm | 1:4a23efdf0da9 | 3 | * |
bogdanm | 1:4a23efdf0da9 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
bogdanm | 1:4a23efdf0da9 | 5 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
bogdanm | 1:4a23efdf0da9 | 6 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
bogdanm | 1:4a23efdf0da9 | 7 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
bogdanm | 1:4a23efdf0da9 | 8 | * furnished to do so, subject to the following conditions: |
bogdanm | 1:4a23efdf0da9 | 9 | * |
bogdanm | 1:4a23efdf0da9 | 10 | * The above copyright notice and this permission notice shall be included in all copies or |
bogdanm | 1:4a23efdf0da9 | 11 | * substantial portions of the Software. |
bogdanm | 1:4a23efdf0da9 | 12 | * |
bogdanm | 1:4a23efdf0da9 | 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
bogdanm | 1:4a23efdf0da9 | 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
bogdanm | 1:4a23efdf0da9 | 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
bogdanm | 1:4a23efdf0da9 | 16 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
bogdanm | 1:4a23efdf0da9 | 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
bogdanm | 1:4a23efdf0da9 | 18 | */ |
bogdanm | 1:4a23efdf0da9 | 19 | |
bogdanm | 1:4a23efdf0da9 | 20 | #define __DEBUG__ 2 |
bogdanm | 1:4a23efdf0da9 | 21 | #ifndef __MODULE__ |
bogdanm | 1:4a23efdf0da9 | 22 | #define __MODULE__ "GSMSMSInterface.cpp" |
bogdanm | 1:4a23efdf0da9 | 23 | #endif |
bogdanm | 1:4a23efdf0da9 | 24 | |
bogdanm | 1:4a23efdf0da9 | 25 | #include "core/fwk.h" |
bogdanm | 1:4a23efdf0da9 | 26 | |
bogdanm | 1:4a23efdf0da9 | 27 | #include "GSMSMSInterface.h" |
bogdanm | 1:4a23efdf0da9 | 28 | |
bogdanm | 1:4a23efdf0da9 | 29 | #include <cstdio> |
bogdanm | 1:4a23efdf0da9 | 30 | #include <cstring> |
bogdanm | 1:4a23efdf0da9 | 31 | |
bogdanm | 1:4a23efdf0da9 | 32 | #define DEFAULT_TIMEOUT 10000 |
bogdanm | 1:4a23efdf0da9 | 33 | |
bogdanm | 1:4a23efdf0da9 | 34 | GSMSMSInterface::GSMSMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL) |
bogdanm | 1:4a23efdf0da9 | 35 | { |
bogdanm | 1:4a23efdf0da9 | 36 | m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers |
bogdanm | 1:4a23efdf0da9 | 37 | } |
bogdanm | 1:4a23efdf0da9 | 38 | |
bogdanm | 1:4a23efdf0da9 | 39 | int GSMSMSInterface::init() |
bogdanm | 1:4a23efdf0da9 | 40 | { |
bogdanm | 1:4a23efdf0da9 | 41 | m_msgRefListCount = 0; |
bogdanm | 1:4a23efdf0da9 | 42 | m_needsUpdate = true; |
bogdanm | 1:4a23efdf0da9 | 43 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 44 | |
bogdanm | 1:4a23efdf0da9 | 45 | DBG("Set format"); |
bogdanm | 1:4a23efdf0da9 | 46 | //Set Text mode format |
bogdanm | 1:4a23efdf0da9 | 47 | int ret = m_pIf->executeSimple("AT+CMGF=1", NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 48 | if(ret != OK) |
bogdanm | 1:4a23efdf0da9 | 49 | { |
bogdanm | 1:4a23efdf0da9 | 50 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 51 | } |
bogdanm | 1:4a23efdf0da9 | 52 | |
bogdanm | 1:4a23efdf0da9 | 53 | DBG("Setup new messages indication"); |
bogdanm | 1:4a23efdf0da9 | 54 | //Setup new messages indication |
bogdanm | 1:4a23efdf0da9 | 55 | ret = m_pIf->executeSimple("AT+CNMI=2,1,0,0,0", NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 56 | if(ret != OK) |
bogdanm | 1:4a23efdf0da9 | 57 | { |
bogdanm | 1:4a23efdf0da9 | 58 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 59 | } |
bogdanm | 1:4a23efdf0da9 | 60 | |
bogdanm | 1:4a23efdf0da9 | 61 | DBG("Try to fetch inbox"); |
bogdanm | 1:4a23efdf0da9 | 62 | m_inboxMtx.lock(); |
bogdanm | 1:4a23efdf0da9 | 63 | if( m_needsUpdate ) |
bogdanm | 1:4a23efdf0da9 | 64 | { |
bogdanm | 1:4a23efdf0da9 | 65 | ret = updateInbox(); //Fetch existing messages references |
bogdanm | 1:4a23efdf0da9 | 66 | if(ret) |
bogdanm | 1:4a23efdf0da9 | 67 | { |
bogdanm | 1:4a23efdf0da9 | 68 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 69 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 70 | } |
bogdanm | 1:4a23efdf0da9 | 71 | } |
bogdanm | 1:4a23efdf0da9 | 72 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 73 | |
bogdanm | 1:4a23efdf0da9 | 74 | DBG("Initialization done"); |
bogdanm | 1:4a23efdf0da9 | 75 | return OK; |
bogdanm | 1:4a23efdf0da9 | 76 | } |
bogdanm | 1:4a23efdf0da9 | 77 | |
bogdanm | 1:4a23efdf0da9 | 78 | int GSMSMSInterface::send(const char* number, const char* message) |
bogdanm | 1:4a23efdf0da9 | 79 | { |
bogdanm | 1:4a23efdf0da9 | 80 | if( strlen(number) > 16 ) |
bogdanm | 1:4a23efdf0da9 | 81 | { |
bogdanm | 1:4a23efdf0da9 | 82 | return NET_INVALID; //Number too long to match 3GPP spec |
bogdanm | 1:4a23efdf0da9 | 83 | } |
bogdanm | 1:4a23efdf0da9 | 84 | |
bogdanm | 1:4a23efdf0da9 | 85 | int ret; |
bogdanm | 1:4a23efdf0da9 | 86 | |
bogdanm | 1:4a23efdf0da9 | 87 | //Prepare infos |
bogdanm | 1:4a23efdf0da9 | 88 | m_state = SMS_SEND_CMD_SENT; |
bogdanm | 1:4a23efdf0da9 | 89 | m_msg = (char*) message; |
bogdanm | 1:4a23efdf0da9 | 90 | |
bogdanm | 1:4a23efdf0da9 | 91 | DBG("Send SM"); |
bogdanm | 1:4a23efdf0da9 | 92 | //Send command |
bogdanm | 1:4a23efdf0da9 | 93 | char cmd[32]; |
bogdanm | 1:4a23efdf0da9 | 94 | std::sprintf(cmd, "AT+CMGS=\"%s\"", number); |
bogdanm | 1:4a23efdf0da9 | 95 | ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 96 | |
bogdanm | 1:4a23efdf0da9 | 97 | if( (ret != OK) || (m_state != SMS_CMD_PROCESSED) ) |
bogdanm | 1:4a23efdf0da9 | 98 | { |
bogdanm | 1:4a23efdf0da9 | 99 | WARN("ret %d, state %d", ret, m_state); |
bogdanm | 1:4a23efdf0da9 | 100 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 101 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 102 | } |
bogdanm | 1:4a23efdf0da9 | 103 | |
bogdanm | 1:4a23efdf0da9 | 104 | DBG("SM sent"); |
bogdanm | 1:4a23efdf0da9 | 105 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 106 | return OK; |
bogdanm | 1:4a23efdf0da9 | 107 | } |
bogdanm | 1:4a23efdf0da9 | 108 | |
bogdanm | 1:4a23efdf0da9 | 109 | |
bogdanm | 1:4a23efdf0da9 | 110 | int GSMSMSInterface::get(char* number, char* message, size_t maxLength) |
bogdanm | 1:4a23efdf0da9 | 111 | { |
bogdanm | 1:4a23efdf0da9 | 112 | if( maxLength < 1 ) |
bogdanm | 1:4a23efdf0da9 | 113 | { |
bogdanm | 1:4a23efdf0da9 | 114 | return NET_INVALID; //Buffer too short |
bogdanm | 1:4a23efdf0da9 | 115 | } |
bogdanm | 1:4a23efdf0da9 | 116 | |
bogdanm | 1:4a23efdf0da9 | 117 | int ret; |
bogdanm | 1:4a23efdf0da9 | 118 | |
bogdanm | 1:4a23efdf0da9 | 119 | DBG("Get next message"); |
bogdanm | 1:4a23efdf0da9 | 120 | m_inboxMtx.lock(); |
bogdanm | 1:4a23efdf0da9 | 121 | if( ((m_msgRefListCount == 0) && m_needsUpdate) || ((m_msgRefListCount > 0) && (m_msgRefList[0] == -1)) ) |
bogdanm | 1:4a23efdf0da9 | 122 | { |
bogdanm | 1:4a23efdf0da9 | 123 | DBG("Message list count is 0 and needs updating or next index is unknown, calling updateInbox()"); |
bogdanm | 1:4a23efdf0da9 | 124 | ret = updateInbox(); |
bogdanm | 1:4a23efdf0da9 | 125 | |
bogdanm | 1:4a23efdf0da9 | 126 | if (ret) |
bogdanm | 1:4a23efdf0da9 | 127 | { |
bogdanm | 1:4a23efdf0da9 | 128 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 129 | return ret; |
bogdanm | 1:4a23efdf0da9 | 130 | } |
bogdanm | 1:4a23efdf0da9 | 131 | } |
bogdanm | 1:4a23efdf0da9 | 132 | |
bogdanm | 1:4a23efdf0da9 | 133 | DBG("%d messages to read", m_msgRefListCount); |
bogdanm | 1:4a23efdf0da9 | 134 | |
bogdanm | 1:4a23efdf0da9 | 135 | if(m_msgRefListCount == 0) |
bogdanm | 1:4a23efdf0da9 | 136 | { |
bogdanm | 1:4a23efdf0da9 | 137 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 138 | DBG("Message list count is 0, I think it's empty and returning."); |
bogdanm | 1:4a23efdf0da9 | 139 | return NET_EMPTY; //No message to read |
bogdanm | 1:4a23efdf0da9 | 140 | } |
bogdanm | 1:4a23efdf0da9 | 141 | |
bogdanm | 1:4a23efdf0da9 | 142 | //Prepare infos |
bogdanm | 1:4a23efdf0da9 | 143 | m_state = SMS_GET_CMD_SENT; |
bogdanm | 1:4a23efdf0da9 | 144 | m_msisdn = (char*) number; |
bogdanm | 1:4a23efdf0da9 | 145 | m_msg = (char*) message; |
bogdanm | 1:4a23efdf0da9 | 146 | m_maxMsgLength = maxLength; |
bogdanm | 1:4a23efdf0da9 | 147 | |
bogdanm | 1:4a23efdf0da9 | 148 | DBG("Get SMS"); |
bogdanm | 1:4a23efdf0da9 | 149 | //List command |
bogdanm | 1:4a23efdf0da9 | 150 | char cmd[32]; |
bogdanm | 1:4a23efdf0da9 | 151 | std::sprintf(cmd, "AT+CMGR=%d", m_msgRefList[0]); |
bogdanm | 1:4a23efdf0da9 | 152 | ret = m_pIf->execute(cmd, this, NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 153 | if( ret != OK ) |
bogdanm | 1:4a23efdf0da9 | 154 | { |
bogdanm | 1:4a23efdf0da9 | 155 | WARN("AT+CMGR returned %d", ret); |
bogdanm | 1:4a23efdf0da9 | 156 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 157 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 158 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 159 | } |
bogdanm | 1:4a23efdf0da9 | 160 | |
bogdanm | 1:4a23efdf0da9 | 161 | if (m_state != SMS_CMD_PROCESSED) |
bogdanm | 1:4a23efdf0da9 | 162 | { |
bogdanm | 1:4a23efdf0da9 | 163 | WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'"); |
bogdanm | 1:4a23efdf0da9 | 164 | } |
bogdanm | 1:4a23efdf0da9 | 165 | |
bogdanm | 1:4a23efdf0da9 | 166 | DBG("Deleting message from index number: %d", m_msgRefList[0] ); |
bogdanm | 1:4a23efdf0da9 | 167 | //Delete message from outbox |
bogdanm | 1:4a23efdf0da9 | 168 | std::sprintf(cmd, "AT+CMGD=%d", m_msgRefList[0]); |
bogdanm | 1:4a23efdf0da9 | 169 | ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 170 | if(ret != OK) |
bogdanm | 1:4a23efdf0da9 | 171 | { |
bogdanm | 1:4a23efdf0da9 | 172 | ERR("Could not delete message"); |
bogdanm | 1:4a23efdf0da9 | 173 | } |
bogdanm | 1:4a23efdf0da9 | 174 | //Remove message from list |
bogdanm | 1:4a23efdf0da9 | 175 | std::memmove(&m_msgRefList[0], &m_msgRefList[1], MIN(m_msgRefListCount-1,MAX_SM-1)*sizeof(m_msgRefList[0])); |
bogdanm | 1:4a23efdf0da9 | 176 | m_msgRefListCount--; |
bogdanm | 1:4a23efdf0da9 | 177 | |
bogdanm | 1:4a23efdf0da9 | 178 | if(m_msgRefListCount > MAX_SM - 1) //Last message index is unknown, so put -1 to tell the lib to fetch it when needed |
bogdanm | 1:4a23efdf0da9 | 179 | { |
bogdanm | 1:4a23efdf0da9 | 180 | DBG("Last message index is unknown, will need to be updated"); |
bogdanm | 1:4a23efdf0da9 | 181 | m_msgRefList[MAX_SM - 1] = -1; |
bogdanm | 1:4a23efdf0da9 | 182 | } |
bogdanm | 1:4a23efdf0da9 | 183 | |
bogdanm | 1:4a23efdf0da9 | 184 | DBG("%d messages to read", m_msgRefListCount); |
bogdanm | 1:4a23efdf0da9 | 185 | |
bogdanm | 1:4a23efdf0da9 | 186 | if (m_state != SMS_CMD_PROCESSED) |
bogdanm | 1:4a23efdf0da9 | 187 | { |
bogdanm | 1:4a23efdf0da9 | 188 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 189 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 190 | return NET_EMPTY; |
bogdanm | 1:4a23efdf0da9 | 191 | } |
bogdanm | 1:4a23efdf0da9 | 192 | |
bogdanm | 1:4a23efdf0da9 | 193 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 194 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 195 | |
bogdanm | 1:4a23efdf0da9 | 196 | return OK; |
bogdanm | 1:4a23efdf0da9 | 197 | } |
bogdanm | 1:4a23efdf0da9 | 198 | |
bogdanm | 1:4a23efdf0da9 | 199 | |
bogdanm | 1:4a23efdf0da9 | 200 | int GSMSMSInterface::getCount(size_t* pCount) |
bogdanm | 1:4a23efdf0da9 | 201 | { |
bogdanm | 1:4a23efdf0da9 | 202 | int ret; |
bogdanm | 1:4a23efdf0da9 | 203 | |
bogdanm | 1:4a23efdf0da9 | 204 | m_inboxMtx.lock(); |
bogdanm | 1:4a23efdf0da9 | 205 | if( m_needsUpdate ) |
bogdanm | 1:4a23efdf0da9 | 206 | { |
bogdanm | 1:4a23efdf0da9 | 207 | ret = updateInbox(); |
bogdanm | 1:4a23efdf0da9 | 208 | if(ret) |
bogdanm | 1:4a23efdf0da9 | 209 | { |
bogdanm | 1:4a23efdf0da9 | 210 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 211 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 212 | } |
bogdanm | 1:4a23efdf0da9 | 213 | } |
bogdanm | 1:4a23efdf0da9 | 214 | |
bogdanm | 1:4a23efdf0da9 | 215 | *pCount = m_msgRefListCount; |
bogdanm | 1:4a23efdf0da9 | 216 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 217 | |
bogdanm | 1:4a23efdf0da9 | 218 | return OK; |
bogdanm | 1:4a23efdf0da9 | 219 | } |
bogdanm | 1:4a23efdf0da9 | 220 | |
bogdanm | 1:4a23efdf0da9 | 221 | |
bogdanm | 1:4a23efdf0da9 | 222 | /*virtual*/ int GSMSMSInterface::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) |
bogdanm | 1:4a23efdf0da9 | 223 | { |
bogdanm | 1:4a23efdf0da9 | 224 | if(m_state == SMS_SEND_CMD_SENT) |
bogdanm | 1:4a23efdf0da9 | 225 | { |
bogdanm | 1:4a23efdf0da9 | 226 | if( std::sscanf(line, "+CMGS: %*d") == 0 ) |
bogdanm | 1:4a23efdf0da9 | 227 | { |
bogdanm | 1:4a23efdf0da9 | 228 | DBG("SM sent"); |
bogdanm | 1:4a23efdf0da9 | 229 | m_state = SMS_CMD_PROCESSED; |
bogdanm | 1:4a23efdf0da9 | 230 | } |
bogdanm | 1:4a23efdf0da9 | 231 | } |
bogdanm | 1:4a23efdf0da9 | 232 | else if(m_state == SMS_GET_CMD_SENT) |
bogdanm | 1:4a23efdf0da9 | 233 | { |
bogdanm | 1:4a23efdf0da9 | 234 | DBG("Header: %s", line); |
bogdanm | 1:4a23efdf0da9 | 235 | if( std::sscanf(line, "+CMGR: %*[^,],\"%16[^\"]\"", m_msisdn) == 1 ) //Get message ref |
bogdanm | 1:4a23efdf0da9 | 236 | { |
bogdanm | 1:4a23efdf0da9 | 237 | m_state = SMS_GET_HDR_RECEIVED; |
bogdanm | 1:4a23efdf0da9 | 238 | } |
bogdanm | 1:4a23efdf0da9 | 239 | } |
bogdanm | 1:4a23efdf0da9 | 240 | else if(m_state == SMS_GET_HDR_RECEIVED) |
bogdanm | 1:4a23efdf0da9 | 241 | { |
bogdanm | 1:4a23efdf0da9 | 242 | DBG("Message: %s", line); |
bogdanm | 1:4a23efdf0da9 | 243 | size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 ); |
bogdanm | 1:4a23efdf0da9 | 244 | std::memcpy( m_msg, line, cpyLen ); |
bogdanm | 1:4a23efdf0da9 | 245 | m_msg[cpyLen] = '\0'; |
bogdanm | 1:4a23efdf0da9 | 246 | m_state = SMS_CMD_PROCESSED; |
bogdanm | 1:4a23efdf0da9 | 247 | } |
bogdanm | 1:4a23efdf0da9 | 248 | else if(m_state == SMS_GET_COUNT_CMD_SENT) |
bogdanm | 1:4a23efdf0da9 | 249 | { |
bogdanm | 1:4a23efdf0da9 | 250 | DBG("Header: %s", line); |
bogdanm | 1:4a23efdf0da9 | 251 | int msgRef; |
bogdanm | 1:4a23efdf0da9 | 252 | if( std::sscanf(line, "+CMGL: %d,\"REC", &msgRef) == 1 ) //Filter on REC READ and REC UNREAD messages |
bogdanm | 1:4a23efdf0da9 | 253 | { |
bogdanm | 1:4a23efdf0da9 | 254 | m_state = SMS_GET_COUNT_HDR_RECEIVED; |
bogdanm | 1:4a23efdf0da9 | 255 | //Add message to list |
bogdanm | 1:4a23efdf0da9 | 256 | if(m_msgRefListCount < MAX_SM) |
bogdanm | 1:4a23efdf0da9 | 257 | { |
bogdanm | 1:4a23efdf0da9 | 258 | m_msgRefList[m_msgRefListCount] = msgRef; |
bogdanm | 1:4a23efdf0da9 | 259 | } |
bogdanm | 1:4a23efdf0da9 | 260 | m_msgRefListCount++; //Always count message |
bogdanm | 1:4a23efdf0da9 | 261 | DBG("m_msgRefListCount=%d",m_msgRefListCount); |
bogdanm | 1:4a23efdf0da9 | 262 | } |
bogdanm | 1:4a23efdf0da9 | 263 | } |
bogdanm | 1:4a23efdf0da9 | 264 | else if(m_state == SMS_GET_COUNT_HDR_RECEIVED) |
bogdanm | 1:4a23efdf0da9 | 265 | { |
bogdanm | 1:4a23efdf0da9 | 266 | DBG("Message (debug only): %s", line); //For debug only |
bogdanm | 1:4a23efdf0da9 | 267 | m_state = SMS_GET_COUNT_CMD_SENT; |
bogdanm | 1:4a23efdf0da9 | 268 | } |
bogdanm | 1:4a23efdf0da9 | 269 | return OK; |
bogdanm | 1:4a23efdf0da9 | 270 | } |
bogdanm | 1:4a23efdf0da9 | 271 | |
bogdanm | 1:4a23efdf0da9 | 272 | /*virtual*/ int GSMSMSInterface::onNewEntryPrompt(ATCommandsInterface* pInst) |
bogdanm | 1:4a23efdf0da9 | 273 | { |
bogdanm | 1:4a23efdf0da9 | 274 | if(m_state == SMS_SEND_CMD_SENT) |
bogdanm | 1:4a23efdf0da9 | 275 | { |
bogdanm | 1:4a23efdf0da9 | 276 | char* crPtr = strchr(m_msg, CR); |
bogdanm | 1:4a23efdf0da9 | 277 | if(crPtr != NULL) |
bogdanm | 1:4a23efdf0da9 | 278 | { |
bogdanm | 1:4a23efdf0da9 | 279 | int crPos = crPtr - m_msg; |
bogdanm | 1:4a23efdf0da9 | 280 | //Replace m_inputBuf[crPos] with null-terminating char |
bogdanm | 1:4a23efdf0da9 | 281 | m_msg[crPos] = '\x0'; |
bogdanm | 1:4a23efdf0da9 | 282 | |
bogdanm | 1:4a23efdf0da9 | 283 | //If there is a CR char, split message there |
bogdanm | 1:4a23efdf0da9 | 284 | |
bogdanm | 1:4a23efdf0da9 | 285 | //Do print the message |
bogdanm | 1:4a23efdf0da9 | 286 | int ret = pInst->sendData(m_msg); |
bogdanm | 1:4a23efdf0da9 | 287 | if(ret) |
bogdanm | 1:4a23efdf0da9 | 288 | { |
bogdanm | 1:4a23efdf0da9 | 289 | return ret; |
bogdanm | 1:4a23efdf0da9 | 290 | } |
bogdanm | 1:4a23efdf0da9 | 291 | |
bogdanm | 1:4a23efdf0da9 | 292 | char cr[2] = {CR, '\0'}; |
bogdanm | 1:4a23efdf0da9 | 293 | ret = pInst->sendData(cr); |
bogdanm | 1:4a23efdf0da9 | 294 | if(ret) |
bogdanm | 1:4a23efdf0da9 | 295 | { |
bogdanm | 1:4a23efdf0da9 | 296 | return ret; |
bogdanm | 1:4a23efdf0da9 | 297 | } |
bogdanm | 1:4a23efdf0da9 | 298 | |
bogdanm | 1:4a23efdf0da9 | 299 | m_msg += crPos; |
bogdanm | 1:4a23efdf0da9 | 300 | |
bogdanm | 1:4a23efdf0da9 | 301 | if(m_msg[0] == LF) |
bogdanm | 1:4a23efdf0da9 | 302 | { |
bogdanm | 1:4a23efdf0da9 | 303 | m_msg++; //Discard LF char as well |
bogdanm | 1:4a23efdf0da9 | 304 | } |
bogdanm | 1:4a23efdf0da9 | 305 | |
bogdanm | 1:4a23efdf0da9 | 306 | return NET_MOREINFO; |
bogdanm | 1:4a23efdf0da9 | 307 | } |
bogdanm | 1:4a23efdf0da9 | 308 | else |
bogdanm | 1:4a23efdf0da9 | 309 | { |
bogdanm | 1:4a23efdf0da9 | 310 | //Do print the message |
bogdanm | 1:4a23efdf0da9 | 311 | pInst->sendData(m_msg); |
bogdanm | 1:4a23efdf0da9 | 312 | return OK; |
bogdanm | 1:4a23efdf0da9 | 313 | } |
bogdanm | 1:4a23efdf0da9 | 314 | } |
bogdanm | 1:4a23efdf0da9 | 315 | |
bogdanm | 1:4a23efdf0da9 | 316 | return OK; |
bogdanm | 1:4a23efdf0da9 | 317 | } |
bogdanm | 1:4a23efdf0da9 | 318 | |
bogdanm | 1:4a23efdf0da9 | 319 | /*virtual*/ bool GSMSMSInterface::isATCodeHandled(const char* atCode) //Is this AT code handled |
bogdanm | 1:4a23efdf0da9 | 320 | { |
bogdanm | 1:4a23efdf0da9 | 321 | DBG("AT code is %s", atCode); |
bogdanm | 1:4a23efdf0da9 | 322 | if( strcmp("+CMTI", atCode) == 0 ) |
bogdanm | 1:4a23efdf0da9 | 323 | { |
bogdanm | 1:4a23efdf0da9 | 324 | return true; |
bogdanm | 1:4a23efdf0da9 | 325 | } |
bogdanm | 1:4a23efdf0da9 | 326 | |
bogdanm | 1:4a23efdf0da9 | 327 | DBG("Not handled"); |
bogdanm | 1:4a23efdf0da9 | 328 | return false; |
bogdanm | 1:4a23efdf0da9 | 329 | } |
bogdanm | 1:4a23efdf0da9 | 330 | |
bogdanm | 1:4a23efdf0da9 | 331 | /*virtual*/ void GSMSMSInterface::onDispatchStart() |
bogdanm | 1:4a23efdf0da9 | 332 | { |
bogdanm | 1:4a23efdf0da9 | 333 | |
bogdanm | 1:4a23efdf0da9 | 334 | } |
bogdanm | 1:4a23efdf0da9 | 335 | |
bogdanm | 1:4a23efdf0da9 | 336 | /*virtual*/ void GSMSMSInterface::onDispatchStop() |
bogdanm | 1:4a23efdf0da9 | 337 | { |
bogdanm | 1:4a23efdf0da9 | 338 | |
bogdanm | 1:4a23efdf0da9 | 339 | } |
bogdanm | 1:4a23efdf0da9 | 340 | |
bogdanm | 1:4a23efdf0da9 | 341 | /*virtual*/ char* GSMSMSInterface::getEventsEnableCommand() |
bogdanm | 1:4a23efdf0da9 | 342 | { |
bogdanm | 1:4a23efdf0da9 | 343 | return "AT+CNMI=2,1,0,0,0"; |
bogdanm | 1:4a23efdf0da9 | 344 | } |
bogdanm | 1:4a23efdf0da9 | 345 | |
bogdanm | 1:4a23efdf0da9 | 346 | /*virtual*/ char* GSMSMSInterface::getEventsDisableCommand() |
bogdanm | 1:4a23efdf0da9 | 347 | { |
bogdanm | 1:4a23efdf0da9 | 348 | return "AT+CNMI=0,0,0,0,0"; //Indications will be buffered within the modem and flushed back when the former command is executed |
bogdanm | 1:4a23efdf0da9 | 349 | } |
bogdanm | 1:4a23efdf0da9 | 350 | |
bogdanm | 1:4a23efdf0da9 | 351 | /*virtual*/ void GSMSMSInterface::onEvent(const char* atCode, const char* evt) |
bogdanm | 1:4a23efdf0da9 | 352 | { |
bogdanm | 1:4a23efdf0da9 | 353 | if( strcmp("+CMTI", atCode) != 0 ) |
bogdanm | 1:4a23efdf0da9 | 354 | { |
bogdanm | 1:4a23efdf0da9 | 355 | return; //Not supported |
bogdanm | 1:4a23efdf0da9 | 356 | } |
bogdanm | 1:4a23efdf0da9 | 357 | |
bogdanm | 1:4a23efdf0da9 | 358 | DBG("Unsollicited result code: %s - %s", atCode, evt); |
bogdanm | 1:4a23efdf0da9 | 359 | |
bogdanm | 1:4a23efdf0da9 | 360 | //Get index |
bogdanm | 1:4a23efdf0da9 | 361 | int msgRef; |
bogdanm | 1:4a23efdf0da9 | 362 | if(( std::sscanf(evt, "\"SM\",%d", &msgRef) == 1 ) || |
bogdanm | 1:4a23efdf0da9 | 363 | ( std::sscanf(evt, "\"ME\",%d", &msgRef) == 1 )) |
bogdanm | 1:4a23efdf0da9 | 364 | { |
bogdanm | 1:4a23efdf0da9 | 365 | DBG("Adding message to list (ref %d)", msgRef); |
bogdanm | 1:4a23efdf0da9 | 366 | if(m_inboxMtx.trylock()) |
bogdanm | 1:4a23efdf0da9 | 367 | { |
bogdanm | 1:4a23efdf0da9 | 368 | //Add message to list |
bogdanm | 1:4a23efdf0da9 | 369 | if(m_msgRefListCount < MAX_SM) |
bogdanm | 1:4a23efdf0da9 | 370 | { |
bogdanm | 1:4a23efdf0da9 | 371 | m_msgRefList[m_msgRefListCount] = msgRef; |
bogdanm | 1:4a23efdf0da9 | 372 | } |
bogdanm | 1:4a23efdf0da9 | 373 | m_msgRefListCount++; //Always count message |
bogdanm | 1:4a23efdf0da9 | 374 | m_inboxMtx.unlock(); |
bogdanm | 1:4a23efdf0da9 | 375 | } |
bogdanm | 1:4a23efdf0da9 | 376 | else |
bogdanm | 1:4a23efdf0da9 | 377 | { |
bogdanm | 1:4a23efdf0da9 | 378 | WARN("Could not get lock"); |
bogdanm | 1:4a23efdf0da9 | 379 | m_needsUpdate = true; |
bogdanm | 1:4a23efdf0da9 | 380 | } |
bogdanm | 1:4a23efdf0da9 | 381 | } |
bogdanm | 1:4a23efdf0da9 | 382 | } |
bogdanm | 1:4a23efdf0da9 | 383 | |
bogdanm | 1:4a23efdf0da9 | 384 | int GSMSMSInterface::updateInbox() |
bogdanm | 1:4a23efdf0da9 | 385 | { |
bogdanm | 1:4a23efdf0da9 | 386 | //Get memory indexes of unread messages |
bogdanm | 1:4a23efdf0da9 | 387 | |
bogdanm | 1:4a23efdf0da9 | 388 | DBG("Updating inbox"); |
bogdanm | 1:4a23efdf0da9 | 389 | m_msgRefListCount = 0; //Reset list |
bogdanm | 1:4a23efdf0da9 | 390 | m_needsUpdate = false; //Assume we won't need update after this routine (can be set to true by an incoming SM event) |
bogdanm | 1:4a23efdf0da9 | 391 | |
bogdanm | 1:4a23efdf0da9 | 392 | //First list the "REC READ" messages that were not processed in the previous session |
bogdanm | 1:4a23efdf0da9 | 393 | m_state = SMS_GET_COUNT_CMD_SENT; |
bogdanm | 1:4a23efdf0da9 | 394 | int ret = m_pIf->execute("AT+CMGL=\"REC READ\"", this, NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 395 | if( ret != OK ) |
bogdanm | 1:4a23efdf0da9 | 396 | { |
bogdanm | 1:4a23efdf0da9 | 397 | WARN("AT+CMGL returned %d", ret); |
bogdanm | 1:4a23efdf0da9 | 398 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 399 | m_msgRefListCount = 0; //List could be invalid |
bogdanm | 1:4a23efdf0da9 | 400 | m_needsUpdate = true; |
bogdanm | 1:4a23efdf0da9 | 401 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 402 | } |
bogdanm | 1:4a23efdf0da9 | 403 | |
bogdanm | 1:4a23efdf0da9 | 404 | //Now list the "REC UNREAD" messages that were received by the modem since |
bogdanm | 1:4a23efdf0da9 | 405 | m_state = SMS_GET_COUNT_CMD_SENT; |
bogdanm | 1:4a23efdf0da9 | 406 | ret = m_pIf->execute("AT+CMGL=\"REC UNREAD\"", this, NULL, DEFAULT_TIMEOUT); |
bogdanm | 1:4a23efdf0da9 | 407 | if( ret != OK ) |
bogdanm | 1:4a23efdf0da9 | 408 | { |
bogdanm | 1:4a23efdf0da9 | 409 | WARN("AT+CMGL returned %d", ret); |
bogdanm | 1:4a23efdf0da9 | 410 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 411 | m_msgRefListCount = 0; //List could be invalid |
bogdanm | 1:4a23efdf0da9 | 412 | m_needsUpdate = true; |
bogdanm | 1:4a23efdf0da9 | 413 | return NET_PROTOCOL; |
bogdanm | 1:4a23efdf0da9 | 414 | } |
bogdanm | 1:4a23efdf0da9 | 415 | |
bogdanm | 1:4a23efdf0da9 | 416 | DBG("%d incoming messages in inbox", m_msgRefListCount); |
bogdanm | 1:4a23efdf0da9 | 417 | |
bogdanm | 1:4a23efdf0da9 | 418 | m_state = SMS_IDLE; |
bogdanm | 1:4a23efdf0da9 | 419 | |
bogdanm | 1:4a23efdf0da9 | 420 | return OK; |
bogdanm | 1:4a23efdf0da9 | 421 | } |
bogdanm | 1:4a23efdf0da9 | 422 | |
bogdanm | 1:4a23efdf0da9 | 423 |