Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems
Dependents: mtsas mtsas mtsas mtsas
Cellular/Cellular.cpp@52:2cb58398a4f9, 2014-08-11 (annotated)
- Committer:
- Vanger
- Date:
- Mon Aug 11 16:03:19 2014 +0000
- Revision:
- 52:2cb58398a4f9
- Parent:
- 51:ffc556ba33f7
- Child:
- 55:85c04afa939a
Removed parse response '>' from sendCommand() under Cellular.cpp, changed sendSMS() to verify sending SMS message under Cellular.cpp, changed disconnect() to have better flow under EasyIP.cpp, changed isConnected() to be simpler under EasyIP.cpp
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Mike Fiore |
4:1f63354b8d1b | 1 | #include "mbed.h" |
Mike Fiore |
1:f155d94d6f3a | 2 | #include "Cellular.h" |
Mike Fiore |
1:f155d94d6f3a | 3 | #include "MTSText.h" |
Mike Fiore |
4:1f63354b8d1b | 4 | #include "MTSLog.h" |
Mike Fiore |
1:f155d94d6f3a | 5 | |
Mike Fiore |
1:f155d94d6f3a | 6 | using namespace mts; |
Mike Fiore |
1:f155d94d6f3a | 7 | |
Mike Fiore |
8:2d7259d244d1 | 8 | bool Cellular::init(MTSBufferedIO* io) |
Mike Fiore |
8:2d7259d244d1 | 9 | { |
Mike Fiore |
8:2d7259d244d1 | 10 | if (io == NULL) { |
Mike Fiore |
8:2d7259d244d1 | 11 | return false; |
Mike Fiore |
8:2d7259d244d1 | 12 | } |
Mike Fiore |
8:2d7259d244d1 | 13 | this->io = io; |
Mike Fiore |
8:2d7259d244d1 | 14 | |
Mike Fiore |
8:2d7259d244d1 | 15 | return true; |
Mike Fiore |
8:2d7259d244d1 | 16 | } |
Mike Fiore |
8:2d7259d244d1 | 17 | |
Mike Fiore |
9:1a03e3f3e7fe | 18 | bool Cellular::configureSignals(unsigned int DCD, unsigned int DTR, unsigned int RESET) |
Mike Fiore |
9:1a03e3f3e7fe | 19 | { |
Mike Fiore |
9:1a03e3f3e7fe | 20 | //Set DCD - The radio will raise and lower this line |
Mike Fiore |
9:1a03e3f3e7fe | 21 | if (DCD != NC) { |
Mike Fiore |
9:1a03e3f3e7fe | 22 | dcd = new DigitalIn(PinName(DCD)); |
Mike Fiore |
9:1a03e3f3e7fe | 23 | } |
Mike Fiore |
9:1a03e3f3e7fe | 24 | /* Set DTR - This line should be lowered when we want to talk to the radio and raised when we're done |
Mike Fiore |
9:1a03e3f3e7fe | 25 | * for now we will lower it in the constructor and raise it in the destructor. |
Mike Fiore |
9:1a03e3f3e7fe | 26 | */ |
Mike Fiore |
9:1a03e3f3e7fe | 27 | if (DTR != NC) { |
Mike Fiore |
9:1a03e3f3e7fe | 28 | dtr = new DigitalOut(PinName(DTR)); |
Mike Fiore |
9:1a03e3f3e7fe | 29 | dtr->write(0); |
Mike Fiore |
9:1a03e3f3e7fe | 30 | } |
Mike Fiore |
9:1a03e3f3e7fe | 31 | //Set RESET - Set the hardware reset line to the radio |
Mike Fiore |
9:1a03e3f3e7fe | 32 | if (RESET != NC) { |
Mike Fiore |
9:1a03e3f3e7fe | 33 | resetLine = new DigitalOut(PinName(RESET)); |
Mike Fiore |
9:1a03e3f3e7fe | 34 | } |
Mike Fiore |
9:1a03e3f3e7fe | 35 | return true; |
Mike Fiore |
9:1a03e3f3e7fe | 36 | } |
Mike Fiore |
9:1a03e3f3e7fe | 37 | |
Mike Fiore |
1:f155d94d6f3a | 38 | std::string Cellular::getRegistrationNames(Registration registration) |
Mike Fiore |
1:f155d94d6f3a | 39 | { |
Mike Fiore |
1:f155d94d6f3a | 40 | switch(registration) { |
Mike Fiore |
1:f155d94d6f3a | 41 | case NOT_REGISTERED: |
Mike Fiore |
1:f155d94d6f3a | 42 | return "NOT_REGISTERED"; |
Mike Fiore |
1:f155d94d6f3a | 43 | case REGISTERED: |
Mike Fiore |
1:f155d94d6f3a | 44 | return "REGISTERED"; |
Mike Fiore |
1:f155d94d6f3a | 45 | case SEARCHING: |
Mike Fiore |
1:f155d94d6f3a | 46 | return "SEARCHING"; |
Mike Fiore |
1:f155d94d6f3a | 47 | case DENIED: |
Mike Fiore |
1:f155d94d6f3a | 48 | return "DENIED"; |
Mike Fiore |
1:f155d94d6f3a | 49 | case UNKNOWN: |
Mike Fiore |
1:f155d94d6f3a | 50 | return "UNKNOWN"; |
Mike Fiore |
1:f155d94d6f3a | 51 | case ROAMING: |
Mike Fiore |
1:f155d94d6f3a | 52 | return "ROAMING"; |
Mike Fiore |
1:f155d94d6f3a | 53 | default: |
Mike Fiore |
1:f155d94d6f3a | 54 | return "UNKNOWN ENUM"; |
Mike Fiore |
1:f155d94d6f3a | 55 | } |
Mike Fiore |
1:f155d94d6f3a | 56 | } |
Mike Fiore |
1:f155d94d6f3a | 57 | |
Mike Fiore |
11:4e428f689069 | 58 | std::string Cellular::getRadioNames(Radio radio) { |
Mike Fiore |
11:4e428f689069 | 59 | switch(radio) { |
Mike Fiore |
11:4e428f689069 | 60 | case MTSMC_H5: |
Mike Fiore |
11:4e428f689069 | 61 | return "MTSMC-H5"; |
Mike Fiore |
11:4e428f689069 | 62 | case MTSMC_EV3: |
Mike Fiore |
11:4e428f689069 | 63 | return "MTSMC-EV3"; |
Mike Fiore |
11:4e428f689069 | 64 | case MTSMC_G3: |
Mike Fiore |
11:4e428f689069 | 65 | return "MTSMC-G3"; |
Mike Fiore |
11:4e428f689069 | 66 | case MTSMC_C2: |
Mike Fiore |
11:4e428f689069 | 67 | return "MTSMC-C2"; |
Mike Fiore |
11:4e428f689069 | 68 | case MTSMC_H5_IP: |
Mike Fiore |
11:4e428f689069 | 69 | return "MTSMC-H5-IP"; |
Mike Fiore |
11:4e428f689069 | 70 | case MTSMC_EV3_IP: |
Mike Fiore |
11:4e428f689069 | 71 | return "MTSMC-EV3-IP"; |
Mike Fiore |
11:4e428f689069 | 72 | case MTSMC_C2_IP: |
Mike Fiore |
11:4e428f689069 | 73 | return "MTSMC-C2-IP"; |
Mike Fiore |
11:4e428f689069 | 74 | default: |
Mike Fiore |
11:4e428f689069 | 75 | return "UNKNOWN ENUM"; |
Mike Fiore |
11:4e428f689069 | 76 | } |
Mike Fiore |
11:4e428f689069 | 77 | } |
Mike Fiore |
11:4e428f689069 | 78 | |
Mike Fiore |
1:f155d94d6f3a | 79 | Code Cellular::test() |
Mike Fiore |
1:f155d94d6f3a | 80 | { |
Mike Fiore |
1:f155d94d6f3a | 81 | int i = 0; |
mfiore | 18:fa0d8120f81f | 82 | while (sendBasicCommand("AT", 1000) != MTS_SUCCESS) { |
Mike Fiore |
1:f155d94d6f3a | 83 | i++; |
Mike Fiore |
1:f155d94d6f3a | 84 | if (i >= 30) { |
Mike Fiore |
4:1f63354b8d1b | 85 | logError("Could not talk to radio after 30 tries"); |
Mike Fiore |
1:f155d94d6f3a | 86 | i = 0; |
Mike Fiore |
1:f155d94d6f3a | 87 | } |
Mike Fiore |
1:f155d94d6f3a | 88 | wait(1); |
Mike Fiore |
1:f155d94d6f3a | 89 | } |
mfiore | 18:fa0d8120f81f | 90 | return MTS_SUCCESS; |
Mike Fiore |
1:f155d94d6f3a | 91 | } |
Mike Fiore |
1:f155d94d6f3a | 92 | |
Mike Fiore |
1:f155d94d6f3a | 93 | int Cellular::getSignalStrength() |
Mike Fiore |
1:f155d94d6f3a | 94 | { |
Mike Fiore |
1:f155d94d6f3a | 95 | string response = sendCommand("AT+CSQ", 1000); |
Mike Fiore |
1:f155d94d6f3a | 96 | if (response.find("OK") == string::npos) { |
Mike Fiore |
1:f155d94d6f3a | 97 | return -1; |
Mike Fiore |
1:f155d94d6f3a | 98 | } |
Mike Fiore |
1:f155d94d6f3a | 99 | int start = response.find(':'); |
Mike Fiore |
1:f155d94d6f3a | 100 | int stop = response.find(',', start); |
Mike Fiore |
1:f155d94d6f3a | 101 | string signal = response.substr(start + 2, stop - start - 2); |
Mike Fiore |
1:f155d94d6f3a | 102 | int value; |
Mike Fiore |
1:f155d94d6f3a | 103 | sscanf(signal.c_str(), "%d", &value); |
Mike Fiore |
1:f155d94d6f3a | 104 | return value; |
Mike Fiore |
1:f155d94d6f3a | 105 | } |
Mike Fiore |
1:f155d94d6f3a | 106 | |
Mike Fiore |
1:f155d94d6f3a | 107 | Cellular::Registration Cellular::getRegistration() |
Mike Fiore |
1:f155d94d6f3a | 108 | { |
Mike Fiore |
1:f155d94d6f3a | 109 | string response = sendCommand("AT+CREG?", 5000); |
Mike Fiore |
1:f155d94d6f3a | 110 | if (response.find("OK") == string::npos) { |
Mike Fiore |
1:f155d94d6f3a | 111 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 112 | } |
Mike Fiore |
1:f155d94d6f3a | 113 | int start = response.find(','); |
Mike Fiore |
1:f155d94d6f3a | 114 | int stop = response.find(' ', start); |
Mike Fiore |
1:f155d94d6f3a | 115 | string regStat = response.substr(start + 1, stop - start - 1); |
Mike Fiore |
1:f155d94d6f3a | 116 | int value; |
Mike Fiore |
1:f155d94d6f3a | 117 | sscanf(regStat.c_str(), "%d", &value); |
Mike Fiore |
1:f155d94d6f3a | 118 | switch (value) { |
Mike Fiore |
1:f155d94d6f3a | 119 | case 0: |
Mike Fiore |
1:f155d94d6f3a | 120 | return NOT_REGISTERED; |
Mike Fiore |
1:f155d94d6f3a | 121 | case 1: |
Mike Fiore |
1:f155d94d6f3a | 122 | return REGISTERED; |
Mike Fiore |
1:f155d94d6f3a | 123 | case 2: |
Mike Fiore |
1:f155d94d6f3a | 124 | return SEARCHING; |
Mike Fiore |
1:f155d94d6f3a | 125 | case 3: |
Mike Fiore |
1:f155d94d6f3a | 126 | return DENIED; |
Mike Fiore |
1:f155d94d6f3a | 127 | case 4: |
Mike Fiore |
1:f155d94d6f3a | 128 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 129 | case 5: |
Mike Fiore |
1:f155d94d6f3a | 130 | return ROAMING; |
Mike Fiore |
1:f155d94d6f3a | 131 | } |
Mike Fiore |
1:f155d94d6f3a | 132 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 133 | } |
Mike Fiore |
7:0ee8e69a3e9c | 134 | |
Mike Fiore |
8:2d7259d244d1 | 135 | Code Cellular::setDns(const std::string& primary, const std::string& secondary) |
Mike Fiore |
8:2d7259d244d1 | 136 | { |
Mike Fiore |
8:2d7259d244d1 | 137 | return sendBasicCommand("AT#DNS=1," + primary + "," + secondary, 1000); |
Mike Fiore |
8:2d7259d244d1 | 138 | } |
Mike Fiore |
8:2d7259d244d1 | 139 | |
Mike Fiore |
7:0ee8e69a3e9c | 140 | Code Cellular::sendSMS(const Sms& sms) |
Mike Fiore |
7:0ee8e69a3e9c | 141 | { |
Mike Fiore |
7:0ee8e69a3e9c | 142 | return sendSMS(sms.phoneNumber, sms.message); |
Mike Fiore |
7:0ee8e69a3e9c | 143 | } |
Mike Fiore |
7:0ee8e69a3e9c | 144 | |
Mike Fiore |
10:c188cc05aed5 | 145 | Code Cellular::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc) |
Mike Fiore |
10:c188cc05aed5 | 146 | { |
Mike Fiore |
10:c188cc05aed5 | 147 | if(socketOpened) { |
Mike Fiore |
10:c188cc05aed5 | 148 | logError("socket is open. Can not send AT commands"); |
mfiore | 18:fa0d8120f81f | 149 | return MTS_ERROR; |
Mike Fiore |
10:c188cc05aed5 | 150 | } |
Mike Fiore |
10:c188cc05aed5 | 151 | |
Mike Fiore |
10:c188cc05aed5 | 152 | string response = sendCommand(command, timeoutMillis, esc); |
Mike Fiore |
10:c188cc05aed5 | 153 | if (response.size() == 0) { |
mfiore | 18:fa0d8120f81f | 154 | return MTS_NO_RESPONSE; |
Mike Fiore |
10:c188cc05aed5 | 155 | } else if (response.find("OK") != string::npos) { |
mfiore | 18:fa0d8120f81f | 156 | return MTS_SUCCESS; |
Mike Fiore |
10:c188cc05aed5 | 157 | } else if (response.find("ERROR") != string::npos) { |
mfiore | 18:fa0d8120f81f | 158 | return MTS_ERROR; |
Mike Fiore |
10:c188cc05aed5 | 159 | } else { |
mfiore | 18:fa0d8120f81f | 160 | return MTS_FAILURE; |
Mike Fiore |
10:c188cc05aed5 | 161 | } |
Mike Fiore |
10:c188cc05aed5 | 162 | } |
Mike Fiore |
10:c188cc05aed5 | 163 | |
Mike Fiore |
10:c188cc05aed5 | 164 | string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc) |
Mike Fiore |
10:c188cc05aed5 | 165 | { |
Mike Fiore |
10:c188cc05aed5 | 166 | if(io == NULL) { |
Mike Fiore |
10:c188cc05aed5 | 167 | logError("MTSBufferedIO not set"); |
Mike Fiore |
10:c188cc05aed5 | 168 | return ""; |
Mike Fiore |
10:c188cc05aed5 | 169 | } |
Mike Fiore |
10:c188cc05aed5 | 170 | if(socketOpened) { |
Mike Fiore |
10:c188cc05aed5 | 171 | logError("socket is open. Can not send AT commands"); |
Mike Fiore |
10:c188cc05aed5 | 172 | return ""; |
Mike Fiore |
10:c188cc05aed5 | 173 | } |
Mike Fiore |
10:c188cc05aed5 | 174 | |
Mike Fiore |
10:c188cc05aed5 | 175 | io->rxClear(); |
Mike Fiore |
10:c188cc05aed5 | 176 | io->txClear(); |
Mike Fiore |
10:c188cc05aed5 | 177 | std::string result; |
Mike Fiore |
10:c188cc05aed5 | 178 | |
Mike Fiore |
10:c188cc05aed5 | 179 | //Attempt to write command |
Mike Fiore |
10:c188cc05aed5 | 180 | if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) { |
Mike Fiore |
10:c188cc05aed5 | 181 | //Failed to write command |
Mike Fiore |
10:c188cc05aed5 | 182 | if (command != "AT" && command != "at") { |
Mike Fiore |
10:c188cc05aed5 | 183 | logError("failed to send command to radio within %d milliseconds", timeoutMillis); |
Mike Fiore |
10:c188cc05aed5 | 184 | } |
Mike Fiore |
10:c188cc05aed5 | 185 | return ""; |
Mike Fiore |
10:c188cc05aed5 | 186 | } |
Mike Fiore |
10:c188cc05aed5 | 187 | |
Mike Fiore |
10:c188cc05aed5 | 188 | //Send Escape Character |
Mike Fiore |
10:c188cc05aed5 | 189 | if (esc != 0x00) { |
Mike Fiore |
10:c188cc05aed5 | 190 | if(io->write(esc, timeoutMillis) != 1) { |
Mike Fiore |
10:c188cc05aed5 | 191 | if (command != "AT" && command != "at") { |
Mike Fiore |
10:c188cc05aed5 | 192 | logError("failed to send character '%c' (0x%02X) to radio within %d milliseconds", esc, esc, timeoutMillis); |
Mike Fiore |
10:c188cc05aed5 | 193 | } |
Mike Fiore |
10:c188cc05aed5 | 194 | return ""; |
Mike Fiore |
10:c188cc05aed5 | 195 | } |
Mike Fiore |
10:c188cc05aed5 | 196 | } |
Vanger | 41:8b9b5098696f | 197 | mbed::Timer tmr; |
Mike Fiore |
10:c188cc05aed5 | 198 | char tmp[256]; |
Mike Fiore |
10:c188cc05aed5 | 199 | tmp[255] = 0; |
Mike Fiore |
10:c188cc05aed5 | 200 | bool done = false; |
Vanger | 41:8b9b5098696f | 201 | tmr.start(); |
Mike Fiore |
10:c188cc05aed5 | 202 | do { |
Mike Fiore |
10:c188cc05aed5 | 203 | //Make a non-blocking read call by passing timeout of zero |
Mike Fiore |
10:c188cc05aed5 | 204 | int size = io->read(tmp,255,0); //1 less than allocated (timeout is instant) |
Mike Fiore |
10:c188cc05aed5 | 205 | if(size > 0) { |
Mike Fiore |
10:c188cc05aed5 | 206 | result.append(tmp, size); |
Mike Fiore |
10:c188cc05aed5 | 207 | } |
Vanger | 41:8b9b5098696f | 208 | |
Vanger | 45:b9ead235ab7c | 209 | //Check for a response to signify the completion of the AT command |
Vanger | 41:8b9b5098696f | 210 | //OK, ERROR, CONNECT are the 3 most likely responses |
Vanger | 41:8b9b5098696f | 211 | if(result.size() > (command.size() + 2)) { |
Vanger | 52:2cb58398a4f9 | 212 | if(result.find("OK\r\n",command.size()) != std::string::npos) { |
Vanger | 45:b9ead235ab7c | 213 | done = true; |
Vanger | 52:2cb58398a4f9 | 214 | } else if (result.find("ERROR\r\n") != std::string::npos) { |
Vanger | 45:b9ead235ab7c | 215 | done = true; |
Vanger | 52:2cb58398a4f9 | 216 | } else if (result.find("NO CARRIER\r\n") != std::string::npos) { |
Vanger | 52:2cb58398a4f9 | 217 | done = true; |
Vanger | 48:3f9d82915e83 | 218 | } |
Vanger | 48:3f9d82915e83 | 219 | |
Vanger | 45:b9ead235ab7c | 220 | if(type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_EV3 || type == MTSMC_C2) { |
Vanger | 52:2cb58398a4f9 | 221 | if (result.find("CONNECT\r\n") != std::string::npos) { |
Vanger | 45:b9ead235ab7c | 222 | done = true; |
Vanger | 45:b9ead235ab7c | 223 | } |
Vanger | 45:b9ead235ab7c | 224 | } else if (type == MTSMC_H5_IP || type == MTSMC_EV3_IP || type == MTSMC_C2_IP) { |
Vanger | 52:2cb58398a4f9 | 225 | if (result.find("Ok_Info_WaitingForData\r\n") != std::string::npos) { |
Vanger | 51:ffc556ba33f7 | 226 | done = true; |
Vanger | 52:2cb58398a4f9 | 227 | } else if (result.find("Ok_Info_SocketClosed\r\n") != std::string::npos) { |
Vanger | 51:ffc556ba33f7 | 228 | done = true; |
Vanger | 52:2cb58398a4f9 | 229 | } else if (result.find("Ok_Info_PPP\r\n") != std::string::npos) { |
Vanger | 51:ffc556ba33f7 | 230 | done = true; |
Vanger | 52:2cb58398a4f9 | 231 | } else if (result.find("Ok_Info_GprsActivation\r\n") != std::string::npos) { |
Vanger | 51:ffc556ba33f7 | 232 | done = true; |
Vanger | 52:2cb58398a4f9 | 233 | } else if (result.find("alive") != std::string::npos) { |
Vanger | 45:b9ead235ab7c | 234 | done = true; |
Vanger | 52:2cb58398a4f9 | 235 | } |
Vanger | 45:b9ead235ab7c | 236 | } |
Mike Fiore |
10:c188cc05aed5 | 237 | } |
Vanger | 41:8b9b5098696f | 238 | |
Vanger | 41:8b9b5098696f | 239 | if(tmr.read_ms() >= timeoutMillis) { |
Mike Fiore |
10:c188cc05aed5 | 240 | if (command != "AT" && command != "at") { |
Mike Fiore |
10:c188cc05aed5 | 241 | logWarning("sendCommand [%s] timed out after %d milliseconds", command.c_str(), timeoutMillis); |
Mike Fiore |
10:c188cc05aed5 | 242 | } |
Mike Fiore |
10:c188cc05aed5 | 243 | done = true; |
Mike Fiore |
10:c188cc05aed5 | 244 | } |
Mike Fiore |
10:c188cc05aed5 | 245 | } while (!done); |
Vanger | 52:2cb58398a4f9 | 246 | |
Mike Fiore |
10:c188cc05aed5 | 247 | return result; |
Mike Fiore |
10:c188cc05aed5 | 248 | } |
Mike Fiore |
10:c188cc05aed5 | 249 | |
Mike Fiore |
7:0ee8e69a3e9c | 250 | Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message) |
Mike Fiore |
7:0ee8e69a3e9c | 251 | { |
mfiore | 16:1bc3e44d4746 | 252 | string csmp; |
mfiore | 16:1bc3e44d4746 | 253 | |
mfiore | 16:1bc3e44d4746 | 254 | if (type == MTSMC_H5_IP || type == MTSMC_H5) { |
mfiore | 16:1bc3e44d4746 | 255 | csmp = "AT+CSMP=17,167,0,0"; |
mfiore | 16:1bc3e44d4746 | 256 | } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2) { |
mfiore | 16:1bc3e44d4746 | 257 | csmp = "AT+CSMP=,4098,0,2"; |
mfiore | 16:1bc3e44d4746 | 258 | } else if (type == MTSMC_G3) { |
mfiore | 16:1bc3e44d4746 | 259 | } else { |
mfiore | 16:1bc3e44d4746 | 260 | logError("unknown radio type [%d]", type); |
mfiore | 18:fa0d8120f81f | 261 | return MTS_FAILURE; |
mfiore | 16:1bc3e44d4746 | 262 | } |
mfiore | 16:1bc3e44d4746 | 263 | |
Mike Fiore |
7:0ee8e69a3e9c | 264 | Code code = sendBasicCommand("AT+CMGF=1", 1000); |
mfiore | 18:fa0d8120f81f | 265 | if (code != MTS_SUCCESS) { |
mfiore | 16:1bc3e44d4746 | 266 | logError("CMGF failed"); |
mfiore | 16:1bc3e44d4746 | 267 | return code; |
mfiore | 16:1bc3e44d4746 | 268 | } |
Vanger | 52:2cb58398a4f9 | 269 | |
mfiore | 16:1bc3e44d4746 | 270 | code = sendBasicCommand(csmp, 1000); |
mfiore | 18:fa0d8120f81f | 271 | if (code != MTS_SUCCESS) { |
mfiore | 16:1bc3e44d4746 | 272 | logError("CSMP failed [%s]", getRadioNames(type).c_str()); |
Mike Fiore |
7:0ee8e69a3e9c | 273 | return code; |
Mike Fiore |
7:0ee8e69a3e9c | 274 | } |
Vanger | 52:2cb58398a4f9 | 275 | |
Vanger | 35:257eb41405e1 | 276 | string cmd = "AT+CMGS=\""; |
Vanger | 38:b2088faa8bfd | 277 | cmd.append("+"); |
Mike Fiore |
7:0ee8e69a3e9c | 278 | cmd.append(phoneNumber); |
Vanger | 36:948d06b3e23c | 279 | cmd.append("\",145"); |
mfiore | 23:8333593dd86f | 280 | for (int i = 0; i < 5; i++) { |
Vanger | 48:3f9d82915e83 | 281 | string response1 = sendCommand(cmd, 2000); |
mfiore | 23:8333593dd86f | 282 | if (response1.find('>') != string::npos) { |
mfiore | 23:8333593dd86f | 283 | break; |
mfiore | 23:8333593dd86f | 284 | } |
mfiore | 23:8333593dd86f | 285 | if (i >= 5) { |
mfiore | 23:8333593dd86f | 286 | logError("CMGS phone number failed"); |
mfiore | 23:8333593dd86f | 287 | return MTS_NO_RESPONSE; |
mfiore | 23:8333593dd86f | 288 | } |
mfiore | 23:8333593dd86f | 289 | wait(1); |
Mike Fiore |
7:0ee8e69a3e9c | 290 | } |
Mike Fiore |
7:0ee8e69a3e9c | 291 | wait(.2); |
Vanger | 52:2cb58398a4f9 | 292 | |
Vanger | 52:2cb58398a4f9 | 293 | for (int i = 0; i < 5; i++) { |
Vanger | 52:2cb58398a4f9 | 294 | string response2 = sendCommand(message, 4000, CTRL_Z); |
Vanger | 52:2cb58398a4f9 | 295 | if (response2.find("+CMGS:") != string::npos) { |
Vanger | 52:2cb58398a4f9 | 296 | break; |
Vanger | 52:2cb58398a4f9 | 297 | } |
Vanger | 52:2cb58398a4f9 | 298 | if (i >= 5) { |
Vanger | 52:2cb58398a4f9 | 299 | logError("CMGS message failed"); |
Vanger | 52:2cb58398a4f9 | 300 | return MTS_FAILURE; |
Vanger | 52:2cb58398a4f9 | 301 | } |
Vanger | 52:2cb58398a4f9 | 302 | wait(1); |
Mike Fiore |
7:0ee8e69a3e9c | 303 | } |
mfiore | 18:fa0d8120f81f | 304 | return MTS_SUCCESS; |
Mike Fiore |
7:0ee8e69a3e9c | 305 | } |
Mike Fiore |
7:0ee8e69a3e9c | 306 | |
Mike Fiore |
7:0ee8e69a3e9c | 307 | std::vector<Cellular::Sms> Cellular::getReceivedSms() |
Mike Fiore |
7:0ee8e69a3e9c | 308 | { |
Mike Fiore |
7:0ee8e69a3e9c | 309 | int smsNumber = 0; |
Mike Fiore |
7:0ee8e69a3e9c | 310 | std::vector<Sms> vSms; |
mfiore | 16:1bc3e44d4746 | 311 | std::string received; |
mfiore | 16:1bc3e44d4746 | 312 | size_t pos; |
mfiore | 16:1bc3e44d4746 | 313 | |
mfiore | 16:1bc3e44d4746 | 314 | Code code = sendBasicCommand("AT+CMGF=1", 1000); |
mfiore | 18:fa0d8120f81f | 315 | if (code != MTS_SUCCESS) { |
mfiore | 16:1bc3e44d4746 | 316 | logError("CMGF failed"); |
mfiore | 16:1bc3e44d4746 | 317 | return vSms; |
mfiore | 16:1bc3e44d4746 | 318 | } |
mfiore | 16:1bc3e44d4746 | 319 | |
Vanger | 35:257eb41405e1 | 320 | received = sendCommand("AT+CMGL=\"ALL\"", 5000); |
mfiore | 16:1bc3e44d4746 | 321 | pos = received.find("+CMGL: "); |
Mike Fiore |
7:0ee8e69a3e9c | 322 | |
Mike Fiore |
7:0ee8e69a3e9c | 323 | while (pos != std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 324 | Cellular::Sms sms; |
Mike Fiore |
7:0ee8e69a3e9c | 325 | std::string line(Text::getLine(received, pos, pos)); |
Mike Fiore |
7:0ee8e69a3e9c | 326 | if(line.find("+CMGL: ") == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 327 | continue; |
Mike Fiore |
7:0ee8e69a3e9c | 328 | } |
Mike Fiore |
7:0ee8e69a3e9c | 329 | //Start of SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 330 | std::vector<std::string> vSmsParts = Text::split(line, ','); |
mfiore | 16:1bc3e44d4746 | 331 | if (type == MTSMC_H5_IP || type == MTSMC_H5) { |
mfiore | 16:1bc3e44d4746 | 332 | /* format for H5 and H5-IP radios |
mfiore | 16:1bc3e44d4746 | 333 | * <index>, <status>, <oa>, <alpha>, <scts> |
mfiore | 16:1bc3e44d4746 | 334 | * scts contains a comma, so splitting on commas should give us 6 items |
mfiore | 16:1bc3e44d4746 | 335 | */ |
mfiore | 16:1bc3e44d4746 | 336 | if(vSmsParts.size() != 6) { |
mfiore | 16:1bc3e44d4746 | 337 | logWarning("Expected 5 commas. SMS[%d] DATA[%s]. Continuing ...", smsNumber, line.c_str()); |
mfiore | 16:1bc3e44d4746 | 338 | continue; |
mfiore | 16:1bc3e44d4746 | 339 | } |
mfiore | 16:1bc3e44d4746 | 340 | |
mfiore | 16:1bc3e44d4746 | 341 | sms.phoneNumber = vSmsParts[2]; |
mfiore | 16:1bc3e44d4746 | 342 | sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5]; |
mfiore | 16:1bc3e44d4746 | 343 | } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2) { |
mfiore | 16:1bc3e44d4746 | 344 | /* format for EV3 and EV3-IP radios |
mfiore | 16:1bc3e44d4746 | 345 | * <index>, <status>, <oa>, <callback>, <date> |
mfiore | 16:1bc3e44d4746 | 346 | * splitting on commas should give us 5 items |
mfiore | 16:1bc3e44d4746 | 347 | */ |
mfiore | 16:1bc3e44d4746 | 348 | if(vSmsParts.size() != 5) { |
mfiore | 16:1bc3e44d4746 | 349 | logWarning("Expected 4 commas. SMS[%d] DATA[%s]. Continuing ...", smsNumber, line.c_str()); |
mfiore | 16:1bc3e44d4746 | 350 | continue; |
mfiore | 16:1bc3e44d4746 | 351 | } |
mfiore | 16:1bc3e44d4746 | 352 | |
mfiore | 16:1bc3e44d4746 | 353 | sms.phoneNumber = vSmsParts[2]; |
mfiore | 16:1bc3e44d4746 | 354 | /* timestamp is in a nasty format |
mfiore | 16:1bc3e44d4746 | 355 | * YYYYMMDDHHMMSS |
mfiore | 16:1bc3e44d4746 | 356 | * nobody wants to try and decipher that, so format it nicely |
mfiore | 16:1bc3e44d4746 | 357 | * YY/MM/DD,HH:MM:SS |
mfiore | 16:1bc3e44d4746 | 358 | */ |
mfiore | 16:1bc3e44d4746 | 359 | string s = vSmsParts[4]; |
mfiore | 16:1bc3e44d4746 | 360 | sms.timestamp = s.substr(2,2) + "/" + s.substr(4,2) + "/" + s.substr(6,2) + ", " + s.substr(8,2) + ":" + s.substr(10,2) + ":" + s.substr(12,2); |
Mike Fiore |
7:0ee8e69a3e9c | 361 | } |
Mike Fiore |
7:0ee8e69a3e9c | 362 | |
Mike Fiore |
7:0ee8e69a3e9c | 363 | if(pos == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 364 | logWarning("Expected SMS body. SMS[%d]. Leaving ...", smsNumber); |
Mike Fiore |
7:0ee8e69a3e9c | 365 | break; |
Mike Fiore |
7:0ee8e69a3e9c | 366 | } |
Mike Fiore |
7:0ee8e69a3e9c | 367 | //Check for the start of the next SMS message |
Vanger | 48:3f9d82915e83 | 368 | size_t bodyEnd = received.find("\r\n+CMGL:", pos); |
Mike Fiore |
7:0ee8e69a3e9c | 369 | if(bodyEnd == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 370 | //This must be the last SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 371 | bodyEnd = received.find("\r\n\r\nOK", pos); |
Mike Fiore |
7:0ee8e69a3e9c | 372 | } |
Mike Fiore |
7:0ee8e69a3e9c | 373 | //Safety check that we found the boundary of this current SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 374 | if(bodyEnd != std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 375 | sms.message = received.substr(pos, bodyEnd - pos); |
Mike Fiore |
7:0ee8e69a3e9c | 376 | } else { |
Mike Fiore |
7:0ee8e69a3e9c | 377 | sms.message = received.substr(pos); |
Mike Fiore |
7:0ee8e69a3e9c | 378 | logWarning("Expected to find end of SMS list. SMS[%d] DATA[%s].", smsNumber, sms.message.c_str()); |
Mike Fiore |
7:0ee8e69a3e9c | 379 | } |
Mike Fiore |
7:0ee8e69a3e9c | 380 | vSms.push_back(sms); |
Mike Fiore |
7:0ee8e69a3e9c | 381 | pos = bodyEnd; |
Mike Fiore |
7:0ee8e69a3e9c | 382 | smsNumber++; |
Mike Fiore |
7:0ee8e69a3e9c | 383 | } |
Mike Fiore |
7:0ee8e69a3e9c | 384 | logInfo("Received %d SMS", smsNumber); |
Mike Fiore |
7:0ee8e69a3e9c | 385 | return vSms; |
Mike Fiore |
7:0ee8e69a3e9c | 386 | } |
Mike Fiore |
7:0ee8e69a3e9c | 387 | |
Mike Fiore |
7:0ee8e69a3e9c | 388 | Code Cellular::deleteOnlyReceivedReadSms() |
Mike Fiore |
7:0ee8e69a3e9c | 389 | { |
Mike Fiore |
7:0ee8e69a3e9c | 390 | return sendBasicCommand("AT+CMGD=1,1", 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 391 | } |
Mike Fiore |
7:0ee8e69a3e9c | 392 | |
Mike Fiore |
7:0ee8e69a3e9c | 393 | Code Cellular::deleteAllReceivedSms() |
Mike Fiore |
7:0ee8e69a3e9c | 394 | { |
Mike Fiore |
7:0ee8e69a3e9c | 395 | return sendBasicCommand("AT+CMGD=1,4", 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 396 | } |