screen display for roommate tracker

Dependencies:   mbed-rtos mbed uLCD_4D_Picaso

Dependents:   RoommateTracker

Committer:
jbaker66
Date:
Mon Apr 25 14:07:25 2016 +0000
Revision:
0:831eff5e20cb
screen display complete

Who changed what in which revision?

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