A library for talking to Multi-Tech's Cellular SocketModem Devices.
Dependents: M2X_dev axeda_wrapper_dev MTS_M2x_Example1 MTS_Cellular_Connect_Example ... more
cellular/Cellular.cpp@4:6561c9128c6f, 2013-12-11 (annotated)
- Committer:
- sgodinez
- Date:
- Wed Dec 11 16:49:21 2013 +0000
- Revision:
- 4:6561c9128c6f
- Parent:
- 0:563b70517320
- Child:
- 5:93e889a5abc6
modified Cellular class. added Text utilities.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jengbrecht | 0:563b70517320 | 1 | #ifndef CELLULAR_CPP |
jengbrecht | 0:563b70517320 | 2 | #define CELLULAR_CPP |
jengbrecht | 0:563b70517320 | 3 | |
jengbrecht | 0:563b70517320 | 4 | #include "Cellular.h" |
sgodinez | 4:6561c9128c6f | 5 | #include "MTSText.h" |
jengbrecht | 0:563b70517320 | 6 | |
sgodinez | 4:6561c9128c6f | 7 | Cellular::Cellular(MTSBufferedIO& io) : io(io) |
jengbrecht | 0:563b70517320 | 8 | { |
jengbrecht | 0:563b70517320 | 9 | } |
jengbrecht | 0:563b70517320 | 10 | |
jengbrecht | 0:563b70517320 | 11 | Cellular::~Cellular() |
jengbrecht | 0:563b70517320 | 12 | { |
jengbrecht | 0:563b70517320 | 13 | } |
jengbrecht | 0:563b70517320 | 14 | |
jengbrecht | 0:563b70517320 | 15 | Cellular::Code Cellular::ATTest() |
jengbrecht | 0:563b70517320 | 16 | { |
jengbrecht | 0:563b70517320 | 17 | return sendBasicCommand("AT", 1000); |
jengbrecht | 0:563b70517320 | 18 | } |
jengbrecht | 0:563b70517320 | 19 | |
jengbrecht | 0:563b70517320 | 20 | Cellular::Code Cellular::echoOff(bool state) |
jengbrecht | 0:563b70517320 | 21 | { |
jengbrecht | 0:563b70517320 | 22 | if (state) { |
jengbrecht | 0:563b70517320 | 23 | return sendBasicCommand("ATE0", 1000); |
jengbrecht | 0:563b70517320 | 24 | } else { |
jengbrecht | 0:563b70517320 | 25 | return sendBasicCommand("ATE1", 1000); |
jengbrecht | 0:563b70517320 | 26 | } |
jengbrecht | 0:563b70517320 | 27 | } |
jengbrecht | 0:563b70517320 | 28 | |
jengbrecht | 0:563b70517320 | 29 | int Cellular::getSignalStrength() |
jengbrecht | 0:563b70517320 | 30 | { |
jengbrecht | 0:563b70517320 | 31 | string response = sendCommand("AT+CSQ", 1000); |
jengbrecht | 0:563b70517320 | 32 | if (response.find("OK") == string::npos) { |
jengbrecht | 0:563b70517320 | 33 | return -1; |
jengbrecht | 0:563b70517320 | 34 | } |
jengbrecht | 0:563b70517320 | 35 | int start = response.find(':'); |
jengbrecht | 0:563b70517320 | 36 | int stop = response.find(',', start); |
jengbrecht | 0:563b70517320 | 37 | string signal = response.substr(start + 2, stop - start - 2); |
jengbrecht | 0:563b70517320 | 38 | int value; |
jengbrecht | 0:563b70517320 | 39 | sscanf(signal.c_str(), "%d", &value); |
jengbrecht | 0:563b70517320 | 40 | return value; |
jengbrecht | 0:563b70517320 | 41 | } |
jengbrecht | 0:563b70517320 | 42 | |
jengbrecht | 0:563b70517320 | 43 | Cellular::Registration Cellular::getRegistration() |
jengbrecht | 0:563b70517320 | 44 | { |
jengbrecht | 0:563b70517320 | 45 | string response = sendCommand("AT+CREG?", 1000); |
jengbrecht | 0:563b70517320 | 46 | if (response.find("OK") == string::npos) { |
jengbrecht | 0:563b70517320 | 47 | return UNKNOWN; |
jengbrecht | 0:563b70517320 | 48 | } |
jengbrecht | 0:563b70517320 | 49 | int start = response.find(','); |
jengbrecht | 0:563b70517320 | 50 | int stop = response.find(' ', start); |
jengbrecht | 0:563b70517320 | 51 | string regStat = response.substr(start + 1, stop - start - 1); |
jengbrecht | 0:563b70517320 | 52 | int value; |
jengbrecht | 0:563b70517320 | 53 | sscanf(regStat.c_str(), "%d", &value); |
jengbrecht | 0:563b70517320 | 54 | switch (value) { |
jengbrecht | 0:563b70517320 | 55 | case 0: |
jengbrecht | 0:563b70517320 | 56 | return NOT_REGISTERED; |
jengbrecht | 0:563b70517320 | 57 | case 1: |
jengbrecht | 0:563b70517320 | 58 | return REGISTERED; |
jengbrecht | 0:563b70517320 | 59 | case 2: |
jengbrecht | 0:563b70517320 | 60 | return SEARCHING; |
jengbrecht | 0:563b70517320 | 61 | case 3: |
jengbrecht | 0:563b70517320 | 62 | return DENIED; |
jengbrecht | 0:563b70517320 | 63 | case 4: |
jengbrecht | 0:563b70517320 | 64 | return UNKNOWN; |
jengbrecht | 0:563b70517320 | 65 | case 5: |
jengbrecht | 0:563b70517320 | 66 | return ROAMING; |
jengbrecht | 0:563b70517320 | 67 | } |
sgodinez | 4:6561c9128c6f | 68 | return UNKNOWN; |
jengbrecht | 0:563b70517320 | 69 | } |
jengbrecht | 0:563b70517320 | 70 | |
jengbrecht | 0:563b70517320 | 71 | int Cellular::connect(string host, int port) |
jengbrecht | 0:563b70517320 | 72 | { |
jengbrecht | 0:563b70517320 | 73 | // Set the Server Address |
jengbrecht | 0:563b70517320 | 74 | string hostCmd = "AT#TCPSERV=1,\""; |
jengbrecht | 0:563b70517320 | 75 | hostCmd.append(host); |
jengbrecht | 0:563b70517320 | 76 | hostCmd.append("\""); |
jengbrecht | 0:563b70517320 | 77 | if (sendBasicCommand(hostCmd, 1000) != OK) { |
jengbrecht | 0:563b70517320 | 78 | return -1; |
jengbrecht | 0:563b70517320 | 79 | } |
jengbrecht | 0:563b70517320 | 80 | |
jengbrecht | 0:563b70517320 | 81 | // Set the Server Port |
jengbrecht | 0:563b70517320 | 82 | string portCmd = "AT#TCPPORT=1,\""; |
jengbrecht | 0:563b70517320 | 83 | char tmp[7]; |
jengbrecht | 0:563b70517320 | 84 | if (sprintf(tmp, "%d", port) < 0) { |
jengbrecht | 0:563b70517320 | 85 | return -1; |
jengbrecht | 0:563b70517320 | 86 | } |
jengbrecht | 0:563b70517320 | 87 | portCmd.append(string(tmp)); |
jengbrecht | 0:563b70517320 | 88 | portCmd.append("\""); |
jengbrecht | 0:563b70517320 | 89 | if (sendBasicCommand(portCmd, 1000) != OK) { |
jengbrecht | 0:563b70517320 | 90 | return -1; |
jengbrecht | 0:563b70517320 | 91 | } |
jengbrecht | 0:563b70517320 | 92 | |
jengbrecht | 0:563b70517320 | 93 | // Try and Connect |
jengbrecht | 0:563b70517320 | 94 | string response = sendCommand("AT#OTCP=1", 2000); |
jengbrecht | 0:563b70517320 | 95 | if (response.find("Ok_Info_WaitingForData") != string::npos) { |
jengbrecht | 0:563b70517320 | 96 | return 0; |
jengbrecht | 0:563b70517320 | 97 | } else { |
jengbrecht | 0:563b70517320 | 98 | return -1; |
jengbrecht | 0:563b70517320 | 99 | } |
jengbrecht | 0:563b70517320 | 100 | } |
jengbrecht | 0:563b70517320 | 101 | |
jengbrecht | 0:563b70517320 | 102 | Cellular::Code Cellular::sendBasicCommand(string command, int timeoutMillis, ESC_CHAR esc) |
jengbrecht | 0:563b70517320 | 103 | { |
jengbrecht | 0:563b70517320 | 104 | string response = sendCommand(command, timeoutMillis, esc); |
jengbrecht | 0:563b70517320 | 105 | if (response.size() == 0) { |
jengbrecht | 0:563b70517320 | 106 | return NO_RESPONSE; |
jengbrecht | 0:563b70517320 | 107 | } else if (response.find("OK") != string::npos) { |
jengbrecht | 0:563b70517320 | 108 | return OK; |
jengbrecht | 0:563b70517320 | 109 | } else if (response.find("ERROR") != string::npos) { |
jengbrecht | 0:563b70517320 | 110 | return ERROR; |
jengbrecht | 0:563b70517320 | 111 | } else { |
jengbrecht | 0:563b70517320 | 112 | return FAILURE; |
jengbrecht | 0:563b70517320 | 113 | } |
jengbrecht | 0:563b70517320 | 114 | } |
jengbrecht | 0:563b70517320 | 115 | |
sgodinez | 4:6561c9128c6f | 116 | Cellular::Code Cellular::sendSMS(const Sms& sms) { |
sgodinez | 4:6561c9128c6f | 117 | return sendSMS(sms.phoneNumber, sms.message); |
sgodinez | 4:6561c9128c6f | 118 | } |
sgodinez | 4:6561c9128c6f | 119 | |
sgodinez | 4:6561c9128c6f | 120 | Cellular::Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message) |
jengbrecht | 0:563b70517320 | 121 | { |
jengbrecht | 0:563b70517320 | 122 | Code code = sendBasicCommand("AT+CMGF=1", 1000); |
jengbrecht | 0:563b70517320 | 123 | if (code != OK) { |
jengbrecht | 0:563b70517320 | 124 | return code; |
jengbrecht | 0:563b70517320 | 125 | } |
jengbrecht | 0:563b70517320 | 126 | string cmd = "AT+CMGS=\"+"; |
jengbrecht | 0:563b70517320 | 127 | cmd.append(phoneNumber); |
jengbrecht | 0:563b70517320 | 128 | cmd.append("\""); |
jengbrecht | 0:563b70517320 | 129 | string response1 = sendCommand(cmd, 1000); |
jengbrecht | 0:563b70517320 | 130 | if (response1.find('>') == string::npos) { |
jengbrecht | 0:563b70517320 | 131 | return NO_RESPONSE; |
jengbrecht | 0:563b70517320 | 132 | } |
jengbrecht | 0:563b70517320 | 133 | wait(.2); |
jengbrecht | 0:563b70517320 | 134 | string response2 = sendCommand(message, 4000, CTRL_Z); |
sgodinez | 4:6561c9128c6f | 135 | printf("SMS Response: %s\n", response2.c_str()); |
jengbrecht | 0:563b70517320 | 136 | if (response2.find("+CMGS:") == string::npos) { |
jengbrecht | 0:563b70517320 | 137 | return FAILURE; |
jengbrecht | 0:563b70517320 | 138 | } |
jengbrecht | 0:563b70517320 | 139 | return OK; |
jengbrecht | 0:563b70517320 | 140 | } |
jengbrecht | 0:563b70517320 | 141 | |
sgodinez | 4:6561c9128c6f | 142 | std::vector<Cellular::Sms> Cellular::getReceivedSms() { |
sgodinez | 4:6561c9128c6f | 143 | int lineNumber = 0; |
sgodinez | 4:6561c9128c6f | 144 | size_t pos = 0; |
sgodinez | 4:6561c9128c6f | 145 | bool done = false; |
sgodinez | 4:6561c9128c6f | 146 | std::vector<Sms> vSms; |
sgodinez | 4:6561c9128c6f | 147 | std::string received = sendCommand("AT+CMGL=\"ALL\"", 4000); |
sgodinez | 4:6561c9128c6f | 148 | |
sgodinez | 4:6561c9128c6f | 149 | while (pos != std::string::npos && !done) { |
sgodinez | 4:6561c9128c6f | 150 | Cellular::Sms sms; |
sgodinez | 4:6561c9128c6f | 151 | std::string line(Text::getLine(received, pos, pos)); |
sgodinez | 4:6561c9128c6f | 152 | if(line.find("+CMGL: ") == std::string::npos) { |
sgodinez | 4:6561c9128c6f | 153 | //Searching for SMS start |
sgodinez | 4:6561c9128c6f | 154 | printf("[WARNING] Expected +CMGL. LINE[%d] DATA[%s]. Continuing ...", lineNumber, line.c_str()); |
sgodinez | 4:6561c9128c6f | 155 | continue; |
sgodinez | 4:6561c9128c6f | 156 | } |
sgodinez | 4:6561c9128c6f | 157 | |
sgodinez | 4:6561c9128c6f | 158 | //Start of SMS message |
sgodinez | 4:6561c9128c6f | 159 | std::vector<std::string> vSmsParts = Text::split(line, ','); |
sgodinez | 4:6561c9128c6f | 160 | if(vSmsParts.size() != 6) { |
sgodinez | 4:6561c9128c6f | 161 | printf("[WARNING] Expected 6 commas. LINE[%d] DATA[%s]. Continuing ...", lineNumber, line.c_str()); |
sgodinez | 4:6561c9128c6f | 162 | continue; |
sgodinez | 4:6561c9128c6f | 163 | } |
sgodinez | 4:6561c9128c6f | 164 | |
sgodinez | 4:6561c9128c6f | 165 | sms.phoneNumber = vSmsParts[2]; |
sgodinez | 4:6561c9128c6f | 166 | sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5]; |
sgodinez | 4:6561c9128c6f | 167 | |
sgodinez | 4:6561c9128c6f | 168 | size_t bodyEnd = received.find("+CMGL: ", pos); |
sgodinez | 4:6561c9128c6f | 169 | sms.message = received.substr(pos, bodyEnd); |
sgodinez | 4:6561c9128c6f | 170 | pos = bodyEnd; |
sgodinez | 4:6561c9128c6f | 171 | } |
sgodinez | 4:6561c9128c6f | 172 | return vSms; |
sgodinez | 4:6561c9128c6f | 173 | } |
sgodinez | 4:6561c9128c6f | 174 | |
sgodinez | 4:6561c9128c6f | 175 | Cellular::Code Cellular::deleteOnlyReceivedReadSms() { |
sgodinez | 4:6561c9128c6f | 176 | return sendBasicCommand("AT+CMGD=1,1", 1000); |
sgodinez | 4:6561c9128c6f | 177 | } |
sgodinez | 4:6561c9128c6f | 178 | |
sgodinez | 4:6561c9128c6f | 179 | Cellular::Code Cellular::deleteAllReceivedSms() { |
sgodinez | 4:6561c9128c6f | 180 | return sendBasicCommand("AT+CMGD=1,4", 1000); |
sgodinez | 4:6561c9128c6f | 181 | } |
sgodinez | 4:6561c9128c6f | 182 | |
sgodinez | 4:6561c9128c6f | 183 | |
jengbrecht | 0:563b70517320 | 184 | string Cellular::sendCommand(string command, int timeoutMillis, ESC_CHAR esc) |
jengbrecht | 0:563b70517320 | 185 | { |
jengbrecht | 0:563b70517320 | 186 | int size = command.size() + 1; |
jengbrecht | 0:563b70517320 | 187 | char cmd[size]; |
jengbrecht | 0:563b70517320 | 188 | strcpy(cmd, command.c_str()); |
jengbrecht | 0:563b70517320 | 189 | if (esc == CR) { |
jengbrecht | 0:563b70517320 | 190 | cmd[size -1] = '\r'; |
jengbrecht | 0:563b70517320 | 191 | } else if (esc == CTRL_Z) { |
jengbrecht | 0:563b70517320 | 192 | cmd[size -1] = 0x1A; |
jengbrecht | 0:563b70517320 | 193 | } |
jengbrecht | 0:563b70517320 | 194 | |
sgodinez | 4:6561c9128c6f | 195 | io.rxClear(); |
sgodinez | 4:6561c9128c6f | 196 | io.txClear(); |
sgodinez | 4:6561c9128c6f | 197 | int status = io.write(cmd, size); |
sgodinez | 4:6561c9128c6f | 198 | int available = io.rxAvailable(); |
jengbrecht | 0:563b70517320 | 199 | int previous = -1; |
jengbrecht | 0:563b70517320 | 200 | int timer = 0; |
jengbrecht | 0:563b70517320 | 201 | while (available != previous && timer < timeoutMillis) { |
jengbrecht | 0:563b70517320 | 202 | wait(.1); |
jengbrecht | 0:563b70517320 | 203 | timer = timer + 100; |
jengbrecht | 0:563b70517320 | 204 | previous = available; |
sgodinez | 4:6561c9128c6f | 205 | available = io.rxAvailable(); |
jengbrecht | 0:563b70517320 | 206 | } |
jengbrecht | 0:563b70517320 | 207 | char tmp[available]; |
sgodinez | 4:6561c9128c6f | 208 | io.read(tmp, available); |
jengbrecht | 0:563b70517320 | 209 | return string(tmp); |
jengbrecht | 0:563b70517320 | 210 | } |
jengbrecht | 0:563b70517320 | 211 | |
jengbrecht | 0:563b70517320 | 212 | #endif /* CELLULAR_CPP */ |