Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MTS-Cellular by
Cellular/Cellular.cpp@9:1a03e3f3e7fe, 2014-05-21 (annotated)
- Committer:
- Mike Fiore
- Date:
- Wed May 21 15:39:35 2014 -0500
- Revision:
- 9:1a03e3f3e7fe
- Parent:
- 8:2d7259d244d1
- Child:
- 10:c188cc05aed5
more restructuring
move configureSignals and pins to Cellular class
add Radio field to Cellular class to hold radio type
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 |
1:f155d94d6f3a | 58 | Code Cellular::test() |
Mike Fiore |
1:f155d94d6f3a | 59 | { |
Mike Fiore |
1:f155d94d6f3a | 60 | int i = 0; |
Mike Fiore |
1:f155d94d6f3a | 61 | while (sendBasicCommand("AT", 1000) != SUCCESS) { |
Mike Fiore |
1:f155d94d6f3a | 62 | i++; |
Mike Fiore |
1:f155d94d6f3a | 63 | if (i >= 30) { |
Mike Fiore |
4:1f63354b8d1b | 64 | logError("Could not talk to radio after 30 tries"); |
Mike Fiore |
1:f155d94d6f3a | 65 | i = 0; |
Mike Fiore |
1:f155d94d6f3a | 66 | } |
Mike Fiore |
1:f155d94d6f3a | 67 | wait(1); |
Mike Fiore |
1:f155d94d6f3a | 68 | } |
Mike Fiore |
1:f155d94d6f3a | 69 | return SUCCESS; |
Mike Fiore |
1:f155d94d6f3a | 70 | } |
Mike Fiore |
1:f155d94d6f3a | 71 | |
Mike Fiore |
1:f155d94d6f3a | 72 | int Cellular::getSignalStrength() |
Mike Fiore |
1:f155d94d6f3a | 73 | { |
Mike Fiore |
1:f155d94d6f3a | 74 | string response = sendCommand("AT+CSQ", 1000); |
Mike Fiore |
1:f155d94d6f3a | 75 | if (response.find("OK") == string::npos) { |
Mike Fiore |
1:f155d94d6f3a | 76 | return -1; |
Mike Fiore |
1:f155d94d6f3a | 77 | } |
Mike Fiore |
1:f155d94d6f3a | 78 | int start = response.find(':'); |
Mike Fiore |
1:f155d94d6f3a | 79 | int stop = response.find(',', start); |
Mike Fiore |
1:f155d94d6f3a | 80 | string signal = response.substr(start + 2, stop - start - 2); |
Mike Fiore |
1:f155d94d6f3a | 81 | int value; |
Mike Fiore |
1:f155d94d6f3a | 82 | sscanf(signal.c_str(), "%d", &value); |
Mike Fiore |
1:f155d94d6f3a | 83 | return value; |
Mike Fiore |
1:f155d94d6f3a | 84 | } |
Mike Fiore |
1:f155d94d6f3a | 85 | |
Mike Fiore |
1:f155d94d6f3a | 86 | Cellular::Registration Cellular::getRegistration() |
Mike Fiore |
1:f155d94d6f3a | 87 | { |
Mike Fiore |
1:f155d94d6f3a | 88 | string response = sendCommand("AT+CREG?", 5000); |
Mike Fiore |
1:f155d94d6f3a | 89 | if (response.find("OK") == string::npos) { |
Mike Fiore |
1:f155d94d6f3a | 90 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 91 | } |
Mike Fiore |
1:f155d94d6f3a | 92 | int start = response.find(','); |
Mike Fiore |
1:f155d94d6f3a | 93 | int stop = response.find(' ', start); |
Mike Fiore |
1:f155d94d6f3a | 94 | string regStat = response.substr(start + 1, stop - start - 1); |
Mike Fiore |
1:f155d94d6f3a | 95 | int value; |
Mike Fiore |
1:f155d94d6f3a | 96 | sscanf(regStat.c_str(), "%d", &value); |
Mike Fiore |
1:f155d94d6f3a | 97 | switch (value) { |
Mike Fiore |
1:f155d94d6f3a | 98 | case 0: |
Mike Fiore |
1:f155d94d6f3a | 99 | return NOT_REGISTERED; |
Mike Fiore |
1:f155d94d6f3a | 100 | case 1: |
Mike Fiore |
1:f155d94d6f3a | 101 | return REGISTERED; |
Mike Fiore |
1:f155d94d6f3a | 102 | case 2: |
Mike Fiore |
1:f155d94d6f3a | 103 | return SEARCHING; |
Mike Fiore |
1:f155d94d6f3a | 104 | case 3: |
Mike Fiore |
1:f155d94d6f3a | 105 | return DENIED; |
Mike Fiore |
1:f155d94d6f3a | 106 | case 4: |
Mike Fiore |
1:f155d94d6f3a | 107 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 108 | case 5: |
Mike Fiore |
1:f155d94d6f3a | 109 | return ROAMING; |
Mike Fiore |
1:f155d94d6f3a | 110 | } |
Mike Fiore |
1:f155d94d6f3a | 111 | return UNKNOWN; |
Mike Fiore |
1:f155d94d6f3a | 112 | } |
Mike Fiore |
7:0ee8e69a3e9c | 113 | |
Mike Fiore |
8:2d7259d244d1 | 114 | Code Cellular::setApn(const std::string& apn) |
Mike Fiore |
8:2d7259d244d1 | 115 | { |
Mike Fiore |
8:2d7259d244d1 | 116 | Code code = sendBasicCommand("AT#APNSERV=\"" + apn + "\"", 1000); |
Mike Fiore |
8:2d7259d244d1 | 117 | if (code != SUCCESS) { |
Mike Fiore |
8:2d7259d244d1 | 118 | return code; |
Mike Fiore |
8:2d7259d244d1 | 119 | } |
Mike Fiore |
8:2d7259d244d1 | 120 | this->apn = apn; |
Mike Fiore |
8:2d7259d244d1 | 121 | return code; |
Mike Fiore |
8:2d7259d244d1 | 122 | } |
Mike Fiore |
8:2d7259d244d1 | 123 | |
Mike Fiore |
8:2d7259d244d1 | 124 | |
Mike Fiore |
8:2d7259d244d1 | 125 | Code Cellular::setDns(const std::string& primary, const std::string& secondary) |
Mike Fiore |
8:2d7259d244d1 | 126 | { |
Mike Fiore |
8:2d7259d244d1 | 127 | return sendBasicCommand("AT#DNS=1," + primary + "," + secondary, 1000); |
Mike Fiore |
8:2d7259d244d1 | 128 | } |
Mike Fiore |
8:2d7259d244d1 | 129 | |
Mike Fiore |
7:0ee8e69a3e9c | 130 | Code Cellular::sendSMS(const Sms& sms) |
Mike Fiore |
7:0ee8e69a3e9c | 131 | { |
Mike Fiore |
7:0ee8e69a3e9c | 132 | return sendSMS(sms.phoneNumber, sms.message); |
Mike Fiore |
7:0ee8e69a3e9c | 133 | } |
Mike Fiore |
7:0ee8e69a3e9c | 134 | |
Mike Fiore |
7:0ee8e69a3e9c | 135 | Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message) |
Mike Fiore |
7:0ee8e69a3e9c | 136 | { |
Mike Fiore |
7:0ee8e69a3e9c | 137 | Code code = sendBasicCommand("AT+CMGF=1", 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 138 | if (code != SUCCESS) { |
Mike Fiore |
7:0ee8e69a3e9c | 139 | return code; |
Mike Fiore |
7:0ee8e69a3e9c | 140 | } |
Mike Fiore |
7:0ee8e69a3e9c | 141 | string cmd = "AT+CMGS=\"+"; |
Mike Fiore |
7:0ee8e69a3e9c | 142 | cmd.append(phoneNumber); |
Mike Fiore |
7:0ee8e69a3e9c | 143 | cmd.append("\""); |
Mike Fiore |
7:0ee8e69a3e9c | 144 | string response1 = sendCommand(cmd, 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 145 | if (response1.find('>') == string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 146 | return NO_RESPONSE; |
Mike Fiore |
7:0ee8e69a3e9c | 147 | } |
Mike Fiore |
7:0ee8e69a3e9c | 148 | wait(.2); |
Mike Fiore |
7:0ee8e69a3e9c | 149 | string response2 = sendCommand(message, 4000, CTRL_Z); |
Mike Fiore |
7:0ee8e69a3e9c | 150 | logInfo("SMS Response: %s", response2.c_str()); |
Mike Fiore |
7:0ee8e69a3e9c | 151 | if (response2.find("+CMGS:") == string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 152 | return FAILURE; |
Mike Fiore |
7:0ee8e69a3e9c | 153 | } |
Mike Fiore |
7:0ee8e69a3e9c | 154 | return SUCCESS; |
Mike Fiore |
7:0ee8e69a3e9c | 155 | } |
Mike Fiore |
7:0ee8e69a3e9c | 156 | |
Mike Fiore |
7:0ee8e69a3e9c | 157 | std::vector<Cellular::Sms> Cellular::getReceivedSms() |
Mike Fiore |
7:0ee8e69a3e9c | 158 | { |
Mike Fiore |
7:0ee8e69a3e9c | 159 | int smsNumber = 0; |
Mike Fiore |
7:0ee8e69a3e9c | 160 | std::vector<Sms> vSms; |
Mike Fiore |
7:0ee8e69a3e9c | 161 | std::string received = sendCommand("AT+CMGL=\"ALL\"", 4000); |
Mike Fiore |
7:0ee8e69a3e9c | 162 | size_t pos = received.find("+CMGL: "); |
Mike Fiore |
7:0ee8e69a3e9c | 163 | |
Mike Fiore |
7:0ee8e69a3e9c | 164 | while (pos != std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 165 | Cellular::Sms sms; |
Mike Fiore |
7:0ee8e69a3e9c | 166 | std::string line(Text::getLine(received, pos, pos)); |
Mike Fiore |
7:0ee8e69a3e9c | 167 | if(line.find("+CMGL: ") == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 168 | continue; |
Mike Fiore |
7:0ee8e69a3e9c | 169 | } |
Mike Fiore |
7:0ee8e69a3e9c | 170 | |
Mike Fiore |
7:0ee8e69a3e9c | 171 | //Start of SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 172 | std::vector<std::string> vSmsParts = Text::split(line, ','); |
Mike Fiore |
7:0ee8e69a3e9c | 173 | if(vSmsParts.size() != 6) { |
Mike Fiore |
7:0ee8e69a3e9c | 174 | logWarning("Expected 6 commas. SMS[%d] DATA[%s]. Continuing ...", smsNumber, line.c_str()); |
Mike Fiore |
7:0ee8e69a3e9c | 175 | continue; |
Mike Fiore |
7:0ee8e69a3e9c | 176 | } |
Mike Fiore |
7:0ee8e69a3e9c | 177 | |
Mike Fiore |
7:0ee8e69a3e9c | 178 | sms.phoneNumber = vSmsParts[2]; |
Mike Fiore |
7:0ee8e69a3e9c | 179 | sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5]; |
Mike Fiore |
7:0ee8e69a3e9c | 180 | |
Mike Fiore |
7:0ee8e69a3e9c | 181 | if(pos == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 182 | logWarning("Expected SMS body. SMS[%d]. Leaving ...", smsNumber); |
Mike Fiore |
7:0ee8e69a3e9c | 183 | break; |
Mike Fiore |
7:0ee8e69a3e9c | 184 | } |
Mike Fiore |
7:0ee8e69a3e9c | 185 | //Check for the start of the next SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 186 | size_t bodyEnd = received.find("\r\n+CMGL: ", pos); |
Mike Fiore |
7:0ee8e69a3e9c | 187 | if(bodyEnd == std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 188 | //This must be the last SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 189 | bodyEnd = received.find("\r\n\r\nOK", pos); |
Mike Fiore |
7:0ee8e69a3e9c | 190 | } |
Mike Fiore |
7:0ee8e69a3e9c | 191 | |
Mike Fiore |
7:0ee8e69a3e9c | 192 | //Safety check that we found the boundary of this current SMS message |
Mike Fiore |
7:0ee8e69a3e9c | 193 | if(bodyEnd != std::string::npos) { |
Mike Fiore |
7:0ee8e69a3e9c | 194 | sms.message = received.substr(pos, bodyEnd - pos); |
Mike Fiore |
7:0ee8e69a3e9c | 195 | } else { |
Mike Fiore |
7:0ee8e69a3e9c | 196 | sms.message = received.substr(pos); |
Mike Fiore |
7:0ee8e69a3e9c | 197 | logWarning("Expected to find end of SMS list. SMS[%d] DATA[%s].", smsNumber, sms.message.c_str()); |
Mike Fiore |
7:0ee8e69a3e9c | 198 | } |
Mike Fiore |
7:0ee8e69a3e9c | 199 | vSms.push_back(sms); |
Mike Fiore |
7:0ee8e69a3e9c | 200 | pos = bodyEnd; |
Mike Fiore |
7:0ee8e69a3e9c | 201 | smsNumber++; |
Mike Fiore |
7:0ee8e69a3e9c | 202 | } |
Mike Fiore |
7:0ee8e69a3e9c | 203 | logInfo("Received %d SMS", smsNumber); |
Mike Fiore |
7:0ee8e69a3e9c | 204 | return vSms; |
Mike Fiore |
7:0ee8e69a3e9c | 205 | } |
Mike Fiore |
7:0ee8e69a3e9c | 206 | |
Mike Fiore |
7:0ee8e69a3e9c | 207 | Code Cellular::deleteOnlyReceivedReadSms() |
Mike Fiore |
7:0ee8e69a3e9c | 208 | { |
Mike Fiore |
7:0ee8e69a3e9c | 209 | return sendBasicCommand("AT+CMGD=1,1", 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 210 | } |
Mike Fiore |
7:0ee8e69a3e9c | 211 | |
Mike Fiore |
7:0ee8e69a3e9c | 212 | Code Cellular::deleteAllReceivedSms() |
Mike Fiore |
7:0ee8e69a3e9c | 213 | { |
Mike Fiore |
7:0ee8e69a3e9c | 214 | return sendBasicCommand("AT+CMGD=1,4", 1000); |
Mike Fiore |
7:0ee8e69a3e9c | 215 | } |