Program that uses Adafruit FONA 800h and resistive touch uLCD display to track roommates and send and receive text messages.

Dependencies:   mbed-rtos mbed uLCD_4D_Picaso

Committer:
coleandbrandon
Date:
Sun May 01 21:31:25 2016 +0000
Revision:
0:0b0487606b13
program complete JB GT

Who changed what in which revision?

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