Version working with mbed-os

Dependents:  

Fork of Adafruit_FONA_Library by Jesse van Rhijn

Committer:
zathorix
Date:
Wed May 24 09:19:56 2017 +0000
Revision:
8:aacbc647caee
Parent:
6:b675eab1c47a
Changed some print statements

Who changed what in which revision?

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