Allows SMS to be sent to query Alexa. Also allows HTTP requests to be sent to Alexa via an ESP8266-hosted web server.

Dependencies:   emic2 mbed

Committer:
itatchi42
Date:
Tue May 02 03:13:27 2017 +0000
Revision:
0:1271d15b4d4b
Allows SMS communication with Amazon Dot's Alexa.; Also allows URL queries to be sent to ESP8266-hosted HTTP server to communicate with Alexa.

Who changed what in which revision?

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