Adafruit GSM library

Dependents:   GSM

Committer:
ptcrews
Date:
Sat Dec 05 07:22:00 2015 +0000
Revision:
0:13b14c71d29e
Adafruit GSM library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ptcrews 0:13b14c71d29e 1 /***************************************************
ptcrews 0:13b14c71d29e 2 This is a library for our Adafruit FONA Cellular Module
ptcrews 0:13b14c71d29e 3
ptcrews 0:13b14c71d29e 4 Designed specifically to work with the Adafruit FONA
ptcrews 0:13b14c71d29e 5 ----> http://www.adafruit.com/products/1946
ptcrews 0:13b14c71d29e 6 ----> http://www.adafruit.com/products/1963
ptcrews 0:13b14c71d29e 7
ptcrews 0:13b14c71d29e 8 These displays use TTL Serial to communicate, 2 pins are required to
ptcrews 0:13b14c71d29e 9 interface
ptcrews 0:13b14c71d29e 10 Adafruit invests time and resources providing this open source code,
ptcrews 0:13b14c71d29e 11 please support Adafruit and open-source hardware by purchasing
ptcrews 0:13b14c71d29e 12 products from Adafruit!
ptcrews 0:13b14c71d29e 13
ptcrews 0:13b14c71d29e 14 Written by Limor Fried/Ladyada for Adafruit Industries.
ptcrews 0:13b14c71d29e 15 BSD license, all text above must be included in any redistribution
ptcrews 0:13b14c71d29e 16 ****************************************************/
ptcrews 0:13b14c71d29e 17
ptcrews 0:13b14c71d29e 18 /*
ptcrews 0:13b14c71d29e 19 * Modified by Marc PLOUHINEC 27/06/2015 for use in mbed
ptcrews 0:13b14c71d29e 20 */
ptcrews 0:13b14c71d29e 21 #include <algorithm>
ptcrews 0:13b14c71d29e 22 #include "Adafruit_FONA.h"
ptcrews 0:13b14c71d29e 23
ptcrews 0:13b14c71d29e 24 #define HIGH 1
ptcrews 0:13b14c71d29e 25 #define LOW 0
ptcrews 0:13b14c71d29e 26
ptcrews 0:13b14c71d29e 27 bool Adafruit_FONA::begin(int baudrate) {
ptcrews 0:13b14c71d29e 28 mySerial.baud(baudrate);
ptcrews 0:13b14c71d29e 29 mySerial.attach(this, &Adafruit_FONA::onSerialDataReceived, Serial::RxIrq);
ptcrews 0:13b14c71d29e 30
ptcrews 0:13b14c71d29e 31 _rstpin = HIGH;
ptcrews 0:13b14c71d29e 32 wait_ms(10);
ptcrews 0:13b14c71d29e 33 _rstpin = LOW;
ptcrews 0:13b14c71d29e 34 wait_ms(100);
ptcrews 0:13b14c71d29e 35 _rstpin = HIGH;
ptcrews 0:13b14c71d29e 36
ptcrews 0:13b14c71d29e 37 // give 3 seconds to reboot
ptcrews 0:13b14c71d29e 38 wait_ms(3000);
ptcrews 0:13b14c71d29e 39
ptcrews 0:13b14c71d29e 40 while (readable()) getc();
ptcrews 0:13b14c71d29e 41
ptcrews 0:13b14c71d29e 42 sendCheckReply("AT", "OK");
ptcrews 0:13b14c71d29e 43 wait_ms(100);
ptcrews 0:13b14c71d29e 44 sendCheckReply("AT", "OK");
ptcrews 0:13b14c71d29e 45 wait_ms(100);
ptcrews 0:13b14c71d29e 46 sendCheckReply("AT", "OK");
ptcrews 0:13b14c71d29e 47 wait_ms(100);
ptcrews 0:13b14c71d29e 48
ptcrews 0:13b14c71d29e 49 // turn off Echo!
ptcrews 0:13b14c71d29e 50 sendCheckReply("ATE0", "OK");
ptcrews 0:13b14c71d29e 51 wait_ms(100);
ptcrews 0:13b14c71d29e 52
ptcrews 0:13b14c71d29e 53 if (! sendCheckReply("ATE0", "OK")) {
ptcrews 0:13b14c71d29e 54 return false;
ptcrews 0:13b14c71d29e 55 }
ptcrews 0:13b14c71d29e 56
ptcrews 0:13b14c71d29e 57 return true;
ptcrews 0:13b14c71d29e 58 }
ptcrews 0:13b14c71d29e 59
ptcrews 0:13b14c71d29e 60 void Adafruit_FONA::setEventListener(EventListener *eventListener) {
ptcrews 0:13b14c71d29e 61 this->eventListener = eventListener;
ptcrews 0:13b14c71d29e 62 }
ptcrews 0:13b14c71d29e 63
ptcrews 0:13b14c71d29e 64 /********* Stream ********************************************/
ptcrews 0:13b14c71d29e 65
ptcrews 0:13b14c71d29e 66 int Adafruit_FONA::_putc(int value) {
ptcrews 0:13b14c71d29e 67 return mySerial.putc(value);
ptcrews 0:13b14c71d29e 68 }
ptcrews 0:13b14c71d29e 69
ptcrews 0:13b14c71d29e 70 int Adafruit_FONA::_getc() {
ptcrews 0:13b14c71d29e 71 __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables
ptcrews 0:13b14c71d29e 72
ptcrews 0:13b14c71d29e 73 // Wait for data if the buffer is empty
ptcrews 0:13b14c71d29e 74 if (isRxBufferEmpty()) {
ptcrews 0:13b14c71d29e 75 __enable_irq(); // End Critical Section - need to allow rx interrupt to get new characters for buffer
ptcrews 0:13b14c71d29e 76
ptcrews 0:13b14c71d29e 77 while(isRxBufferEmpty());
ptcrews 0:13b14c71d29e 78
ptcrews 0:13b14c71d29e 79 __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables
ptcrews 0:13b14c71d29e 80 }
ptcrews 0:13b14c71d29e 81
ptcrews 0:13b14c71d29e 82 int data = rxBuffer[rxBufferOutIndex];
ptcrews 0:13b14c71d29e 83 incrementRxBufferOutIndex();
ptcrews 0:13b14c71d29e 84
ptcrews 0:13b14c71d29e 85 __enable_irq(); // End Critical Section
ptcrews 0:13b14c71d29e 86
ptcrews 0:13b14c71d29e 87 return data;
ptcrews 0:13b14c71d29e 88 }
ptcrews 0:13b14c71d29e 89
ptcrews 0:13b14c71d29e 90 int Adafruit_FONA::readable() {
ptcrews 0:13b14c71d29e 91 return !isRxBufferEmpty();
ptcrews 0:13b14c71d29e 92 }
ptcrews 0:13b14c71d29e 93
ptcrews 0:13b14c71d29e 94 void Adafruit_FONA::onSerialDataReceived() {
ptcrews 0:13b14c71d29e 95 while (mySerial.readable() && !isRxBufferFull()) {
ptcrews 0:13b14c71d29e 96 int data = mySerial.getc();
ptcrews 0:13b14c71d29e 97 rxBuffer[rxBufferInIndex] = data;
ptcrews 0:13b14c71d29e 98
ptcrews 0:13b14c71d29e 99 //
ptcrews 0:13b14c71d29e 100 // Analyze the received data in order to detect events like RING or NO CARRIER
ptcrews 0:13b14c71d29e 101 //
ptcrews 0:13b14c71d29e 102
ptcrews 0:13b14c71d29e 103 // Copy the data in the current line
ptcrews 0:13b14c71d29e 104 if (currentReceivedLineSize < RX_BUFFER_SIZE && data != '\r' && data != '\n') {
ptcrews 0:13b14c71d29e 105 currentReceivedLine[currentReceivedLineSize] = (char) data;
ptcrews 0:13b14c71d29e 106 currentReceivedLineSize++;
ptcrews 0:13b14c71d29e 107 }
ptcrews 0:13b14c71d29e 108
ptcrews 0:13b14c71d29e 109 // Check if the line is complete
ptcrews 0:13b14c71d29e 110 if (data == '\n') {
ptcrews 0:13b14c71d29e 111 currentReceivedLine[currentReceivedLineSize] = 0;
ptcrews 0:13b14c71d29e 112
ptcrews 0:13b14c71d29e 113 if (eventListener != NULL) {
ptcrews 0:13b14c71d29e 114 // Check if we have a special event
ptcrews 0:13b14c71d29e 115 if (strcmp(currentReceivedLine, "RING") == 0) {
ptcrews 0:13b14c71d29e 116 eventListener->onRing();
ptcrews 0:13b14c71d29e 117 } else if (strcmp(currentReceivedLine, "NO CARRIER") == 0) {
ptcrews 0:13b14c71d29e 118 eventListener->onNoCarrier();
ptcrews 0:13b14c71d29e 119 }
ptcrews 0:13b14c71d29e 120 }
ptcrews 0:13b14c71d29e 121
ptcrews 0:13b14c71d29e 122 currentReceivedLineSize = 0;
ptcrews 0:13b14c71d29e 123 }
ptcrews 0:13b14c71d29e 124
ptcrews 0:13b14c71d29e 125 incrementRxBufferInIndex();
ptcrews 0:13b14c71d29e 126 }
ptcrews 0:13b14c71d29e 127 }
ptcrews 0:13b14c71d29e 128
ptcrews 0:13b14c71d29e 129 /********* Real Time Clock ********************************************/
ptcrews 0:13b14c71d29e 130
ptcrews 0:13b14c71d29e 131 bool Adafruit_FONA::enableRTC(uint8_t i) {
ptcrews 0:13b14c71d29e 132 if (! sendCheckReply("AT+CLTS=", i, "OK"))
ptcrews 0:13b14c71d29e 133 return false;
ptcrews 0:13b14c71d29e 134 return sendCheckReply("AT&W", "OK");
ptcrews 0:13b14c71d29e 135 }
ptcrews 0:13b14c71d29e 136
ptcrews 0:13b14c71d29e 137 /********* BATTERY & ADC ********************************************/
ptcrews 0:13b14c71d29e 138
ptcrews 0:13b14c71d29e 139 /* returns value in mV (uint16_t) */
ptcrews 0:13b14c71d29e 140 bool Adafruit_FONA::getBattVoltage(uint16_t *v) {
ptcrews 0:13b14c71d29e 141 return sendParseReply("AT+CBC", "+CBC: ", v, ',', 2);
ptcrews 0:13b14c71d29e 142 }
ptcrews 0:13b14c71d29e 143
ptcrews 0:13b14c71d29e 144 /* returns the percentage charge of battery as reported by sim800 */
ptcrews 0:13b14c71d29e 145 bool Adafruit_FONA::getBattPercent(uint16_t *p) {
ptcrews 0:13b14c71d29e 146 return sendParseReply("AT+CBC", "+CBC: ", p, ',', 1);
ptcrews 0:13b14c71d29e 147 }
ptcrews 0:13b14c71d29e 148
ptcrews 0:13b14c71d29e 149 bool Adafruit_FONA::getADCVoltage(uint16_t *v) {
ptcrews 0:13b14c71d29e 150 return sendParseReply("AT+CADC?", "+CADC: 1,", v);
ptcrews 0:13b14c71d29e 151 }
ptcrews 0:13b14c71d29e 152
ptcrews 0:13b14c71d29e 153 /********* SIM ***********************************************************/
ptcrews 0:13b14c71d29e 154
ptcrews 0:13b14c71d29e 155 bool Adafruit_FONA::unlockSIM(char *pin)
ptcrews 0:13b14c71d29e 156 {
ptcrews 0:13b14c71d29e 157 char sendbuff[14] = "AT+CPIN=";
ptcrews 0:13b14c71d29e 158 sendbuff[8] = pin[0];
ptcrews 0:13b14c71d29e 159 sendbuff[9] = pin[1];
ptcrews 0:13b14c71d29e 160 sendbuff[10] = pin[2];
ptcrews 0:13b14c71d29e 161 sendbuff[11] = pin[3];
ptcrews 0:13b14c71d29e 162 sendbuff[12] = NULL;
ptcrews 0:13b14c71d29e 163
ptcrews 0:13b14c71d29e 164 return sendCheckReply(sendbuff, "OK");
ptcrews 0:13b14c71d29e 165 }
ptcrews 0:13b14c71d29e 166
ptcrews 0:13b14c71d29e 167 uint8_t Adafruit_FONA::getSIMCCID(char *ccid) {
ptcrews 0:13b14c71d29e 168 getReply("AT+CCID");
ptcrews 0:13b14c71d29e 169 // up to 20 chars
ptcrews 0:13b14c71d29e 170 strncpy(ccid, replybuffer, 20);
ptcrews 0:13b14c71d29e 171 ccid[20] = 0;
ptcrews 0:13b14c71d29e 172
ptcrews 0:13b14c71d29e 173 readline(); // eat 'OK'
ptcrews 0:13b14c71d29e 174
ptcrews 0:13b14c71d29e 175 return strlen(ccid);
ptcrews 0:13b14c71d29e 176 }
ptcrews 0:13b14c71d29e 177
ptcrews 0:13b14c71d29e 178 /********* IMEI **********************************************************/
ptcrews 0:13b14c71d29e 179
ptcrews 0:13b14c71d29e 180 uint8_t Adafruit_FONA::getIMEI(char *imei) {
ptcrews 0:13b14c71d29e 181 getReply("AT+GSN");
ptcrews 0:13b14c71d29e 182
ptcrews 0:13b14c71d29e 183 // up to 15 chars
ptcrews 0:13b14c71d29e 184 strncpy(imei, replybuffer, 15);
ptcrews 0:13b14c71d29e 185 imei[15] = 0;
ptcrews 0:13b14c71d29e 186
ptcrews 0:13b14c71d29e 187 readline(); // eat 'OK'
ptcrews 0:13b14c71d29e 188
ptcrews 0:13b14c71d29e 189 return strlen(imei);
ptcrews 0:13b14c71d29e 190 }
ptcrews 0:13b14c71d29e 191
ptcrews 0:13b14c71d29e 192 /********* NETWORK *******************************************************/
ptcrews 0:13b14c71d29e 193
ptcrews 0:13b14c71d29e 194 uint8_t Adafruit_FONA::getNetworkStatus(void) {
ptcrews 0:13b14c71d29e 195 uint16_t status;
ptcrews 0:13b14c71d29e 196
ptcrews 0:13b14c71d29e 197 if (! sendParseReply("AT+CREG?", "+CREG: ", &status, ',', 1)) return 0;
ptcrews 0:13b14c71d29e 198
ptcrews 0:13b14c71d29e 199 return status;
ptcrews 0:13b14c71d29e 200 }
ptcrews 0:13b14c71d29e 201
ptcrews 0:13b14c71d29e 202
ptcrews 0:13b14c71d29e 203 uint8_t Adafruit_FONA::getRSSI(void) {
ptcrews 0:13b14c71d29e 204 uint16_t reply;
ptcrews 0:13b14c71d29e 205
ptcrews 0:13b14c71d29e 206 if (! sendParseReply("AT+CSQ", "+CSQ: ", &reply) ) return 0;
ptcrews 0:13b14c71d29e 207
ptcrews 0:13b14c71d29e 208 return reply;
ptcrews 0:13b14c71d29e 209 }
ptcrews 0:13b14c71d29e 210
ptcrews 0:13b14c71d29e 211 /********* AUDIO *******************************************************/
ptcrews 0:13b14c71d29e 212
ptcrews 0:13b14c71d29e 213 bool Adafruit_FONA::setAudio(uint8_t a) {
ptcrews 0:13b14c71d29e 214 // 0 is headset, 1 is external audio
ptcrews 0:13b14c71d29e 215 if (a > 1) return false;
ptcrews 0:13b14c71d29e 216
ptcrews 0:13b14c71d29e 217 return sendCheckReply("AT+CHFA=", a, "OK");
ptcrews 0:13b14c71d29e 218 }
ptcrews 0:13b14c71d29e 219
ptcrews 0:13b14c71d29e 220 uint8_t Adafruit_FONA::getVolume(void) {
ptcrews 0:13b14c71d29e 221 uint16_t reply;
ptcrews 0:13b14c71d29e 222
ptcrews 0:13b14c71d29e 223 if (! sendParseReply("AT+CLVL?", "+CLVL: ", &reply) ) return 0;
ptcrews 0:13b14c71d29e 224
ptcrews 0:13b14c71d29e 225 return reply;
ptcrews 0:13b14c71d29e 226 }
ptcrews 0:13b14c71d29e 227
ptcrews 0:13b14c71d29e 228 bool Adafruit_FONA::setVolume(uint8_t i) {
ptcrews 0:13b14c71d29e 229 return sendCheckReply("AT+CLVL=", i, "OK");
ptcrews 0:13b14c71d29e 230 }
ptcrews 0:13b14c71d29e 231
ptcrews 0:13b14c71d29e 232
ptcrews 0:13b14c71d29e 233 bool Adafruit_FONA::playDTMF(char dtmf) {
ptcrews 0:13b14c71d29e 234 char str[4];
ptcrews 0:13b14c71d29e 235 str[0] = '\"';
ptcrews 0:13b14c71d29e 236 str[1] = dtmf;
ptcrews 0:13b14c71d29e 237 str[2] = '\"';
ptcrews 0:13b14c71d29e 238 str[3] = 0;
ptcrews 0:13b14c71d29e 239 return sendCheckReply("AT+CLDTMF=3,", str, "OK");
ptcrews 0:13b14c71d29e 240 }
ptcrews 0:13b14c71d29e 241
ptcrews 0:13b14c71d29e 242 bool Adafruit_FONA::playToolkitTone(uint8_t t, uint16_t len) {
ptcrews 0:13b14c71d29e 243 return sendCheckReply("AT+STTONE=1,", t, len, "OK");
ptcrews 0:13b14c71d29e 244 }
ptcrews 0:13b14c71d29e 245
ptcrews 0:13b14c71d29e 246 bool Adafruit_FONA::setMicVolume(uint8_t a, uint8_t level) {
ptcrews 0:13b14c71d29e 247 // 0 is headset, 1 is external audio
ptcrews 0:13b14c71d29e 248 if (a > 1) return false;
ptcrews 0:13b14c71d29e 249
ptcrews 0:13b14c71d29e 250 return sendCheckReply("AT+CMIC=", a, level, "OK");
ptcrews 0:13b14c71d29e 251 }
ptcrews 0:13b14c71d29e 252
ptcrews 0:13b14c71d29e 253 /********* FM RADIO *******************************************************/
ptcrews 0:13b14c71d29e 254
ptcrews 0:13b14c71d29e 255
ptcrews 0:13b14c71d29e 256 bool Adafruit_FONA::FMradio(bool onoff, uint8_t a) {
ptcrews 0:13b14c71d29e 257 if (! onoff) {
ptcrews 0:13b14c71d29e 258 return sendCheckReply("AT+FMCLOSE", "OK");
ptcrews 0:13b14c71d29e 259 }
ptcrews 0:13b14c71d29e 260
ptcrews 0:13b14c71d29e 261 // 0 is headset, 1 is external audio
ptcrews 0:13b14c71d29e 262 if (a > 1) return false;
ptcrews 0:13b14c71d29e 263
ptcrews 0:13b14c71d29e 264 return sendCheckReply("AT+FMOPEN=", a, "OK");
ptcrews 0:13b14c71d29e 265 }
ptcrews 0:13b14c71d29e 266
ptcrews 0:13b14c71d29e 267 bool Adafruit_FONA::tuneFMradio(uint16_t station) {
ptcrews 0:13b14c71d29e 268 // Fail if FM station is outside allowed range.
ptcrews 0:13b14c71d29e 269 if ((station < 870) || (station > 1090))
ptcrews 0:13b14c71d29e 270 return false;
ptcrews 0:13b14c71d29e 271
ptcrews 0:13b14c71d29e 272 return sendCheckReply("AT+FMFREQ=", station, "OK");
ptcrews 0:13b14c71d29e 273 }
ptcrews 0:13b14c71d29e 274
ptcrews 0:13b14c71d29e 275 bool Adafruit_FONA::setFMVolume(uint8_t i) {
ptcrews 0:13b14c71d29e 276 // Fail if volume is outside allowed range (0-6).
ptcrews 0:13b14c71d29e 277 if (i > 6) {
ptcrews 0:13b14c71d29e 278 return false;
ptcrews 0:13b14c71d29e 279 }
ptcrews 0:13b14c71d29e 280 // Send FM volume command and verify response.
ptcrews 0:13b14c71d29e 281 return sendCheckReply("AT+FMVOLUME=", i, "OK");
ptcrews 0:13b14c71d29e 282 }
ptcrews 0:13b14c71d29e 283
ptcrews 0:13b14c71d29e 284 int8_t Adafruit_FONA::getFMVolume() {
ptcrews 0:13b14c71d29e 285 uint16_t level;
ptcrews 0:13b14c71d29e 286
ptcrews 0:13b14c71d29e 287 if (! sendParseReply("AT+FMVOLUME?", "+FMVOLUME: ", &level) ) return 0;
ptcrews 0:13b14c71d29e 288
ptcrews 0:13b14c71d29e 289 return level;
ptcrews 0:13b14c71d29e 290 }
ptcrews 0:13b14c71d29e 291
ptcrews 0:13b14c71d29e 292 int8_t Adafruit_FONA::getFMSignalLevel(uint16_t station) {
ptcrews 0:13b14c71d29e 293 // Fail if FM station is outside allowed range.
ptcrews 0:13b14c71d29e 294 if ((station < 875) || (station > 1080)) {
ptcrews 0:13b14c71d29e 295 return -1;
ptcrews 0:13b14c71d29e 296 }
ptcrews 0:13b14c71d29e 297
ptcrews 0:13b14c71d29e 298 // Send FM signal level query command.
ptcrews 0:13b14c71d29e 299 // Note, need to explicitly send timeout so right overload is chosen.
ptcrews 0:13b14c71d29e 300 getReply("AT+FMSIGNAL=", station, FONA_DEFAULT_TIMEOUT_MS);
ptcrews 0:13b14c71d29e 301 // Check response starts with expected value.
ptcrews 0:13b14c71d29e 302 char *p = strstr(replybuffer, "+FMSIGNAL: ");
ptcrews 0:13b14c71d29e 303 if (p == 0) return -1;
ptcrews 0:13b14c71d29e 304 p+=11;
ptcrews 0:13b14c71d29e 305 // Find second colon to get start of signal quality.
ptcrews 0:13b14c71d29e 306 p = strchr(p, ':');
ptcrews 0:13b14c71d29e 307 if (p == 0) return -1;
ptcrews 0:13b14c71d29e 308 p+=1;
ptcrews 0:13b14c71d29e 309 // Parse signal quality.
ptcrews 0:13b14c71d29e 310 int8_t level = atoi(p);
ptcrews 0:13b14c71d29e 311 readline(); // eat the "OK"
ptcrews 0:13b14c71d29e 312 return level;
ptcrews 0:13b14c71d29e 313 }
ptcrews 0:13b14c71d29e 314
ptcrews 0:13b14c71d29e 315 /********* PWM/BUZZER **************************************************/
ptcrews 0:13b14c71d29e 316
ptcrews 0:13b14c71d29e 317 bool Adafruit_FONA::setPWM(uint16_t period, uint8_t duty) {
ptcrews 0:13b14c71d29e 318 if (period > 2000) return false;
ptcrews 0:13b14c71d29e 319 if (duty > 100) return false;
ptcrews 0:13b14c71d29e 320
ptcrews 0:13b14c71d29e 321 return sendCheckReply("AT+SPWM=0,", period, duty, "OK");
ptcrews 0:13b14c71d29e 322 }
ptcrews 0:13b14c71d29e 323
ptcrews 0:13b14c71d29e 324 /********* CALL PHONES **************************************************/
ptcrews 0:13b14c71d29e 325 bool Adafruit_FONA::callPhone(char *number) {
ptcrews 0:13b14c71d29e 326 char sendbuff[35] = "ATD";
ptcrews 0:13b14c71d29e 327 strncpy(sendbuff+3, number, min((int)30, (int)strlen(number)));
ptcrews 0:13b14c71d29e 328 uint8_t x = strlen(sendbuff);
ptcrews 0:13b14c71d29e 329 sendbuff[x] = ';';
ptcrews 0:13b14c71d29e 330 sendbuff[x+1] = 0;
ptcrews 0:13b14c71d29e 331
ptcrews 0:13b14c71d29e 332 return sendCheckReply(sendbuff, "OK");
ptcrews 0:13b14c71d29e 333 }
ptcrews 0:13b14c71d29e 334
ptcrews 0:13b14c71d29e 335 bool Adafruit_FONA::hangUp(void) {
ptcrews 0:13b14c71d29e 336 return sendCheckReply("ATH0", "OK");
ptcrews 0:13b14c71d29e 337 }
ptcrews 0:13b14c71d29e 338
ptcrews 0:13b14c71d29e 339 bool Adafruit_FONA::pickUp(void) {
ptcrews 0:13b14c71d29e 340 return sendCheckReply("ATA", "OK");
ptcrews 0:13b14c71d29e 341 }
ptcrews 0:13b14c71d29e 342
ptcrews 0:13b14c71d29e 343 void Adafruit_FONA::onIncomingCall() {
ptcrews 0:13b14c71d29e 344 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 345 printf("> Incoming call...\r\n");
ptcrews 0:13b14c71d29e 346 #endif
ptcrews 0:13b14c71d29e 347 _incomingCall = true;
ptcrews 0:13b14c71d29e 348 }
ptcrews 0:13b14c71d29e 349
ptcrews 0:13b14c71d29e 350 bool Adafruit_FONA::callerIdNotification(bool enable) {
ptcrews 0:13b14c71d29e 351 if(enable){
ptcrews 0:13b14c71d29e 352 _ringIndicatorInterruptIn.fall(this, &Adafruit_FONA::onIncomingCall);
ptcrews 0:13b14c71d29e 353 return sendCheckReply("AT+CLIP=1", "OK");
ptcrews 0:13b14c71d29e 354 }
ptcrews 0:13b14c71d29e 355
ptcrews 0:13b14c71d29e 356 _ringIndicatorInterruptIn.fall(NULL);
ptcrews 0:13b14c71d29e 357 return sendCheckReply("AT+CLIP=0", "OK");
ptcrews 0:13b14c71d29e 358 }
ptcrews 0:13b14c71d29e 359
ptcrews 0:13b14c71d29e 360 bool Adafruit_FONA::incomingCallNumber(char* phonenum) {
ptcrews 0:13b14c71d29e 361 //+CLIP: "<incoming phone number>",145,"",0,"",0
ptcrews 0:13b14c71d29e 362 if(!_incomingCall)
ptcrews 0:13b14c71d29e 363 return false;
ptcrews 0:13b14c71d29e 364
ptcrews 0:13b14c71d29e 365 readline();
ptcrews 0:13b14c71d29e 366 while(!strcmp(replybuffer, "RING") == 0) {
ptcrews 0:13b14c71d29e 367 flushInput();
ptcrews 0:13b14c71d29e 368 readline();
ptcrews 0:13b14c71d29e 369 }
ptcrews 0:13b14c71d29e 370
ptcrews 0:13b14c71d29e 371 readline(); //reads incoming phone number line
ptcrews 0:13b14c71d29e 372
ptcrews 0:13b14c71d29e 373 parseReply("+CLIP: \"", phonenum, '"');
ptcrews 0:13b14c71d29e 374
ptcrews 0:13b14c71d29e 375 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 376 printf("Phone Number: %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 377 #endif
ptcrews 0:13b14c71d29e 378
ptcrews 0:13b14c71d29e 379 _incomingCall = false;
ptcrews 0:13b14c71d29e 380 return true;
ptcrews 0:13b14c71d29e 381 }
ptcrews 0:13b14c71d29e 382
ptcrews 0:13b14c71d29e 383 /********* SMS **********************************************************/
ptcrews 0:13b14c71d29e 384
ptcrews 0:13b14c71d29e 385 uint8_t Adafruit_FONA::getSMSInterrupt(void) {
ptcrews 0:13b14c71d29e 386 uint16_t reply;
ptcrews 0:13b14c71d29e 387
ptcrews 0:13b14c71d29e 388 if (! sendParseReply("AT+CFGRI?", "+CFGRI: ", &reply) ) return 0;
ptcrews 0:13b14c71d29e 389
ptcrews 0:13b14c71d29e 390 return reply;
ptcrews 0:13b14c71d29e 391 }
ptcrews 0:13b14c71d29e 392
ptcrews 0:13b14c71d29e 393 bool Adafruit_FONA::setSMSInterrupt(uint8_t i) {
ptcrews 0:13b14c71d29e 394 return sendCheckReply("AT+CFGRI=", i, "OK");
ptcrews 0:13b14c71d29e 395 }
ptcrews 0:13b14c71d29e 396
ptcrews 0:13b14c71d29e 397 int8_t Adafruit_FONA::getNumSMS(void) {
ptcrews 0:13b14c71d29e 398 uint16_t numsms;
ptcrews 0:13b14c71d29e 399
ptcrews 0:13b14c71d29e 400 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
ptcrews 0:13b14c71d29e 401 // ask how many sms are stored
ptcrews 0:13b14c71d29e 402
ptcrews 0:13b14c71d29e 403 if (! sendParseReply("AT+CPMS?", "+CPMS: \"SM_P\",", &numsms) ) return -1;
ptcrews 0:13b14c71d29e 404
ptcrews 0:13b14c71d29e 405 return numsms;
ptcrews 0:13b14c71d29e 406 }
ptcrews 0:13b14c71d29e 407
ptcrews 0:13b14c71d29e 408 // Reading SMS's is a bit involved so we don't use helpers that may cause delays or debug
ptcrews 0:13b14c71d29e 409 // printouts!
ptcrews 0:13b14c71d29e 410 bool Adafruit_FONA::readSMS(uint8_t i, char *smsbuff, uint16_t maxlen, uint16_t *readlen) {
ptcrews 0:13b14c71d29e 411 // text mode
ptcrews 0:13b14c71d29e 412 if (! sendCheckReply("AT+CMGF=1", "OK")) return false;
ptcrews 0:13b14c71d29e 413
ptcrews 0:13b14c71d29e 414 // show all text mode parameters
ptcrews 0:13b14c71d29e 415 if (! sendCheckReply("AT+CSDH=1", "OK")) return false;
ptcrews 0:13b14c71d29e 416
ptcrews 0:13b14c71d29e 417 // parse out the SMS len
ptcrews 0:13b14c71d29e 418 uint16_t thesmslen = 0;
ptcrews 0:13b14c71d29e 419
ptcrews 0:13b14c71d29e 420 //getReply(F("AT+CMGR="), i, 1000); // do not print debug!
ptcrews 0:13b14c71d29e 421 mySerial.printf("AT+CMGR=%d\r\n", i);
ptcrews 0:13b14c71d29e 422 readline(1000); // timeout
ptcrews 0:13b14c71d29e 423
ptcrews 0:13b14c71d29e 424 // parse it out...
ptcrews 0:13b14c71d29e 425 if (! parseReply("+CMGR:", &thesmslen, ',', 11)) {
ptcrews 0:13b14c71d29e 426 *readlen = 0;
ptcrews 0:13b14c71d29e 427 return false;
ptcrews 0:13b14c71d29e 428 }
ptcrews 0:13b14c71d29e 429
ptcrews 0:13b14c71d29e 430 readRaw(thesmslen);
ptcrews 0:13b14c71d29e 431
ptcrews 0:13b14c71d29e 432 flushInput();
ptcrews 0:13b14c71d29e 433
ptcrews 0:13b14c71d29e 434 uint16_t thelen = min(maxlen, (uint16_t)strlen(replybuffer));
ptcrews 0:13b14c71d29e 435 strncpy(smsbuff, replybuffer, thelen);
ptcrews 0:13b14c71d29e 436 smsbuff[thelen] = 0; // end the string
ptcrews 0:13b14c71d29e 437
ptcrews 0:13b14c71d29e 438 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 439 printf("%s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 440 #endif
ptcrews 0:13b14c71d29e 441 *readlen = thelen;
ptcrews 0:13b14c71d29e 442 return true;
ptcrews 0:13b14c71d29e 443 }
ptcrews 0:13b14c71d29e 444
ptcrews 0:13b14c71d29e 445 // Retrieve the sender of the specified SMS message and copy it as a string to
ptcrews 0:13b14c71d29e 446 // the sender buffer. Up to senderlen characters of the sender will be copied
ptcrews 0:13b14c71d29e 447 // and a null terminator will be added if less than senderlen charactesr are
ptcrews 0:13b14c71d29e 448 // copied to the result. Returns true if a result was successfully retrieved,
ptcrews 0:13b14c71d29e 449 // otherwise false.
ptcrews 0:13b14c71d29e 450 bool Adafruit_FONA::getSMSSender(uint8_t i, char *sender, int senderlen) {
ptcrews 0:13b14c71d29e 451 // Ensure text mode and all text mode parameters are sent.
ptcrews 0:13b14c71d29e 452 if (! sendCheckReply("AT+CMGF=1", "OK")) return false;
ptcrews 0:13b14c71d29e 453 if (! sendCheckReply("AT+CSDH=1", "OK")) return false;
ptcrews 0:13b14c71d29e 454 // Send command to retrieve SMS message and parse a line of response.
ptcrews 0:13b14c71d29e 455 mySerial.printf("AT+CMGR=%d\r\n", i);
ptcrews 0:13b14c71d29e 456 readline(1000);
ptcrews 0:13b14c71d29e 457 // Parse the second field in the response.
ptcrews 0:13b14c71d29e 458 bool result = parseReplyQuoted("+CMGR:", sender, senderlen, ',', 1);
ptcrews 0:13b14c71d29e 459 // Drop any remaining data from the response.
ptcrews 0:13b14c71d29e 460 flushInput();
ptcrews 0:13b14c71d29e 461 return result;
ptcrews 0:13b14c71d29e 462 }
ptcrews 0:13b14c71d29e 463
ptcrews 0:13b14c71d29e 464 bool Adafruit_FONA::sendSMS(char *smsaddr, char *smsmsg) {
ptcrews 0:13b14c71d29e 465 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
ptcrews 0:13b14c71d29e 466
ptcrews 0:13b14c71d29e 467 char sendcmd[30] = "AT+CMGS=\"";
ptcrews 0:13b14c71d29e 468 strncpy(sendcmd+9, smsaddr, 30-9-2); // 9 bytes beginning, 2 bytes for close quote + null
ptcrews 0:13b14c71d29e 469 sendcmd[strlen(sendcmd)] = '\"';
ptcrews 0:13b14c71d29e 470
ptcrews 0:13b14c71d29e 471 if (! sendCheckReply(sendcmd, "> ")) return false;
ptcrews 0:13b14c71d29e 472 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 473 printf("> %s\r\n", smsmsg);
ptcrews 0:13b14c71d29e 474 #endif
ptcrews 0:13b14c71d29e 475 mySerial.printf("%s\r\n\r\n", smsmsg);
ptcrews 0:13b14c71d29e 476 mySerial.putc(0x1A);
ptcrews 0:13b14c71d29e 477 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 478 printf("^Z\r\n");
ptcrews 0:13b14c71d29e 479 #endif
ptcrews 0:13b14c71d29e 480 readline(10000); // read the +CMGS reply, wait up to 10 seconds!!!
ptcrews 0:13b14c71d29e 481 //Serial.print("* "); Serial.println(replybuffer);
ptcrews 0:13b14c71d29e 482 if (strstr(replybuffer, "+CMGS") == 0) {
ptcrews 0:13b14c71d29e 483 return false;
ptcrews 0:13b14c71d29e 484 }
ptcrews 0:13b14c71d29e 485 readline(1000); // read OK
ptcrews 0:13b14c71d29e 486 //Serial.print("* "); Serial.println(replybuffer);
ptcrews 0:13b14c71d29e 487
ptcrews 0:13b14c71d29e 488 if (strcmp(replybuffer, "OK") != 0) {
ptcrews 0:13b14c71d29e 489 return false;
ptcrews 0:13b14c71d29e 490 }
ptcrews 0:13b14c71d29e 491
ptcrews 0:13b14c71d29e 492 return true;
ptcrews 0:13b14c71d29e 493 }
ptcrews 0:13b14c71d29e 494
ptcrews 0:13b14c71d29e 495
ptcrews 0:13b14c71d29e 496 bool Adafruit_FONA::deleteSMS(uint8_t i) {
ptcrews 0:13b14c71d29e 497 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
ptcrews 0:13b14c71d29e 498 // read an sms
ptcrews 0:13b14c71d29e 499 char sendbuff[12] = "AT+CMGD=000";
ptcrews 0:13b14c71d29e 500 sendbuff[8] = (i / 100) + '0';
ptcrews 0:13b14c71d29e 501 i %= 100;
ptcrews 0:13b14c71d29e 502 sendbuff[9] = (i / 10) + '0';
ptcrews 0:13b14c71d29e 503 i %= 10;
ptcrews 0:13b14c71d29e 504 sendbuff[10] = i + '0';
ptcrews 0:13b14c71d29e 505
ptcrews 0:13b14c71d29e 506 return sendCheckReply(sendbuff, "OK", 2000);
ptcrews 0:13b14c71d29e 507 }
ptcrews 0:13b14c71d29e 508
ptcrews 0:13b14c71d29e 509 /********* TIME **********************************************************/
ptcrews 0:13b14c71d29e 510
ptcrews 0:13b14c71d29e 511 bool Adafruit_FONA::enableNetworkTimeSync(bool onoff) {
ptcrews 0:13b14c71d29e 512 if (onoff) {
ptcrews 0:13b14c71d29e 513 if (! sendCheckReply("AT+CLTS=1", "OK"))
ptcrews 0:13b14c71d29e 514 return false;
ptcrews 0:13b14c71d29e 515 } else {
ptcrews 0:13b14c71d29e 516 if (! sendCheckReply("AT+CLTS=0", "OK"))
ptcrews 0:13b14c71d29e 517 return false;
ptcrews 0:13b14c71d29e 518 }
ptcrews 0:13b14c71d29e 519
ptcrews 0:13b14c71d29e 520 flushInput(); // eat any 'Unsolicted Result Code'
ptcrews 0:13b14c71d29e 521
ptcrews 0:13b14c71d29e 522 return true;
ptcrews 0:13b14c71d29e 523 }
ptcrews 0:13b14c71d29e 524
ptcrews 0:13b14c71d29e 525 bool Adafruit_FONA::enableNTPTimeSync(bool onoff, const char* ntpserver) {
ptcrews 0:13b14c71d29e 526 if (onoff) {
ptcrews 0:13b14c71d29e 527 if (! sendCheckReply("AT+CNTPCID=1", "OK"))
ptcrews 0:13b14c71d29e 528 return false;
ptcrews 0:13b14c71d29e 529
ptcrews 0:13b14c71d29e 530 mySerial.printf("AT+CNTP=\"");
ptcrews 0:13b14c71d29e 531 if (ntpserver != 0) {
ptcrews 0:13b14c71d29e 532 mySerial.printf(ntpserver);
ptcrews 0:13b14c71d29e 533 } else {
ptcrews 0:13b14c71d29e 534 mySerial.printf("pool.ntp.org");
ptcrews 0:13b14c71d29e 535 }
ptcrews 0:13b14c71d29e 536 mySerial.printf("\",0\r\n");
ptcrews 0:13b14c71d29e 537 readline(FONA_DEFAULT_TIMEOUT_MS);
ptcrews 0:13b14c71d29e 538 if (strcmp(replybuffer, "OK") != 0)
ptcrews 0:13b14c71d29e 539 return false;
ptcrews 0:13b14c71d29e 540
ptcrews 0:13b14c71d29e 541 if (! sendCheckReply("AT+CNTP", "OK", 10000))
ptcrews 0:13b14c71d29e 542 return false;
ptcrews 0:13b14c71d29e 543
ptcrews 0:13b14c71d29e 544 uint16_t status;
ptcrews 0:13b14c71d29e 545 readline(10000);
ptcrews 0:13b14c71d29e 546 if (! parseReply("+CNTP:", &status))
ptcrews 0:13b14c71d29e 547 return false;
ptcrews 0:13b14c71d29e 548 } else {
ptcrews 0:13b14c71d29e 549 if (! sendCheckReply("AT+CNTPCID=0", "OK"))
ptcrews 0:13b14c71d29e 550 return false;
ptcrews 0:13b14c71d29e 551 }
ptcrews 0:13b14c71d29e 552
ptcrews 0:13b14c71d29e 553 return true;
ptcrews 0:13b14c71d29e 554 }
ptcrews 0:13b14c71d29e 555
ptcrews 0:13b14c71d29e 556 bool Adafruit_FONA::getTime(char* buff, uint16_t maxlen) {
ptcrews 0:13b14c71d29e 557 getReply("AT+CCLK?", (uint16_t) 10000);
ptcrews 0:13b14c71d29e 558 if (strncmp(replybuffer, "+CCLK: ", 7) != 0)
ptcrews 0:13b14c71d29e 559 return false;
ptcrews 0:13b14c71d29e 560
ptcrews 0:13b14c71d29e 561 char *p = replybuffer+7;
ptcrews 0:13b14c71d29e 562 uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p));
ptcrews 0:13b14c71d29e 563 strncpy(buff, p, lentocopy+1);
ptcrews 0:13b14c71d29e 564 buff[lentocopy] = 0;
ptcrews 0:13b14c71d29e 565
ptcrews 0:13b14c71d29e 566 readline(); // eat OK
ptcrews 0:13b14c71d29e 567
ptcrews 0:13b14c71d29e 568 return true;
ptcrews 0:13b14c71d29e 569 }
ptcrews 0:13b14c71d29e 570
ptcrews 0:13b14c71d29e 571 /********* GPS **********************************************************/
ptcrews 0:13b14c71d29e 572
ptcrews 0:13b14c71d29e 573
ptcrews 0:13b14c71d29e 574 bool Adafruit_FONA::enableGPS(bool onoff) {
ptcrews 0:13b14c71d29e 575 uint16_t state;
ptcrews 0:13b14c71d29e 576
ptcrews 0:13b14c71d29e 577 // first check if its already on or off
ptcrews 0:13b14c71d29e 578 if (! sendParseReply("AT+CGPSPWR?", "+CGPSPWR: ", &state) )
ptcrews 0:13b14c71d29e 579 return false;
ptcrews 0:13b14c71d29e 580
ptcrews 0:13b14c71d29e 581 if (onoff && !state) {
ptcrews 0:13b14c71d29e 582 if (! sendCheckReply("AT+CGPSPWR=1", "OK"))
ptcrews 0:13b14c71d29e 583 return false;
ptcrews 0:13b14c71d29e 584 } else if (!onoff && state) {
ptcrews 0:13b14c71d29e 585 if (! sendCheckReply("AT+CGPSPWR=0", "OK"))
ptcrews 0:13b14c71d29e 586 return false;
ptcrews 0:13b14c71d29e 587 }
ptcrews 0:13b14c71d29e 588 return true;
ptcrews 0:13b14c71d29e 589 }
ptcrews 0:13b14c71d29e 590
ptcrews 0:13b14c71d29e 591 int8_t Adafruit_FONA::GPSstatus(void) {
ptcrews 0:13b14c71d29e 592 getReply("AT+CGPSSTATUS?");
ptcrews 0:13b14c71d29e 593
ptcrews 0:13b14c71d29e 594 char *p = strstr(replybuffer, "+CGPSSTATUS: Location ");
ptcrews 0:13b14c71d29e 595 if (p == 0) return -1;
ptcrews 0:13b14c71d29e 596
ptcrews 0:13b14c71d29e 597 p+=22;
ptcrews 0:13b14c71d29e 598
ptcrews 0:13b14c71d29e 599 readline(); // eat 'OK'
ptcrews 0:13b14c71d29e 600
ptcrews 0:13b14c71d29e 601
ptcrews 0:13b14c71d29e 602 if (p[0] == 'U') return 0;
ptcrews 0:13b14c71d29e 603 if (p[0] == 'N') return 1;
ptcrews 0:13b14c71d29e 604 if (p[0] == '2') return 2;
ptcrews 0:13b14c71d29e 605 if (p[0] == '3') return 3;
ptcrews 0:13b14c71d29e 606
ptcrews 0:13b14c71d29e 607 // else
ptcrews 0:13b14c71d29e 608 return 0;
ptcrews 0:13b14c71d29e 609 }
ptcrews 0:13b14c71d29e 610
ptcrews 0:13b14c71d29e 611 uint8_t Adafruit_FONA::getGPS(uint8_t arg, char *buffer, uint8_t maxbuff) {
ptcrews 0:13b14c71d29e 612 int32_t x = arg;
ptcrews 0:13b14c71d29e 613
ptcrews 0:13b14c71d29e 614 getReply("AT+CGPSINF=", x);
ptcrews 0:13b14c71d29e 615
ptcrews 0:13b14c71d29e 616 char *p = strstr(replybuffer, "CGPSINF: ");
ptcrews 0:13b14c71d29e 617 if (p == 0){
ptcrews 0:13b14c71d29e 618 buffer[0] = 0;
ptcrews 0:13b14c71d29e 619 return 0;
ptcrews 0:13b14c71d29e 620 }
ptcrews 0:13b14c71d29e 621 p+=9;
ptcrews 0:13b14c71d29e 622 uint8_t len = max((uint8_t)(maxbuff-1), (uint8_t)strlen(p));
ptcrews 0:13b14c71d29e 623 strncpy(buffer, p, len);
ptcrews 0:13b14c71d29e 624 buffer[len] = 0;
ptcrews 0:13b14c71d29e 625
ptcrews 0:13b14c71d29e 626 readline(); // eat 'OK'
ptcrews 0:13b14c71d29e 627 return len;
ptcrews 0:13b14c71d29e 628 }
ptcrews 0:13b14c71d29e 629
ptcrews 0:13b14c71d29e 630 bool Adafruit_FONA::getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude) {
ptcrews 0:13b14c71d29e 631 char gpsbuffer[120];
ptcrews 0:13b14c71d29e 632
ptcrews 0:13b14c71d29e 633 // we need at least a 2D fix
ptcrews 0:13b14c71d29e 634 if (GPSstatus() < 2)
ptcrews 0:13b14c71d29e 635 return false;
ptcrews 0:13b14c71d29e 636
ptcrews 0:13b14c71d29e 637 // grab the mode 2^5 gps csv from the sim808
ptcrews 0:13b14c71d29e 638 uint8_t res_len = getGPS(32, gpsbuffer, 120);
ptcrews 0:13b14c71d29e 639
ptcrews 0:13b14c71d29e 640 // make sure we have a response
ptcrews 0:13b14c71d29e 641 if (res_len == 0)
ptcrews 0:13b14c71d29e 642 return false;
ptcrews 0:13b14c71d29e 643
ptcrews 0:13b14c71d29e 644 // skip mode
ptcrews 0:13b14c71d29e 645 char *tok = strtok(gpsbuffer, ",");
ptcrews 0:13b14c71d29e 646 if (! tok) return false;
ptcrews 0:13b14c71d29e 647
ptcrews 0:13b14c71d29e 648 // skip date
ptcrews 0:13b14c71d29e 649 tok = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 650 if (! tok) return false;
ptcrews 0:13b14c71d29e 651
ptcrews 0:13b14c71d29e 652 // skip fix
ptcrews 0:13b14c71d29e 653 tok = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 654 if (! tok) return false;
ptcrews 0:13b14c71d29e 655
ptcrews 0:13b14c71d29e 656 // grab the latitude
ptcrews 0:13b14c71d29e 657 char *latp = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 658 if (! latp) return false;
ptcrews 0:13b14c71d29e 659
ptcrews 0:13b14c71d29e 660 // grab latitude direction
ptcrews 0:13b14c71d29e 661 char *latdir = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 662 if (! latdir) return false;
ptcrews 0:13b14c71d29e 663
ptcrews 0:13b14c71d29e 664 // grab longitude
ptcrews 0:13b14c71d29e 665 char *longp = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 666 if (! longp) return false;
ptcrews 0:13b14c71d29e 667
ptcrews 0:13b14c71d29e 668 // grab longitude direction
ptcrews 0:13b14c71d29e 669 char *longdir = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 670 if (! longdir) return false;
ptcrews 0:13b14c71d29e 671
ptcrews 0:13b14c71d29e 672 double latitude = atof(latp);
ptcrews 0:13b14c71d29e 673 double longitude = atof(longp);
ptcrews 0:13b14c71d29e 674
ptcrews 0:13b14c71d29e 675 // convert latitude from minutes to decimal
ptcrews 0:13b14c71d29e 676 float degrees = floor(latitude / 100);
ptcrews 0:13b14c71d29e 677 double minutes = latitude - (100 * degrees);
ptcrews 0:13b14c71d29e 678 minutes /= 60;
ptcrews 0:13b14c71d29e 679 degrees += minutes;
ptcrews 0:13b14c71d29e 680
ptcrews 0:13b14c71d29e 681 // turn direction into + or -
ptcrews 0:13b14c71d29e 682 if (latdir[0] == 'S') degrees *= -1;
ptcrews 0:13b14c71d29e 683
ptcrews 0:13b14c71d29e 684 *lat = degrees;
ptcrews 0:13b14c71d29e 685
ptcrews 0:13b14c71d29e 686 // convert longitude from minutes to decimal
ptcrews 0:13b14c71d29e 687 degrees = floor(longitude / 100);
ptcrews 0:13b14c71d29e 688 minutes = longitude - (100 * degrees);
ptcrews 0:13b14c71d29e 689 minutes /= 60;
ptcrews 0:13b14c71d29e 690 degrees += minutes;
ptcrews 0:13b14c71d29e 691
ptcrews 0:13b14c71d29e 692 // turn direction into + or -
ptcrews 0:13b14c71d29e 693 if (longdir[0] == 'W') degrees *= -1;
ptcrews 0:13b14c71d29e 694
ptcrews 0:13b14c71d29e 695 *lon = degrees;
ptcrews 0:13b14c71d29e 696
ptcrews 0:13b14c71d29e 697 // only grab speed if needed
ptcrews 0:13b14c71d29e 698 if (speed_kph != NULL) {
ptcrews 0:13b14c71d29e 699
ptcrews 0:13b14c71d29e 700 // grab the speed in knots
ptcrews 0:13b14c71d29e 701 char *speedp = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 702 if (! speedp) return false;
ptcrews 0:13b14c71d29e 703
ptcrews 0:13b14c71d29e 704 // convert to kph
ptcrews 0:13b14c71d29e 705 *speed_kph = atof(speedp) * 1.852;
ptcrews 0:13b14c71d29e 706
ptcrews 0:13b14c71d29e 707 }
ptcrews 0:13b14c71d29e 708
ptcrews 0:13b14c71d29e 709 // only grab heading if needed
ptcrews 0:13b14c71d29e 710 if (heading != NULL) {
ptcrews 0:13b14c71d29e 711
ptcrews 0:13b14c71d29e 712 // grab the speed in knots
ptcrews 0:13b14c71d29e 713 char *coursep = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 714 if (! coursep) return false;
ptcrews 0:13b14c71d29e 715
ptcrews 0:13b14c71d29e 716 *heading = atof(coursep);
ptcrews 0:13b14c71d29e 717
ptcrews 0:13b14c71d29e 718 }
ptcrews 0:13b14c71d29e 719
ptcrews 0:13b14c71d29e 720 // no need to continue
ptcrews 0:13b14c71d29e 721 if (altitude == NULL)
ptcrews 0:13b14c71d29e 722 return true;
ptcrews 0:13b14c71d29e 723
ptcrews 0:13b14c71d29e 724 // we need at least a 3D fix for altitude
ptcrews 0:13b14c71d29e 725 if (GPSstatus() < 3)
ptcrews 0:13b14c71d29e 726 return false;
ptcrews 0:13b14c71d29e 727
ptcrews 0:13b14c71d29e 728 // grab the mode 0 gps csv from the sim808
ptcrews 0:13b14c71d29e 729 res_len = getGPS(0, gpsbuffer, 120);
ptcrews 0:13b14c71d29e 730
ptcrews 0:13b14c71d29e 731 // make sure we have a response
ptcrews 0:13b14c71d29e 732 if (res_len == 0)
ptcrews 0:13b14c71d29e 733 return false;
ptcrews 0:13b14c71d29e 734
ptcrews 0:13b14c71d29e 735 // skip mode
ptcrews 0:13b14c71d29e 736 tok = strtok(gpsbuffer, ",");
ptcrews 0:13b14c71d29e 737 if (! tok) return false;
ptcrews 0:13b14c71d29e 738
ptcrews 0:13b14c71d29e 739 // skip lat
ptcrews 0:13b14c71d29e 740 tok = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 741 if (! tok) return false;
ptcrews 0:13b14c71d29e 742
ptcrews 0:13b14c71d29e 743 // skip long
ptcrews 0:13b14c71d29e 744 tok = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 745 if (! tok) return false;
ptcrews 0:13b14c71d29e 746
ptcrews 0:13b14c71d29e 747 // grab altitude
ptcrews 0:13b14c71d29e 748 char *altp = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 749 if (! altp) return false;
ptcrews 0:13b14c71d29e 750
ptcrews 0:13b14c71d29e 751 *altitude = atof(altp);
ptcrews 0:13b14c71d29e 752
ptcrews 0:13b14c71d29e 753 return true;
ptcrews 0:13b14c71d29e 754 }
ptcrews 0:13b14c71d29e 755
ptcrews 0:13b14c71d29e 756 bool Adafruit_FONA::enableGPSNMEA(uint8_t i) {
ptcrews 0:13b14c71d29e 757 char sendbuff[15] = "AT+CGPSOUT=000";
ptcrews 0:13b14c71d29e 758 sendbuff[11] = (i / 100) + '0';
ptcrews 0:13b14c71d29e 759 i %= 100;
ptcrews 0:13b14c71d29e 760 sendbuff[12] = (i / 10) + '0';
ptcrews 0:13b14c71d29e 761 i %= 10;
ptcrews 0:13b14c71d29e 762 sendbuff[13] = i + '0';
ptcrews 0:13b14c71d29e 763
ptcrews 0:13b14c71d29e 764 return sendCheckReply(sendbuff, "OK", 2000);
ptcrews 0:13b14c71d29e 765 }
ptcrews 0:13b14c71d29e 766
ptcrews 0:13b14c71d29e 767
ptcrews 0:13b14c71d29e 768 /********* GPRS **********************************************************/
ptcrews 0:13b14c71d29e 769
ptcrews 0:13b14c71d29e 770
ptcrews 0:13b14c71d29e 771 bool Adafruit_FONA::enableGPRS(bool onoff) {
ptcrews 0:13b14c71d29e 772 if (onoff) {
ptcrews 0:13b14c71d29e 773 // disconnect all sockets
ptcrews 0:13b14c71d29e 774 sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000);
ptcrews 0:13b14c71d29e 775
ptcrews 0:13b14c71d29e 776 if (! sendCheckReply("AT+CGATT=1", "OK", 10000))
ptcrews 0:13b14c71d29e 777 return false;
ptcrews 0:13b14c71d29e 778
ptcrews 0:13b14c71d29e 779 // set bearer profile! connection type GPRS
ptcrews 0:13b14c71d29e 780 if (! sendCheckReply("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 10000))
ptcrews 0:13b14c71d29e 781 return false;
ptcrews 0:13b14c71d29e 782
ptcrews 0:13b14c71d29e 783 // set bearer profile access point name
ptcrews 0:13b14c71d29e 784 if (apn) {
ptcrews 0:13b14c71d29e 785 // Send command AT+SAPBR=3,1,"APN","<apn value>" where <apn value> is the configured APN value.
ptcrews 0:13b14c71d29e 786 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"APN\",", apn, "OK", 10000))
ptcrews 0:13b14c71d29e 787 return false;
ptcrews 0:13b14c71d29e 788
ptcrews 0:13b14c71d29e 789 // set username/password
ptcrews 0:13b14c71d29e 790 if (apnusername) {
ptcrews 0:13b14c71d29e 791 // Send command AT+SAPBR=3,1,"USER","<user>" where <user> is the configured APN username.
ptcrews 0:13b14c71d29e 792 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"USER\",", apnusername, "OK", 10000))
ptcrews 0:13b14c71d29e 793 return false;
ptcrews 0:13b14c71d29e 794 }
ptcrews 0:13b14c71d29e 795 if (apnpassword) {
ptcrews 0:13b14c71d29e 796 // Send command AT+SAPBR=3,1,"PWD","<password>" where <password> is the configured APN password.
ptcrews 0:13b14c71d29e 797 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"PWD\",", apnpassword, "OK", 10000))
ptcrews 0:13b14c71d29e 798 return false;
ptcrews 0:13b14c71d29e 799 }
ptcrews 0:13b14c71d29e 800 }
ptcrews 0:13b14c71d29e 801
ptcrews 0:13b14c71d29e 802 // open GPRS context
ptcrews 0:13b14c71d29e 803 if (! sendCheckReply("AT+SAPBR=1,1", "OK", 10000))
ptcrews 0:13b14c71d29e 804 return false;
ptcrews 0:13b14c71d29e 805 } else {
ptcrews 0:13b14c71d29e 806 // disconnect all sockets
ptcrews 0:13b14c71d29e 807 if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000))
ptcrews 0:13b14c71d29e 808 return false;
ptcrews 0:13b14c71d29e 809
ptcrews 0:13b14c71d29e 810 // close GPRS context
ptcrews 0:13b14c71d29e 811 if (! sendCheckReply("AT+SAPBR=0,1", "OK", 10000))
ptcrews 0:13b14c71d29e 812 return false;
ptcrews 0:13b14c71d29e 813
ptcrews 0:13b14c71d29e 814 if (! sendCheckReply("AT+CGATT=0", "OK", 10000))
ptcrews 0:13b14c71d29e 815 return false;
ptcrews 0:13b14c71d29e 816 }
ptcrews 0:13b14c71d29e 817 return true;
ptcrews 0:13b14c71d29e 818 }
ptcrews 0:13b14c71d29e 819
ptcrews 0:13b14c71d29e 820 uint8_t Adafruit_FONA::GPRSstate(void) {
ptcrews 0:13b14c71d29e 821 uint16_t state;
ptcrews 0:13b14c71d29e 822
ptcrews 0:13b14c71d29e 823 if (! sendParseReply("AT+CGATT?", "+CGATT: ", &state) )
ptcrews 0:13b14c71d29e 824 return -1;
ptcrews 0:13b14c71d29e 825
ptcrews 0:13b14c71d29e 826 return state;
ptcrews 0:13b14c71d29e 827 }
ptcrews 0:13b14c71d29e 828
ptcrews 0:13b14c71d29e 829 void Adafruit_FONA::setGPRSNetworkSettings(const char* apn, const char* ausername, const char* apassword) {
ptcrews 0:13b14c71d29e 830 this->apn = (char*) apn;
ptcrews 0:13b14c71d29e 831 this->apnusername = (char*) ausername;
ptcrews 0:13b14c71d29e 832 this->apnpassword = (char*) apassword;
ptcrews 0:13b14c71d29e 833 }
ptcrews 0:13b14c71d29e 834
ptcrews 0:13b14c71d29e 835 bool Adafruit_FONA::getGSMLoc(uint16_t *errorcode, char *buff, uint16_t maxlen) {
ptcrews 0:13b14c71d29e 836 getReply("AT+CIPGSMLOC=1,1", (uint16_t)10000);
ptcrews 0:13b14c71d29e 837
ptcrews 0:13b14c71d29e 838 if (! parseReply("+CIPGSMLOC: ", errorcode))
ptcrews 0:13b14c71d29e 839 return false;
ptcrews 0:13b14c71d29e 840
ptcrews 0:13b14c71d29e 841 char *p = replybuffer+14;
ptcrews 0:13b14c71d29e 842 uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p));
ptcrews 0:13b14c71d29e 843 strncpy(buff, p, lentocopy+1);
ptcrews 0:13b14c71d29e 844
ptcrews 0:13b14c71d29e 845 readline(); // eat OK
ptcrews 0:13b14c71d29e 846
ptcrews 0:13b14c71d29e 847 return true;
ptcrews 0:13b14c71d29e 848 }
ptcrews 0:13b14c71d29e 849
ptcrews 0:13b14c71d29e 850 bool Adafruit_FONA::getGSMLoc(float *lat, float *lon) {
ptcrews 0:13b14c71d29e 851 uint16_t returncode;
ptcrews 0:13b14c71d29e 852 char gpsbuffer[120];
ptcrews 0:13b14c71d29e 853
ptcrews 0:13b14c71d29e 854 // make sure we could get a response
ptcrews 0:13b14c71d29e 855 if (! getGSMLoc(&returncode, gpsbuffer, 120))
ptcrews 0:13b14c71d29e 856 return false;
ptcrews 0:13b14c71d29e 857
ptcrews 0:13b14c71d29e 858 // make sure we have a valid return code
ptcrews 0:13b14c71d29e 859 if (returncode != 0)
ptcrews 0:13b14c71d29e 860 return false;
ptcrews 0:13b14c71d29e 861
ptcrews 0:13b14c71d29e 862 // tokenize the gps buffer to locate the lat & long
ptcrews 0:13b14c71d29e 863 char *latp = strtok(gpsbuffer, ",");
ptcrews 0:13b14c71d29e 864 if (! latp) return false;
ptcrews 0:13b14c71d29e 865
ptcrews 0:13b14c71d29e 866 char *longp = strtok(NULL, ",");
ptcrews 0:13b14c71d29e 867 if (! longp) return false;
ptcrews 0:13b14c71d29e 868
ptcrews 0:13b14c71d29e 869 *lat = atof(latp);
ptcrews 0:13b14c71d29e 870 *lon = atof(longp);
ptcrews 0:13b14c71d29e 871
ptcrews 0:13b14c71d29e 872 return true;
ptcrews 0:13b14c71d29e 873 }
ptcrews 0:13b14c71d29e 874
ptcrews 0:13b14c71d29e 875 /********* TCP FUNCTIONS ************************************/
ptcrews 0:13b14c71d29e 876
ptcrews 0:13b14c71d29e 877
ptcrews 0:13b14c71d29e 878 bool Adafruit_FONA::TCPconnect(char *server, uint16_t port) {
ptcrews 0:13b14c71d29e 879 flushInput();
ptcrews 0:13b14c71d29e 880
ptcrews 0:13b14c71d29e 881 // close all old connections
ptcrews 0:13b14c71d29e 882 if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000) ) return false;
ptcrews 0:13b14c71d29e 883
ptcrews 0:13b14c71d29e 884 // single connection at a time
ptcrews 0:13b14c71d29e 885 if (! sendCheckReply("AT+CIPMUX=0", "OK") ) return false;
ptcrews 0:13b14c71d29e 886
ptcrews 0:13b14c71d29e 887 // manually read data
ptcrews 0:13b14c71d29e 888 if (! sendCheckReply("AT+CIPRXGET=1", "OK") ) return false;
ptcrews 0:13b14c71d29e 889
ptcrews 0:13b14c71d29e 890 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 891 printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port);
ptcrews 0:13b14c71d29e 892 #endif
ptcrews 0:13b14c71d29e 893
ptcrews 0:13b14c71d29e 894 mySerial.printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port);
ptcrews 0:13b14c71d29e 895
ptcrews 0:13b14c71d29e 896 if (! expectReply("OK")) return false;
ptcrews 0:13b14c71d29e 897 if (! expectReply("CONNECT OK")) return false;
ptcrews 0:13b14c71d29e 898 return true;
ptcrews 0:13b14c71d29e 899 }
ptcrews 0:13b14c71d29e 900
ptcrews 0:13b14c71d29e 901 bool Adafruit_FONA::TCPclose(void) {
ptcrews 0:13b14c71d29e 902 return sendCheckReply("AT+CIPCLOSE", "OK");
ptcrews 0:13b14c71d29e 903 }
ptcrews 0:13b14c71d29e 904
ptcrews 0:13b14c71d29e 905 bool Adafruit_FONA::TCPconnected(void) {
ptcrews 0:13b14c71d29e 906 if (! sendCheckReply("AT+CIPSTATUS", "OK", 100) ) return false;
ptcrews 0:13b14c71d29e 907 readline(100);
ptcrews 0:13b14c71d29e 908 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 909 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 910 #endif
ptcrews 0:13b14c71d29e 911 return (strcmp(replybuffer, "STATE: CONNECT OK") == 0);
ptcrews 0:13b14c71d29e 912 }
ptcrews 0:13b14c71d29e 913
ptcrews 0:13b14c71d29e 914 bool Adafruit_FONA::TCPsend(char *packet, uint8_t len) {
ptcrews 0:13b14c71d29e 915 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 916 printf("AT+CIPSEND=%d\r\n", len);
ptcrews 0:13b14c71d29e 917
ptcrews 0:13b14c71d29e 918 for (uint16_t i=0; i<len; i++) {
ptcrews 0:13b14c71d29e 919 printf(" 0x%#02x", packet[i]);
ptcrews 0:13b14c71d29e 920 }
ptcrews 0:13b14c71d29e 921 printf("\r\n");
ptcrews 0:13b14c71d29e 922 #endif
ptcrews 0:13b14c71d29e 923
ptcrews 0:13b14c71d29e 924
ptcrews 0:13b14c71d29e 925 mySerial.printf("AT+CIPSEND=%d\r\n", len);
ptcrews 0:13b14c71d29e 926 readline();
ptcrews 0:13b14c71d29e 927 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 928 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 929 #endif
ptcrews 0:13b14c71d29e 930 if (replybuffer[0] != '>') return false;
ptcrews 0:13b14c71d29e 931
ptcrews 0:13b14c71d29e 932 for (uint16_t i=0; i<len; i++) {
ptcrews 0:13b14c71d29e 933 mySerial.putc(packet[i]);
ptcrews 0:13b14c71d29e 934 }
ptcrews 0:13b14c71d29e 935 readline(3000); // wait up to 3 seconds to send the data
ptcrews 0:13b14c71d29e 936 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 937 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 938 #endif
ptcrews 0:13b14c71d29e 939
ptcrews 0:13b14c71d29e 940 return (strcmp(replybuffer, "SEND OK") == 0);
ptcrews 0:13b14c71d29e 941 }
ptcrews 0:13b14c71d29e 942
ptcrews 0:13b14c71d29e 943 uint16_t Adafruit_FONA::TCPavailable(void) {
ptcrews 0:13b14c71d29e 944 uint16_t avail;
ptcrews 0:13b14c71d29e 945
ptcrews 0:13b14c71d29e 946 if (! sendParseReply("AT+CIPRXGET=4", "+CIPRXGET: 4,", &avail, ',', 0) ) return false;
ptcrews 0:13b14c71d29e 947
ptcrews 0:13b14c71d29e 948 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 949 printf("%d bytes available\r\n", avail);
ptcrews 0:13b14c71d29e 950 #endif
ptcrews 0:13b14c71d29e 951
ptcrews 0:13b14c71d29e 952 return avail;
ptcrews 0:13b14c71d29e 953 }
ptcrews 0:13b14c71d29e 954
ptcrews 0:13b14c71d29e 955
ptcrews 0:13b14c71d29e 956 uint16_t Adafruit_FONA::TCPread(uint8_t *buff, uint8_t len) {
ptcrews 0:13b14c71d29e 957 uint16_t avail;
ptcrews 0:13b14c71d29e 958
ptcrews 0:13b14c71d29e 959 mySerial.printf("AT+CIPRXGET=2,%d\r\n", len);
ptcrews 0:13b14c71d29e 960 readline();
ptcrews 0:13b14c71d29e 961 if (! parseReply("+CIPRXGET: 2,", &avail, ',', 0)) return false;
ptcrews 0:13b14c71d29e 962
ptcrews 0:13b14c71d29e 963 readRaw(avail);
ptcrews 0:13b14c71d29e 964
ptcrews 0:13b14c71d29e 965 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 966 printf("%d bytes read\r\n", avail);
ptcrews 0:13b14c71d29e 967 for (uint8_t i=0;i<avail;i++) {
ptcrews 0:13b14c71d29e 968 printf(" 0x%#02x", replybuffer[i]);
ptcrews 0:13b14c71d29e 969 }
ptcrews 0:13b14c71d29e 970 printf("\r\n");
ptcrews 0:13b14c71d29e 971 #endif
ptcrews 0:13b14c71d29e 972
ptcrews 0:13b14c71d29e 973 memcpy(buff, replybuffer, avail);
ptcrews 0:13b14c71d29e 974
ptcrews 0:13b14c71d29e 975 return avail;
ptcrews 0:13b14c71d29e 976 }
ptcrews 0:13b14c71d29e 977
ptcrews 0:13b14c71d29e 978 /********* HTTP LOW LEVEL FUNCTIONS ************************************/
ptcrews 0:13b14c71d29e 979
ptcrews 0:13b14c71d29e 980 bool Adafruit_FONA::HTTP_init() {
ptcrews 0:13b14c71d29e 981 return sendCheckReply("AT+HTTPINIT", "OK");
ptcrews 0:13b14c71d29e 982 }
ptcrews 0:13b14c71d29e 983
ptcrews 0:13b14c71d29e 984 bool Adafruit_FONA::HTTP_term() {
ptcrews 0:13b14c71d29e 985 return sendCheckReply("AT+HTTPTERM", "OK");
ptcrews 0:13b14c71d29e 986 }
ptcrews 0:13b14c71d29e 987
ptcrews 0:13b14c71d29e 988 void Adafruit_FONA::HTTP_para_start(const char* parameter, bool quoted) {
ptcrews 0:13b14c71d29e 989 flushInput();
ptcrews 0:13b14c71d29e 990
ptcrews 0:13b14c71d29e 991 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 992 printf("\t---> AT+HTTPPARA=\"%s\"\r\n", parameter);
ptcrews 0:13b14c71d29e 993 #endif
ptcrews 0:13b14c71d29e 994
ptcrews 0:13b14c71d29e 995 mySerial.printf("AT+HTTPPARA=\"%s", parameter);
ptcrews 0:13b14c71d29e 996 if (quoted)
ptcrews 0:13b14c71d29e 997 mySerial.printf("\",\"");
ptcrews 0:13b14c71d29e 998 else
ptcrews 0:13b14c71d29e 999 mySerial.printf("\",");
ptcrews 0:13b14c71d29e 1000 }
ptcrews 0:13b14c71d29e 1001
ptcrews 0:13b14c71d29e 1002 bool Adafruit_FONA::HTTP_para_end(bool quoted) {
ptcrews 0:13b14c71d29e 1003 if (quoted)
ptcrews 0:13b14c71d29e 1004 mySerial.printf("\"\r\n");
ptcrews 0:13b14c71d29e 1005 else
ptcrews 0:13b14c71d29e 1006 mySerial.printf("\r\n");
ptcrews 0:13b14c71d29e 1007
ptcrews 0:13b14c71d29e 1008 return expectReply("OK");
ptcrews 0:13b14c71d29e 1009 }
ptcrews 0:13b14c71d29e 1010
ptcrews 0:13b14c71d29e 1011 bool Adafruit_FONA::HTTP_para(const char* parameter, const char* value) {
ptcrews 0:13b14c71d29e 1012 HTTP_para_start(parameter, true);
ptcrews 0:13b14c71d29e 1013 mySerial.printf(value);
ptcrews 0:13b14c71d29e 1014 return HTTP_para_end(true);
ptcrews 0:13b14c71d29e 1015 }
ptcrews 0:13b14c71d29e 1016
ptcrews 0:13b14c71d29e 1017 bool Adafruit_FONA::HTTP_para(const char* parameter, int32_t value) {
ptcrews 0:13b14c71d29e 1018 HTTP_para_start(parameter, false);
ptcrews 0:13b14c71d29e 1019 mySerial.printf("%d", value);
ptcrews 0:13b14c71d29e 1020 return HTTP_para_end(false);
ptcrews 0:13b14c71d29e 1021 }
ptcrews 0:13b14c71d29e 1022
ptcrews 0:13b14c71d29e 1023 bool Adafruit_FONA::HTTP_data(uint32_t size, uint32_t maxTime) {
ptcrews 0:13b14c71d29e 1024 flushInput();
ptcrews 0:13b14c71d29e 1025
ptcrews 0:13b14c71d29e 1026 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1027 printf("\t---> AT+HTTPDATA=%d,%d\r\n", size, maxTime);
ptcrews 0:13b14c71d29e 1028 #endif
ptcrews 0:13b14c71d29e 1029
ptcrews 0:13b14c71d29e 1030 mySerial.printf("AT+HTTPDATA=%d,%d\r\n", size, maxTime);
ptcrews 0:13b14c71d29e 1031
ptcrews 0:13b14c71d29e 1032 return expectReply("DOWNLOAD");
ptcrews 0:13b14c71d29e 1033 }
ptcrews 0:13b14c71d29e 1034
ptcrews 0:13b14c71d29e 1035 bool Adafruit_FONA::HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout) {
ptcrews 0:13b14c71d29e 1036 // Send request.
ptcrews 0:13b14c71d29e 1037 if (! sendCheckReply("AT+HTTPACTION=", method, "OK"))
ptcrews 0:13b14c71d29e 1038 return false;
ptcrews 0:13b14c71d29e 1039
ptcrews 0:13b14c71d29e 1040 // Parse response status and size.
ptcrews 0:13b14c71d29e 1041 readline(timeout);
ptcrews 0:13b14c71d29e 1042 if (! parseReply("+HTTPACTION:", status, ',', 1))
ptcrews 0:13b14c71d29e 1043 return false;
ptcrews 0:13b14c71d29e 1044 if (! parseReply("+HTTPACTION:", datalen, ',', 2))
ptcrews 0:13b14c71d29e 1045 return false;
ptcrews 0:13b14c71d29e 1046
ptcrews 0:13b14c71d29e 1047 return true;
ptcrews 0:13b14c71d29e 1048 }
ptcrews 0:13b14c71d29e 1049
ptcrews 0:13b14c71d29e 1050 bool Adafruit_FONA::HTTP_readall(uint16_t *datalen) {
ptcrews 0:13b14c71d29e 1051 getReply("AT+HTTPREAD");
ptcrews 0:13b14c71d29e 1052 if (! parseReply("+HTTPREAD:", datalen, ',', 0))
ptcrews 0:13b14c71d29e 1053 return false;
ptcrews 0:13b14c71d29e 1054
ptcrews 0:13b14c71d29e 1055 return true;
ptcrews 0:13b14c71d29e 1056 }
ptcrews 0:13b14c71d29e 1057
ptcrews 0:13b14c71d29e 1058 bool Adafruit_FONA::HTTP_ssl(bool onoff) {
ptcrews 0:13b14c71d29e 1059 return sendCheckReply("AT+HTTPSSL=", onoff ? 1 : 0, "OK");
ptcrews 0:13b14c71d29e 1060 }
ptcrews 0:13b14c71d29e 1061
ptcrews 0:13b14c71d29e 1062 /********* HTTP HIGH LEVEL FUNCTIONS ***************************/
ptcrews 0:13b14c71d29e 1063
ptcrews 0:13b14c71d29e 1064 bool Adafruit_FONA::HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen){
ptcrews 0:13b14c71d29e 1065 if (! HTTP_setup(url))
ptcrews 0:13b14c71d29e 1066 return false;
ptcrews 0:13b14c71d29e 1067
ptcrews 0:13b14c71d29e 1068 // HTTP GET
ptcrews 0:13b14c71d29e 1069 if (! HTTP_action(FONA_HTTP_GET, status, datalen))
ptcrews 0:13b14c71d29e 1070 return false;
ptcrews 0:13b14c71d29e 1071
ptcrews 0:13b14c71d29e 1072 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1073 printf("Status: %d\r\n", *status);
ptcrews 0:13b14c71d29e 1074 printf("Len: %d\r\n", *datalen);
ptcrews 0:13b14c71d29e 1075 #endif
ptcrews 0:13b14c71d29e 1076
ptcrews 0:13b14c71d29e 1077 // HTTP response data
ptcrews 0:13b14c71d29e 1078 if (! HTTP_readall(datalen))
ptcrews 0:13b14c71d29e 1079 return false;
ptcrews 0:13b14c71d29e 1080
ptcrews 0:13b14c71d29e 1081 return true;
ptcrews 0:13b14c71d29e 1082 }
ptcrews 0:13b14c71d29e 1083
ptcrews 0:13b14c71d29e 1084 void Adafruit_FONA::HTTP_GET_end(void) {
ptcrews 0:13b14c71d29e 1085 HTTP_term();
ptcrews 0:13b14c71d29e 1086 }
ptcrews 0:13b14c71d29e 1087
ptcrews 0:13b14c71d29e 1088 bool Adafruit_FONA::HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen) {
ptcrews 0:13b14c71d29e 1089 if (! HTTP_setup(url))
ptcrews 0:13b14c71d29e 1090 return false;
ptcrews 0:13b14c71d29e 1091
ptcrews 0:13b14c71d29e 1092 if (! HTTP_para("CONTENT", contenttype)) {
ptcrews 0:13b14c71d29e 1093 return false;
ptcrews 0:13b14c71d29e 1094 }
ptcrews 0:13b14c71d29e 1095
ptcrews 0:13b14c71d29e 1096 // HTTP POST data
ptcrews 0:13b14c71d29e 1097 if (! HTTP_data(postdatalen, 10000))
ptcrews 0:13b14c71d29e 1098 return false;
ptcrews 0:13b14c71d29e 1099 for (uint16_t i = 0; i < postdatalen; i++) {
ptcrews 0:13b14c71d29e 1100 mySerial.putc(postdata[i]);
ptcrews 0:13b14c71d29e 1101 }
ptcrews 0:13b14c71d29e 1102 if (! expectReply("OK"))
ptcrews 0:13b14c71d29e 1103 return false;
ptcrews 0:13b14c71d29e 1104
ptcrews 0:13b14c71d29e 1105 // HTTP POST
ptcrews 0:13b14c71d29e 1106 if (! HTTP_action(FONA_HTTP_POST, status, datalen))
ptcrews 0:13b14c71d29e 1107 return false;
ptcrews 0:13b14c71d29e 1108
ptcrews 0:13b14c71d29e 1109 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1110 printf("Status: %d\r\n", *status);
ptcrews 0:13b14c71d29e 1111 printf("Len: %d\r\n", *datalen);
ptcrews 0:13b14c71d29e 1112 #endif
ptcrews 0:13b14c71d29e 1113
ptcrews 0:13b14c71d29e 1114 // HTTP response data
ptcrews 0:13b14c71d29e 1115 if (! HTTP_readall(datalen))
ptcrews 0:13b14c71d29e 1116 return false;
ptcrews 0:13b14c71d29e 1117
ptcrews 0:13b14c71d29e 1118 return true;
ptcrews 0:13b14c71d29e 1119 }
ptcrews 0:13b14c71d29e 1120
ptcrews 0:13b14c71d29e 1121 void Adafruit_FONA::HTTP_POST_end(void) {
ptcrews 0:13b14c71d29e 1122 HTTP_term();
ptcrews 0:13b14c71d29e 1123 }
ptcrews 0:13b14c71d29e 1124
ptcrews 0:13b14c71d29e 1125 void Adafruit_FONA::setUserAgent(const char* useragent) {
ptcrews 0:13b14c71d29e 1126 this->useragent = (char*) useragent;
ptcrews 0:13b14c71d29e 1127 }
ptcrews 0:13b14c71d29e 1128
ptcrews 0:13b14c71d29e 1129 void Adafruit_FONA::setHTTPSRedirect(bool onoff) {
ptcrews 0:13b14c71d29e 1130 httpsredirect = onoff;
ptcrews 0:13b14c71d29e 1131 }
ptcrews 0:13b14c71d29e 1132
ptcrews 0:13b14c71d29e 1133 /********* HTTP HELPERS ****************************************/
ptcrews 0:13b14c71d29e 1134
ptcrews 0:13b14c71d29e 1135 bool Adafruit_FONA::HTTP_setup(char *url) {
ptcrews 0:13b14c71d29e 1136 // Handle any pending
ptcrews 0:13b14c71d29e 1137 HTTP_term();
ptcrews 0:13b14c71d29e 1138
ptcrews 0:13b14c71d29e 1139 // Initialize and set parameters
ptcrews 0:13b14c71d29e 1140 if (! HTTP_init())
ptcrews 0:13b14c71d29e 1141 return false;
ptcrews 0:13b14c71d29e 1142 if (! HTTP_para("CID", 1))
ptcrews 0:13b14c71d29e 1143 return false;
ptcrews 0:13b14c71d29e 1144 if (! HTTP_para("UA", useragent))
ptcrews 0:13b14c71d29e 1145 return false;
ptcrews 0:13b14c71d29e 1146 if (! HTTP_para("URL", url))
ptcrews 0:13b14c71d29e 1147 return false;
ptcrews 0:13b14c71d29e 1148
ptcrews 0:13b14c71d29e 1149 // HTTPS redirect
ptcrews 0:13b14c71d29e 1150 if (httpsredirect) {
ptcrews 0:13b14c71d29e 1151 if (! HTTP_para("REDIR",1))
ptcrews 0:13b14c71d29e 1152 return false;
ptcrews 0:13b14c71d29e 1153
ptcrews 0:13b14c71d29e 1154 if (! HTTP_ssl(true))
ptcrews 0:13b14c71d29e 1155 return false;
ptcrews 0:13b14c71d29e 1156 }
ptcrews 0:13b14c71d29e 1157
ptcrews 0:13b14c71d29e 1158 return true;
ptcrews 0:13b14c71d29e 1159 }
ptcrews 0:13b14c71d29e 1160
ptcrews 0:13b14c71d29e 1161
ptcrews 0:13b14c71d29e 1162 /********* HELPERS *********************************************/
ptcrews 0:13b14c71d29e 1163
ptcrews 0:13b14c71d29e 1164 bool Adafruit_FONA::expectReply(const char* reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1165 readline(timeout);
ptcrews 0:13b14c71d29e 1166 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1167 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1168 #endif
ptcrews 0:13b14c71d29e 1169 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1170 }
ptcrews 0:13b14c71d29e 1171
ptcrews 0:13b14c71d29e 1172 /********* LOW LEVEL *******************************************/
ptcrews 0:13b14c71d29e 1173
ptcrews 0:13b14c71d29e 1174 void Adafruit_FONA::flushInput() {
ptcrews 0:13b14c71d29e 1175 // Read all available serial input to flush pending data.
ptcrews 0:13b14c71d29e 1176 uint16_t timeoutloop = 0;
ptcrews 0:13b14c71d29e 1177 while (timeoutloop++ < 40) {
ptcrews 0:13b14c71d29e 1178 while(readable()) {
ptcrews 0:13b14c71d29e 1179 getc();
ptcrews 0:13b14c71d29e 1180 timeoutloop = 0; // If char was received reset the timer
ptcrews 0:13b14c71d29e 1181 }
ptcrews 0:13b14c71d29e 1182 wait_ms(1);
ptcrews 0:13b14c71d29e 1183 }
ptcrews 0:13b14c71d29e 1184 }
ptcrews 0:13b14c71d29e 1185
ptcrews 0:13b14c71d29e 1186 uint16_t Adafruit_FONA::readRaw(uint16_t b) {
ptcrews 0:13b14c71d29e 1187 uint16_t idx = 0;
ptcrews 0:13b14c71d29e 1188
ptcrews 0:13b14c71d29e 1189 while (b && (idx < sizeof(replybuffer)-1)) {
ptcrews 0:13b14c71d29e 1190 if (readable()) {
ptcrews 0:13b14c71d29e 1191 replybuffer[idx] = getc();
ptcrews 0:13b14c71d29e 1192 idx++;
ptcrews 0:13b14c71d29e 1193 b--;
ptcrews 0:13b14c71d29e 1194 }
ptcrews 0:13b14c71d29e 1195 }
ptcrews 0:13b14c71d29e 1196 replybuffer[idx] = 0;
ptcrews 0:13b14c71d29e 1197
ptcrews 0:13b14c71d29e 1198 return idx;
ptcrews 0:13b14c71d29e 1199 }
ptcrews 0:13b14c71d29e 1200
ptcrews 0:13b14c71d29e 1201 uint8_t Adafruit_FONA::readline(uint16_t timeout, bool multiline) {
ptcrews 0:13b14c71d29e 1202 uint16_t replyidx = 0;
ptcrews 0:13b14c71d29e 1203
ptcrews 0:13b14c71d29e 1204 while (timeout--) {
ptcrews 0:13b14c71d29e 1205 if (replyidx >= 254) {
ptcrews 0:13b14c71d29e 1206 break;
ptcrews 0:13b14c71d29e 1207 }
ptcrews 0:13b14c71d29e 1208
ptcrews 0:13b14c71d29e 1209 while(readable()) {
ptcrews 0:13b14c71d29e 1210 char c = getc();
ptcrews 0:13b14c71d29e 1211 if (c == '\r') continue;
ptcrews 0:13b14c71d29e 1212 if (c == 0xA) {
ptcrews 0:13b14c71d29e 1213 if (replyidx == 0) // the first 0x0A is ignored
ptcrews 0:13b14c71d29e 1214 continue;
ptcrews 0:13b14c71d29e 1215
ptcrews 0:13b14c71d29e 1216 if (!multiline) {
ptcrews 0:13b14c71d29e 1217 timeout = 0; // the second 0x0A is the end of the line
ptcrews 0:13b14c71d29e 1218 break;
ptcrews 0:13b14c71d29e 1219 }
ptcrews 0:13b14c71d29e 1220 }
ptcrews 0:13b14c71d29e 1221 replybuffer[replyidx] = c;
ptcrews 0:13b14c71d29e 1222 replyidx++;
ptcrews 0:13b14c71d29e 1223 }
ptcrews 0:13b14c71d29e 1224
ptcrews 0:13b14c71d29e 1225 if (timeout == 0) {
ptcrews 0:13b14c71d29e 1226 break;
ptcrews 0:13b14c71d29e 1227 }
ptcrews 0:13b14c71d29e 1228 wait_ms(1);
ptcrews 0:13b14c71d29e 1229 }
ptcrews 0:13b14c71d29e 1230 replybuffer[replyidx] = 0; // null term
ptcrews 0:13b14c71d29e 1231 return replyidx;
ptcrews 0:13b14c71d29e 1232 }
ptcrews 0:13b14c71d29e 1233
ptcrews 0:13b14c71d29e 1234 uint8_t Adafruit_FONA::getReply(const char* send, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1235 flushInput();
ptcrews 0:13b14c71d29e 1236
ptcrews 0:13b14c71d29e 1237 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1238 printf("\t---> %s\r\n", send);
ptcrews 0:13b14c71d29e 1239 #endif
ptcrews 0:13b14c71d29e 1240
ptcrews 0:13b14c71d29e 1241 mySerial.printf("%s\r\n",send);
ptcrews 0:13b14c71d29e 1242
ptcrews 0:13b14c71d29e 1243 uint8_t l = readline(timeout);
ptcrews 0:13b14c71d29e 1244 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1245 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1246 #endif
ptcrews 0:13b14c71d29e 1247 return l;
ptcrews 0:13b14c71d29e 1248 }
ptcrews 0:13b14c71d29e 1249
ptcrews 0:13b14c71d29e 1250 // Send prefix, suffix, and newline. Return response (and also set replybuffer with response).
ptcrews 0:13b14c71d29e 1251 uint8_t Adafruit_FONA::getReply(const char* prefix, char* suffix, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1252 flushInput();
ptcrews 0:13b14c71d29e 1253
ptcrews 0:13b14c71d29e 1254 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1255 printf("\t---> %s%s\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1256 #endif
ptcrews 0:13b14c71d29e 1257
ptcrews 0:13b14c71d29e 1258 mySerial.printf("%s%s\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1259
ptcrews 0:13b14c71d29e 1260 uint8_t l = readline(timeout);
ptcrews 0:13b14c71d29e 1261 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1262 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1263 #endif
ptcrews 0:13b14c71d29e 1264 return l;
ptcrews 0:13b14c71d29e 1265 }
ptcrews 0:13b14c71d29e 1266
ptcrews 0:13b14c71d29e 1267 // Send prefix, suffix, and newline. Return response (and also set replybuffer with response).
ptcrews 0:13b14c71d29e 1268 uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1269 flushInput();
ptcrews 0:13b14c71d29e 1270
ptcrews 0:13b14c71d29e 1271 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1272 printf("\t---> %s%d\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1273 #endif
ptcrews 0:13b14c71d29e 1274
ptcrews 0:13b14c71d29e 1275 mySerial.printf("%s%d\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1276
ptcrews 0:13b14c71d29e 1277 uint8_t l = readline(timeout);
ptcrews 0:13b14c71d29e 1278 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1279 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1280 #endif
ptcrews 0:13b14c71d29e 1281 return l;
ptcrews 0:13b14c71d29e 1282 }
ptcrews 0:13b14c71d29e 1283
ptcrews 0:13b14c71d29e 1284 // Send prefix, suffix, suffix2, and newline. Return response (and also set replybuffer with response).
ptcrews 0:13b14c71d29e 1285 uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix1, int32_t suffix2, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1286 flushInput();
ptcrews 0:13b14c71d29e 1287
ptcrews 0:13b14c71d29e 1288 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1289 printf("\t---> %s%d,%d\r\n", prefix, suffix1, suffix2);
ptcrews 0:13b14c71d29e 1290 #endif
ptcrews 0:13b14c71d29e 1291
ptcrews 0:13b14c71d29e 1292 mySerial.printf("%s%d,%d\r\n", prefix, suffix1, suffix2);
ptcrews 0:13b14c71d29e 1293
ptcrews 0:13b14c71d29e 1294 uint8_t l = readline(timeout);
ptcrews 0:13b14c71d29e 1295 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1296 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1297 #endif
ptcrews 0:13b14c71d29e 1298 return l;
ptcrews 0:13b14c71d29e 1299 }
ptcrews 0:13b14c71d29e 1300
ptcrews 0:13b14c71d29e 1301 // Send prefix, ", suffix, ", and newline. Return response (and also set replybuffer with response).
ptcrews 0:13b14c71d29e 1302 uint8_t Adafruit_FONA::getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1303 flushInput();
ptcrews 0:13b14c71d29e 1304
ptcrews 0:13b14c71d29e 1305 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1306 printf("\t---> %s\"%s\"\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1307 #endif
ptcrews 0:13b14c71d29e 1308
ptcrews 0:13b14c71d29e 1309 mySerial.printf("%s\"%s\"\r\n", prefix, suffix);
ptcrews 0:13b14c71d29e 1310
ptcrews 0:13b14c71d29e 1311 uint8_t l = readline(timeout);
ptcrews 0:13b14c71d29e 1312 #ifdef ADAFRUIT_FONA_DEBUG
ptcrews 0:13b14c71d29e 1313 printf("\t<--- %s\r\n", replybuffer);
ptcrews 0:13b14c71d29e 1314 #endif
ptcrews 0:13b14c71d29e 1315 return l;
ptcrews 0:13b14c71d29e 1316 }
ptcrews 0:13b14c71d29e 1317
ptcrews 0:13b14c71d29e 1318
ptcrews 0:13b14c71d29e 1319 bool Adafruit_FONA::sendCheckReply(const char *send, const char *reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1320 getReply(send, timeout);
ptcrews 0:13b14c71d29e 1321
ptcrews 0:13b14c71d29e 1322 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1323 }
ptcrews 0:13b14c71d29e 1324
ptcrews 0:13b14c71d29e 1325 // Send prefix, suffix, and newline. Verify FONA response matches reply parameter.
ptcrews 0:13b14c71d29e 1326 bool Adafruit_FONA::sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1327 getReply(prefix, suffix, timeout);
ptcrews 0:13b14c71d29e 1328 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1329 }
ptcrews 0:13b14c71d29e 1330
ptcrews 0:13b14c71d29e 1331 // Send prefix, suffix, and newline. Verify FONA response matches reply parameter.
ptcrews 0:13b14c71d29e 1332 bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1333 getReply(prefix, suffix, timeout);
ptcrews 0:13b14c71d29e 1334 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1335 }
ptcrews 0:13b14c71d29e 1336
ptcrews 0:13b14c71d29e 1337 // Send prefix, suffix, suffix2, and newline. Verify FONA response matches reply parameter.
ptcrews 0:13b14c71d29e 1338 bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix1, int32_t suffix2, const char* reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1339 getReply(prefix, suffix1, suffix2, timeout);
ptcrews 0:13b14c71d29e 1340 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1341 }
ptcrews 0:13b14c71d29e 1342
ptcrews 0:13b14c71d29e 1343 // Send prefix, ", suffix, ", and newline. Verify FONA response matches reply parameter.
ptcrews 0:13b14c71d29e 1344 bool Adafruit_FONA::sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout) {
ptcrews 0:13b14c71d29e 1345 getReplyQuoted(prefix, suffix, timeout);
ptcrews 0:13b14c71d29e 1346 return (strcmp(replybuffer, reply) == 0);
ptcrews 0:13b14c71d29e 1347 }
ptcrews 0:13b14c71d29e 1348
ptcrews 0:13b14c71d29e 1349 bool Adafruit_FONA::parseReply(const char* toreply, uint16_t *v, char divider, uint8_t index) {
ptcrews 0:13b14c71d29e 1350 char *p = strstr(replybuffer, toreply); // get the pointer to the voltage
ptcrews 0:13b14c71d29e 1351 if (p == 0) return false;
ptcrews 0:13b14c71d29e 1352 p += strlen(toreply);
ptcrews 0:13b14c71d29e 1353
ptcrews 0:13b14c71d29e 1354 for (uint8_t i=0; i<index;i++) {
ptcrews 0:13b14c71d29e 1355 // increment dividers
ptcrews 0:13b14c71d29e 1356 p = strchr(p, divider);
ptcrews 0:13b14c71d29e 1357 if (!p) return false;
ptcrews 0:13b14c71d29e 1358 p++;
ptcrews 0:13b14c71d29e 1359 }
ptcrews 0:13b14c71d29e 1360
ptcrews 0:13b14c71d29e 1361 *v = atoi(p);
ptcrews 0:13b14c71d29e 1362
ptcrews 0:13b14c71d29e 1363 return true;
ptcrews 0:13b14c71d29e 1364 }
ptcrews 0:13b14c71d29e 1365
ptcrews 0:13b14c71d29e 1366 bool Adafruit_FONA::parseReply(const char* toreply, char *v, char divider, uint8_t index) {
ptcrews 0:13b14c71d29e 1367 uint8_t i=0;
ptcrews 0:13b14c71d29e 1368 char *p = strstr(replybuffer, toreply);
ptcrews 0:13b14c71d29e 1369 if (p == 0) return false;
ptcrews 0:13b14c71d29e 1370 p+=strlen(toreply);
ptcrews 0:13b14c71d29e 1371
ptcrews 0:13b14c71d29e 1372 for (i=0; i<index;i++) {
ptcrews 0:13b14c71d29e 1373 // increment dividers
ptcrews 0:13b14c71d29e 1374 p = strchr(p, divider);
ptcrews 0:13b14c71d29e 1375 if (!p) return false;
ptcrews 0:13b14c71d29e 1376 p++;
ptcrews 0:13b14c71d29e 1377 }
ptcrews 0:13b14c71d29e 1378
ptcrews 0:13b14c71d29e 1379 for(i=0; i<strlen(p);i++) {
ptcrews 0:13b14c71d29e 1380 if(p[i] == divider)
ptcrews 0:13b14c71d29e 1381 break;
ptcrews 0:13b14c71d29e 1382 v[i] = p[i];
ptcrews 0:13b14c71d29e 1383 }
ptcrews 0:13b14c71d29e 1384
ptcrews 0:13b14c71d29e 1385 v[i] = '\0';
ptcrews 0:13b14c71d29e 1386
ptcrews 0:13b14c71d29e 1387 return true;
ptcrews 0:13b14c71d29e 1388 }
ptcrews 0:13b14c71d29e 1389
ptcrews 0:13b14c71d29e 1390 // Parse a quoted string in the response fields and copy its value (without quotes)
ptcrews 0:13b14c71d29e 1391 // to the specified character array (v). Only up to maxlen characters are copied
ptcrews 0:13b14c71d29e 1392 // into the result buffer, so make sure to pass a large enough buffer to handle the
ptcrews 0:13b14c71d29e 1393 // response.
ptcrews 0:13b14c71d29e 1394 bool Adafruit_FONA::parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index) {
ptcrews 0:13b14c71d29e 1395 uint8_t i=0, j;
ptcrews 0:13b14c71d29e 1396 // Verify response starts with toreply.
ptcrews 0:13b14c71d29e 1397 char *p = strstr(replybuffer, toreply);
ptcrews 0:13b14c71d29e 1398 if (p == 0) return false;
ptcrews 0:13b14c71d29e 1399 p+=strlen(toreply);
ptcrews 0:13b14c71d29e 1400
ptcrews 0:13b14c71d29e 1401 // Find location of desired response field.
ptcrews 0:13b14c71d29e 1402 for (i=0; i<index;i++) {
ptcrews 0:13b14c71d29e 1403 // increment dividers
ptcrews 0:13b14c71d29e 1404 p = strchr(p, divider);
ptcrews 0:13b14c71d29e 1405 if (!p) return false;
ptcrews 0:13b14c71d29e 1406 p++;
ptcrews 0:13b14c71d29e 1407 }
ptcrews 0:13b14c71d29e 1408
ptcrews 0:13b14c71d29e 1409 // Copy characters from response field into result string.
ptcrews 0:13b14c71d29e 1410 for(i=0, j=0; j<maxlen && i<strlen(p); ++i) {
ptcrews 0:13b14c71d29e 1411 // Stop if a divier is found.
ptcrews 0:13b14c71d29e 1412 if(p[i] == divider)
ptcrews 0:13b14c71d29e 1413 break;
ptcrews 0:13b14c71d29e 1414 // Skip any quotation marks.
ptcrews 0:13b14c71d29e 1415 else if(p[i] == '"')
ptcrews 0:13b14c71d29e 1416 continue;
ptcrews 0:13b14c71d29e 1417 v[j++] = p[i];
ptcrews 0:13b14c71d29e 1418 }
ptcrews 0:13b14c71d29e 1419
ptcrews 0:13b14c71d29e 1420 // Add a null terminator if result string buffer was not filled.
ptcrews 0:13b14c71d29e 1421 if (j < maxlen)
ptcrews 0:13b14c71d29e 1422 v[j] = '\0';
ptcrews 0:13b14c71d29e 1423
ptcrews 0:13b14c71d29e 1424 return true;
ptcrews 0:13b14c71d29e 1425 }
ptcrews 0:13b14c71d29e 1426
ptcrews 0:13b14c71d29e 1427 bool Adafruit_FONA::sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider, uint8_t index) {
ptcrews 0:13b14c71d29e 1428 getReply(tosend);
ptcrews 0:13b14c71d29e 1429
ptcrews 0:13b14c71d29e 1430 if (! parseReply(toreply, v, divider, index)) return false;
ptcrews 0:13b14c71d29e 1431
ptcrews 0:13b14c71d29e 1432 readline(); // eat 'OK'
ptcrews 0:13b14c71d29e 1433
ptcrews 0:13b14c71d29e 1434 return true;
ptcrews 0:13b14c71d29e 1435 }