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

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?

UserRevisionLine numberNew 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 */