screen display for roommate tracker
Dependencies: mbed-rtos mbed uLCD_4D_Picaso
Adafruit_FONA.cpp
00001 /*************************************************** 00002 This is a library for our Adafruit FONA Cellular Module 00003 00004 Designed specifically to work with the Adafruit FONA 00005 ----> http://www.adafruit.com/products/1946 00006 ----> http://www.adafruit.com/products/1963 00007 00008 These displays use TTL Serial to communicate, 2 pins are required to 00009 interface 00010 Adafruit invests time and resources providing this open source code, 00011 please support Adafruit and open-source hardware by purchasing 00012 products from Adafruit! 00013 00014 Written by Limor Fried/Ladyada for Adafruit Industries. 00015 BSD license, all text above must be included in any redistribution 00016 ****************************************************/ 00017 00018 /* 00019 * Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768 00020 */ 00021 #include <algorithm> 00022 #include "Adafruit_FONA.h" 00023 00024 #define HIGH 1 00025 #define LOW 0 00026 00027 /* 00028 Notes George is taking: 00029 sendCheckReply returns a boolean where its true when FONA responds with the string of its second input 00030 00031 */ 00032 00033 00034 bool Adafruit_FONA::begin(int baudrate) { 00035 mySerial.baud(baudrate); //set the baud rate of the fona serial connection 00036 mySerial.attach(this, &Adafruit_FONA::onSerialDataReceived, Serial::RxIrq); //attached onSerialDataReceived as Serial receive interrupt 00037 00038 // INIT Reboot process 00039 _rstpin = HIGH; 00040 wait_ms(10); 00041 _rstpin = LOW; 00042 wait_ms(100); 00043 _rstpin = HIGH; 00044 00045 // give 3 seconds to reboot 00046 wait_ms(3000); 00047 00048 // flushes the serial port 00049 while (readable()) getc(); 00050 00051 // Make sure FONA is alive 00052 sendCheckReply("AT", "OK"); 00053 wait_ms(100); 00054 sendCheckReply("AT", "OK"); 00055 wait_ms(100); 00056 sendCheckReply("AT", "OK"); 00057 wait_ms(100); 00058 00059 // turn off Echo! 00060 sendCheckReply("ATE0", "OK"); 00061 wait_ms(100); 00062 00063 // Just checks if the FONA even responds, if it doesnt, then return false 00064 if (! sendCheckReply("ATE0", "OK")) { 00065 return false; 00066 } 00067 00068 return true; 00069 } 00070 00071 void Adafruit_FONA::setEventListener(EventListener *eventListener) { 00072 this->eventListener = eventListener; 00073 } 00074 00075 /********* Stream ********************************************/ 00076 00077 int Adafruit_FONA::_putc(int value) { 00078 return mySerial.putc(value); 00079 } 00080 00081 int Adafruit_FONA::_getc() { 00082 __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables 00083 00084 // Wait for data if the buffer is empty 00085 if (isRxBufferEmpty()) { 00086 __enable_irq(); // End Critical Section - need to allow rx interrupt to get new characters for buffer 00087 00088 while(isRxBufferEmpty()); 00089 00090 __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables 00091 } 00092 00093 int data = rxBuffer[rxBufferOutIndex]; 00094 incrementRxBufferOutIndex(); 00095 00096 __enable_irq(); // End Critical Section 00097 00098 return data; 00099 } 00100 00101 int Adafruit_FONA::readable() { 00102 return !isRxBufferEmpty(); 00103 } 00104 00105 void Adafruit_FONA::onSerialDataReceived() { 00106 while (mySerial.readable() && !isRxBufferFull()) { 00107 int data = mySerial.getc(); 00108 rxBuffer[rxBufferInIndex] = data; 00109 00110 // 00111 // Analyze the received data in order to detect events like RING or NO CARRIER 00112 // 00113 00114 // Copy the data in the current line 00115 if (currentReceivedLineSize < RX_BUFFER_SIZE && data != '\r' && data != '\n') { 00116 currentReceivedLine[currentReceivedLineSize] = (char) data; 00117 currentReceivedLineSize++; 00118 } 00119 00120 // Check if the line is complete 00121 if (data == '\n') { 00122 currentReceivedLine[currentReceivedLineSize] = 0; 00123 00124 if (eventListener != NULL) { 00125 // Check if we have a special event 00126 if (strcmp(currentReceivedLine, "RING") == 0) { 00127 eventListener->onRing(); 00128 } else if (strcmp(currentReceivedLine, "NO CARRIER") == 0) { 00129 eventListener->onNoCarrier(); 00130 } 00131 } 00132 00133 currentReceivedLineSize = 0; 00134 } 00135 00136 incrementRxBufferInIndex(); 00137 } 00138 } 00139 00140 /********* Real Time Clock ********************************************/ 00141 00142 bool Adafruit_FONA::enableRTC(uint8_t i) { 00143 if (! sendCheckReply("AT+CLTS=", i, "OK")) 00144 return false; 00145 return sendCheckReply("AT&W", "OK"); 00146 } 00147 00148 /********* BATTERY & ADC ********************************************/ 00149 00150 /* returns value in mV (uint16_t) */ 00151 bool Adafruit_FONA::getBattVoltage(uint16_t *v) { 00152 return sendParseReply("AT+CBC", "+CBC: ", v, ',', 2); 00153 } 00154 00155 /* returns the percentage charge of battery as reported by sim800 */ 00156 bool Adafruit_FONA::getBattPercent(uint16_t *p) { 00157 return sendParseReply("AT+CBC", "+CBC: ", p, ',', 1); 00158 } 00159 00160 bool Adafruit_FONA::getADCVoltage(uint16_t *v) { 00161 return sendParseReply("AT+CADC?", "+CADC: 1,", v); 00162 } 00163 00164 /********* SIM ***********************************************************/ 00165 00166 bool Adafruit_FONA::unlockSIM(char *pin) 00167 { 00168 char sendbuff[14] = "AT+CPIN="; 00169 sendbuff[8] = pin[0]; 00170 sendbuff[9] = pin[1]; 00171 sendbuff[10] = pin[2]; 00172 sendbuff[11] = pin[3]; 00173 sendbuff[12] = NULL; 00174 00175 return sendCheckReply(sendbuff, "OK"); 00176 } 00177 00178 uint8_t Adafruit_FONA::getSIMCCID(char *ccid) { 00179 getReply("AT+CCID"); 00180 // up to 20 chars 00181 strncpy(ccid, replybuffer, 20); 00182 ccid[20] = 0; 00183 00184 readline(); // eat 'OK' 00185 00186 return strlen(ccid); 00187 } 00188 00189 /********* IMEI **********************************************************/ 00190 00191 uint8_t Adafruit_FONA::getIMEI(char *imei) { 00192 getReply("AT+GSN"); 00193 00194 // up to 15 chars 00195 strncpy(imei, replybuffer, 15); 00196 imei[15] = 0; 00197 00198 readline(); // eat 'OK' 00199 00200 return strlen(imei); 00201 } 00202 00203 /********* NETWORK *******************************************************/ 00204 00205 uint8_t Adafruit_FONA::getNetworkStatus(void) { 00206 uint16_t status; 00207 00208 if (! sendParseReply("AT+CREG?", "+CREG: ", &status, ',', 1)) return 0; 00209 00210 return status; 00211 } 00212 00213 00214 uint8_t Adafruit_FONA::getRSSI(void) { 00215 uint16_t reply; 00216 00217 if (! sendParseReply("AT+CSQ", "+CSQ: ", &reply) ) return 0; 00218 00219 return reply; 00220 } 00221 00222 /********* AUDIO *******************************************************/ 00223 00224 bool Adafruit_FONA::setAudio(uint8_t a) { 00225 // 0 is headset, 1 is external audio 00226 if (a > 1) return false; 00227 00228 return sendCheckReply("AT+CHFA=", a, "OK"); 00229 } 00230 00231 uint8_t Adafruit_FONA::getVolume(void) { 00232 uint16_t reply; 00233 00234 if (! sendParseReply("AT+CLVL?", "+CLVL: ", &reply) ) return 0; 00235 00236 return reply; 00237 } 00238 00239 bool Adafruit_FONA::setVolume(uint8_t i) { 00240 return sendCheckReply("AT+CLVL=", i, "OK"); 00241 } 00242 00243 00244 bool Adafruit_FONA::playDTMF(char dtmf) { 00245 char str[4]; 00246 str[0] = '\"'; 00247 str[1] = dtmf; 00248 str[2] = '\"'; 00249 str[3] = 0; 00250 return sendCheckReply("AT+CLDTMF=3,", str, "OK"); 00251 } 00252 00253 bool Adafruit_FONA::playToolkitTone(uint8_t t, uint16_t len) { 00254 return sendCheckReply("AT+STTONE=1,", t, len, "OK"); 00255 } 00256 00257 bool Adafruit_FONA::setMicVolume(uint8_t a, uint8_t level) { 00258 // 0 is headset, 1 is external audio 00259 if (a > 1) return false; 00260 00261 return sendCheckReply("AT+CMIC=", a, level, "OK"); 00262 } 00263 00264 /********* FM RADIO *******************************************************/ 00265 00266 00267 bool Adafruit_FONA::FMradio(bool onoff, uint8_t a) { 00268 if (! onoff) { 00269 return sendCheckReply("AT+FMCLOSE", "OK"); 00270 } 00271 00272 // 0 is headset, 1 is external audio 00273 if (a > 1) return false; 00274 00275 return sendCheckReply("AT+FMOPEN=", a, "OK"); 00276 } 00277 00278 bool Adafruit_FONA::tuneFMradio(uint16_t station) { 00279 // Fail if FM station is outside allowed range. 00280 if ((station < 870) || (station > 1090)) 00281 return false; 00282 00283 return sendCheckReply("AT+FMFREQ=", station, "OK"); 00284 } 00285 00286 bool Adafruit_FONA::setFMVolume(uint8_t i) { 00287 // Fail if volume is outside allowed range (0-6). 00288 if (i > 6) { 00289 return false; 00290 } 00291 // Send FM volume command and verify response. 00292 return sendCheckReply("AT+FMVOLUME=", i, "OK"); 00293 } 00294 00295 int8_t Adafruit_FONA::getFMVolume() { 00296 uint16_t level; 00297 00298 if (! sendParseReply("AT+FMVOLUME?", "+FMVOLUME: ", &level) ) return 0; 00299 00300 return level; 00301 } 00302 00303 int8_t Adafruit_FONA::getFMSignalLevel(uint16_t station) { 00304 // Fail if FM station is outside allowed range. 00305 if ((station < 875) || (station > 1080)) { 00306 return -1; 00307 } 00308 00309 // Send FM signal level query command. 00310 // Note, need to explicitly send timeout so right overload is chosen. 00311 getReply("AT+FMSIGNAL=", station, FONA_DEFAULT_TIMEOUT_MS); 00312 // Check response starts with expected value. 00313 char *p = strstr(replybuffer, "+FMSIGNAL: "); 00314 if (p == 0) return -1; 00315 p+=11; 00316 // Find second colon to get start of signal quality. 00317 p = strchr(p, ':'); 00318 if (p == 0) return -1; 00319 p+=1; 00320 // Parse signal quality. 00321 int8_t level = atoi(p); 00322 readline(); // eat the "OK" 00323 return level; 00324 } 00325 00326 /********* PWM/BUZZER **************************************************/ 00327 00328 bool Adafruit_FONA::setPWM(uint16_t period, uint8_t duty) { 00329 if (period > 2000) return false; 00330 if (duty > 100) return false; 00331 00332 return sendCheckReply("AT+SPWM=0,", period, duty, "OK"); 00333 } 00334 00335 /********* CALL PHONES **************************************************/ 00336 bool Adafruit_FONA::callPhone(char *number) { 00337 char sendbuff[35] = "ATD"; 00338 strncpy(sendbuff+3, number, min((int)30, (int)strlen(number))); 00339 uint8_t x = strlen(sendbuff); 00340 sendbuff[x] = ';'; 00341 sendbuff[x+1] = 0; 00342 00343 return sendCheckReply(sendbuff, "OK"); 00344 } 00345 00346 bool Adafruit_FONA::hangUp(void) { 00347 return sendCheckReply("ATH0", "OK"); 00348 } 00349 00350 bool Adafruit_FONA::pickUp(void) { 00351 return sendCheckReply("ATA", "OK"); 00352 } 00353 00354 void Adafruit_FONA::onIncomingCall() { 00355 #ifdef ADAFRUIT_FONA_DEBUG 00356 printf("> Incoming call...\r\n"); 00357 #endif 00358 _incomingCall = true; 00359 } 00360 00361 bool Adafruit_FONA::callerIdNotification(bool enable) { 00362 if(enable){ 00363 _ringIndicatorInterruptIn.fall(this, &Adafruit_FONA::onIncomingCall); 00364 return sendCheckReply("AT+CLIP=1", "OK"); 00365 } 00366 00367 _ringIndicatorInterruptIn.fall(NULL); 00368 return sendCheckReply("AT+CLIP=0", "OK"); 00369 } 00370 00371 bool Adafruit_FONA::incomingCallNumber(char* phonenum) { 00372 //+CLIP: "<incoming phone number>",145,"",0,"",0 00373 if(!_incomingCall) 00374 return false; 00375 00376 readline(); 00377 while(!strcmp(replybuffer, "RING") == 0) { 00378 flushInput(); 00379 readline(); 00380 } 00381 00382 readline(); //reads incoming phone number line 00383 00384 parseReply("+CLIP: \"", phonenum, '"'); 00385 00386 #ifdef ADAFRUIT_FONA_DEBUG 00387 printf("Phone Number: %s\r\n", replybuffer); 00388 #endif 00389 00390 _incomingCall = false; 00391 return true; 00392 } 00393 00394 /********* SMS **********************************************************/ 00395 00396 uint8_t Adafruit_FONA::getSMSInterrupt(void) { 00397 uint16_t reply; 00398 00399 if (! sendParseReply("AT+CFGRI?", "+CFGRI: ", &reply) ) return 0; 00400 00401 return reply; 00402 } 00403 00404 bool Adafruit_FONA::setSMSInterrupt(uint8_t i) { 00405 return sendCheckReply("AT+CFGRI=", i, "OK"); 00406 } 00407 00408 int8_t Adafruit_FONA::getNumSMS(void) { 00409 uint16_t numsms; 00410 00411 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1; 00412 // ask how many sms are stored 00413 00414 if (! sendParseReply("AT+CPMS?", "+CPMS: \"SM_P\",", &numsms) ) return -1; 00415 00416 return numsms; 00417 } 00418 00419 // Reading SMS's is a bit involved so we don't use helpers that may cause delays or debug 00420 // printouts! 00421 bool Adafruit_FONA::readSMS(uint8_t i, char *smsbuff, uint16_t maxlen, uint16_t *readlen) { 00422 // text mode 00423 if (! sendCheckReply("AT+CMGF=1", "OK")) return false; 00424 00425 // show all text mode parameters 00426 if (! sendCheckReply("AT+CSDH=1", "OK")) return false; 00427 00428 // parse out the SMS len 00429 uint16_t thesmslen = 0; 00430 00431 //getReply(F("AT+CMGR="), i, 1000); // do not print debug! 00432 mySerial.printf("AT+CMGR=%d\r\n", i); 00433 readline(1000); // timeout 00434 00435 // parse it out... 00436 if (! parseReply("+CMGR:", &thesmslen, ',', 11)) { 00437 *readlen = 0; 00438 return false; 00439 } 00440 00441 readRaw(thesmslen); 00442 00443 flushInput(); 00444 00445 uint16_t thelen = min(maxlen, (uint16_t)strlen(replybuffer)); 00446 strncpy(smsbuff, replybuffer, thelen); 00447 smsbuff[thelen] = 0; // end the string 00448 00449 #ifdef ADAFRUIT_FONA_DEBUG 00450 printf("%s\r\n", replybuffer); 00451 #endif 00452 *readlen = thelen; 00453 return true; 00454 } 00455 00456 // Retrieve the sender of the specified SMS message and copy it as a string to 00457 // the sender buffer. Up to senderlen characters of the sender will be copied 00458 // and a null terminator will be added if less than senderlen charactesr are 00459 // copied to the result. Returns true if a result was successfully retrieved, 00460 // otherwise false. 00461 bool Adafruit_FONA::getSMSSender(uint8_t i, char *sender, int senderlen) { 00462 // Ensure text mode and all text mode parameters are sent. 00463 if (! sendCheckReply("AT+CMGF=1", "OK")) return false; 00464 if (! sendCheckReply("AT+CSDH=1", "OK")) return false; 00465 // Send command to retrieve SMS message and parse a line of response. 00466 mySerial.printf("AT+CMGR=%d\r\n", i); 00467 readline(1000); 00468 // Parse the second field in the response. 00469 bool result = parseReplyQuoted("+CMGR:", sender, senderlen, ',', 1); 00470 // Drop any remaining data from the response. 00471 flushInput(); 00472 return result; 00473 } 00474 00475 bool Adafruit_FONA::sendSMS(char *smsaddr, char *smsmsg) { 00476 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1; 00477 00478 char sendcmd[30] = "AT+CMGS=\""; 00479 strncpy(sendcmd+9, smsaddr, 30-9-2); // 9 bytes beginning, 2 bytes for close quote + null 00480 sendcmd[strlen(sendcmd)] = '\"'; 00481 00482 if (! sendCheckReply(sendcmd, "> ")) return false; 00483 #ifdef ADAFRUIT_FONA_DEBUG 00484 printf("> %s\r\n", smsmsg); 00485 #endif 00486 mySerial.printf("%s\r\n\r\n", smsmsg); 00487 mySerial.putc(0x1A); 00488 #ifdef ADAFRUIT_FONA_DEBUG 00489 printf("^Z\r\n"); 00490 #endif 00491 readline(10000); // read the +CMGS reply, wait up to 10 seconds!!! 00492 //Serial.print("* "); Serial.println(replybuffer); 00493 if (strstr(replybuffer, "+CMGS") == 0) { 00494 return false; 00495 } 00496 readline(1000); // read OK 00497 //Serial.print("* "); Serial.println(replybuffer); 00498 00499 if (strcmp(replybuffer, "OK") != 0) { 00500 return false; 00501 } 00502 00503 return true; 00504 } 00505 00506 00507 bool Adafruit_FONA::deleteSMS(uint8_t i) { 00508 if (! sendCheckReply("AT+CMGF=1", "OK")) return -1; 00509 // read an sms 00510 char sendbuff[12] = "AT+CMGD=000"; 00511 sendbuff[8] = (i / 100) + '0'; 00512 i %= 100; 00513 sendbuff[9] = (i / 10) + '0'; 00514 i %= 10; 00515 sendbuff[10] = i + '0'; 00516 00517 return sendCheckReply(sendbuff, "OK", 2000); 00518 } 00519 00520 /********* TIME **********************************************************/ 00521 00522 bool Adafruit_FONA::enableNetworkTimeSync(bool onoff) { 00523 if (onoff) { 00524 if (! sendCheckReply("AT+CLTS=1", "OK")) 00525 return false; 00526 } else { 00527 if (! sendCheckReply("AT+CLTS=0", "OK")) 00528 return false; 00529 } 00530 00531 flushInput(); // eat any 'Unsolicted Result Code' 00532 00533 return true; 00534 } 00535 00536 bool Adafruit_FONA::enableNTPTimeSync(bool onoff, const char* ntpserver) { 00537 if (onoff) { 00538 if (! sendCheckReply("AT+CNTPCID=1", "OK")) 00539 return false; 00540 00541 mySerial.printf("AT+CNTP=\""); 00542 if (ntpserver != 0) { 00543 mySerial.printf(ntpserver); 00544 } else { 00545 mySerial.printf("pool.ntp.org"); 00546 } 00547 mySerial.printf("\",0\r\n"); 00548 readline(FONA_DEFAULT_TIMEOUT_MS); 00549 if (strcmp(replybuffer, "OK") != 0) 00550 return false; 00551 00552 if (! sendCheckReply("AT+CNTP", "OK", 10000)) 00553 return false; 00554 00555 uint16_t status; 00556 readline(10000); 00557 if (! parseReply("+CNTP:", &status)) 00558 return false; 00559 } else { 00560 if (! sendCheckReply("AT+CNTPCID=0", "OK")) 00561 return false; 00562 } 00563 00564 return true; 00565 } 00566 00567 bool Adafruit_FONA::getTime(char* buff, uint16_t maxlen) { 00568 getReply("AT+CCLK?", (uint16_t) 10000); 00569 if (strncmp(replybuffer, "+CCLK: ", 7) != 0) 00570 return false; 00571 00572 char *p = replybuffer+7; 00573 uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p)); 00574 strncpy(buff, p, lentocopy+1); 00575 buff[lentocopy] = 0; 00576 00577 readline(); // eat OK 00578 00579 return true; 00580 } 00581 00582 /********* GPS **********************************************************/ 00583 00584 00585 bool Adafruit_FONA::enableGPS(bool onoff) { 00586 uint16_t state; 00587 00588 // first check if its already on or off 00589 if (! sendParseReply("AT+CGPSPWR?", "+CGPSPWR: ", &state) ) 00590 return false; 00591 00592 if (onoff && !state) { 00593 if (! sendCheckReply("AT+CGPSPWR=1", "OK")) 00594 return false; 00595 } else if (!onoff && state) { 00596 if (! sendCheckReply("AT+CGPSPWR=0", "OK")) 00597 return false; 00598 } 00599 return true; 00600 } 00601 00602 int8_t Adafruit_FONA::GPSstatus(void) { 00603 getReply("AT+CGPSSTATUS?"); 00604 00605 char *p = strstr(replybuffer, "+CGPSSTATUS: Location "); 00606 if (p == 0) return -1; 00607 00608 p+=22; 00609 00610 readline(); // eat 'OK' 00611 00612 00613 if (p[0] == 'U') return 0; 00614 if (p[0] == 'N') return 1; 00615 if (p[0] == '2') return 2; 00616 if (p[0] == '3') return 3; 00617 00618 // else 00619 return 0; 00620 } 00621 00622 uint8_t Adafruit_FONA::getGPS(uint8_t arg, char *buffer, uint8_t maxbuff) { 00623 int32_t x = arg; 00624 00625 getReply("AT+CGPSINF=", x); 00626 00627 char *p = strstr(replybuffer, "CGPSINF: "); 00628 if (p == 0){ 00629 buffer[0] = 0; 00630 return 0; 00631 } 00632 p+=9; 00633 uint8_t len = max((uint8_t)(maxbuff-1), (uint8_t)strlen(p)); 00634 strncpy(buffer, p, len); 00635 buffer[len] = 0; 00636 00637 readline(); // eat 'OK' 00638 return len; 00639 } 00640 00641 bool Adafruit_FONA::getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude) { 00642 char gpsbuffer[120]; 00643 00644 // we need at least a 2D fix 00645 if (GPSstatus() < 2) 00646 return false; 00647 00648 // grab the mode 2^5 gps csv from the sim808 00649 uint8_t res_len = getGPS(32, gpsbuffer, 120); 00650 00651 // make sure we have a response 00652 if (res_len == 0) 00653 return false; 00654 00655 // skip mode 00656 char *tok = strtok(gpsbuffer, ","); 00657 if (! tok) return false; 00658 00659 // skip date 00660 tok = strtok(NULL, ","); 00661 if (! tok) return false; 00662 00663 // skip fix 00664 tok = strtok(NULL, ","); 00665 if (! tok) return false; 00666 00667 // grab the latitude 00668 char *latp = strtok(NULL, ","); 00669 if (! latp) return false; 00670 00671 // grab latitude direction 00672 char *latdir = strtok(NULL, ","); 00673 if (! latdir) return false; 00674 00675 // grab longitude 00676 char *longp = strtok(NULL, ","); 00677 if (! longp) return false; 00678 00679 // grab longitude direction 00680 char *longdir = strtok(NULL, ","); 00681 if (! longdir) return false; 00682 00683 double latitude = atof(latp); 00684 double longitude = atof(longp); 00685 00686 // convert latitude from minutes to decimal 00687 float degrees = floor(latitude / 100); 00688 double minutes = latitude - (100 * degrees); 00689 minutes /= 60; 00690 degrees += minutes; 00691 00692 // turn direction into + or - 00693 if (latdir[0] == 'S') degrees *= -1; 00694 00695 *lat = degrees; 00696 00697 // convert longitude from minutes to decimal 00698 degrees = floor(longitude / 100); 00699 minutes = longitude - (100 * degrees); 00700 minutes /= 60; 00701 degrees += minutes; 00702 00703 // turn direction into + or - 00704 if (longdir[0] == 'W') degrees *= -1; 00705 00706 *lon = degrees; 00707 00708 // only grab speed if needed 00709 if (speed_kph != NULL) { 00710 00711 // grab the speed in knots 00712 char *speedp = strtok(NULL, ","); 00713 if (! speedp) return false; 00714 00715 // convert to kph 00716 *speed_kph = atof(speedp) * 1.852; 00717 00718 } 00719 00720 // only grab heading if needed 00721 if (heading != NULL) { 00722 00723 // grab the speed in knots 00724 char *coursep = strtok(NULL, ","); 00725 if (! coursep) return false; 00726 00727 *heading = atof(coursep); 00728 00729 } 00730 00731 // no need to continue 00732 if (altitude == NULL) 00733 return true; 00734 00735 // we need at least a 3D fix for altitude 00736 if (GPSstatus() < 3) 00737 return false; 00738 00739 // grab the mode 0 gps csv from the sim808 00740 res_len = getGPS(0, gpsbuffer, 120); 00741 00742 // make sure we have a response 00743 if (res_len == 0) 00744 return false; 00745 00746 // skip mode 00747 tok = strtok(gpsbuffer, ","); 00748 if (! tok) return false; 00749 00750 // skip lat 00751 tok = strtok(NULL, ","); 00752 if (! tok) return false; 00753 00754 // skip long 00755 tok = strtok(NULL, ","); 00756 if (! tok) return false; 00757 00758 // grab altitude 00759 char *altp = strtok(NULL, ","); 00760 if (! altp) return false; 00761 00762 *altitude = atof(altp); 00763 00764 return true; 00765 } 00766 00767 bool Adafruit_FONA::enableGPSNMEA(uint8_t i) { 00768 char sendbuff[15] = "AT+CGPSOUT=000"; 00769 sendbuff[11] = (i / 100) + '0'; 00770 i %= 100; 00771 sendbuff[12] = (i / 10) + '0'; 00772 i %= 10; 00773 sendbuff[13] = i + '0'; 00774 00775 return sendCheckReply(sendbuff, "OK", 2000); 00776 } 00777 00778 00779 /********* GPRS **********************************************************/ 00780 00781 00782 bool Adafruit_FONA::enableGPRS(bool onoff) { 00783 if (onoff) { 00784 // disconnect all sockets 00785 sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000); 00786 00787 if (! sendCheckReply("AT+CGATT=1", "OK", 10000)) 00788 return false; 00789 00790 // set bearer profile! connection type GPRS 00791 if (! sendCheckReply("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 10000)) 00792 return false; 00793 00794 // set bearer profile access point name 00795 if (apn) { 00796 // Send command AT+SAPBR=3,1,"APN","<apn value>" where <apn value> is the configured APN value. 00797 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"APN\",", apn, "OK", 10000)) 00798 return false; 00799 00800 // set username/password 00801 if (apnusername) { 00802 // Send command AT+SAPBR=3,1,"USER","<user>" where <user> is the configured APN username. 00803 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"USER\",", apnusername, "OK", 10000)) 00804 return false; 00805 } 00806 if (apnpassword) { 00807 // Send command AT+SAPBR=3,1,"PWD","<password>" where <password> is the configured APN password. 00808 if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"PWD\",", apnpassword, "OK", 10000)) 00809 return false; 00810 } 00811 } 00812 00813 // open GPRS context 00814 if (! sendCheckReply("AT+SAPBR=1,1", "OK", 10000)) 00815 return false; 00816 } else { 00817 // disconnect all sockets 00818 if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000)) 00819 return false; 00820 00821 // close GPRS context 00822 if (! sendCheckReply("AT+SAPBR=0,1", "OK", 10000)) 00823 return false; 00824 00825 if (! sendCheckReply("AT+CGATT=0", "OK", 10000)) 00826 return false; 00827 } 00828 return true; 00829 } 00830 00831 uint8_t Adafruit_FONA::GPRSstate(void) { 00832 uint16_t state; 00833 00834 if (! sendParseReply("AT+CGATT?", "+CGATT: ", &state) ) 00835 return -1; 00836 00837 return state; 00838 } 00839 00840 void Adafruit_FONA::setGPRSNetworkSettings(const char* apn, const char* ausername, const char* apassword) { 00841 this->apn = (char*) apn; 00842 this->apnusername = (char*) ausername; 00843 this->apnpassword = (char*) apassword; 00844 } 00845 00846 bool Adafruit_FONA::getGSMLoc(uint16_t *errorcode, char *buff, uint16_t maxlen) { 00847 getReply("AT+CIPGSMLOC=1,1", (uint16_t)10000); 00848 00849 if (! parseReply("+CIPGSMLOC: ", errorcode)) 00850 return false; 00851 00852 char *p = replybuffer+14; 00853 uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p)); 00854 strncpy(buff, p, lentocopy+1); 00855 00856 readline(); // eat OK 00857 00858 return true; 00859 } 00860 00861 bool Adafruit_FONA::getGSMLoc(float *lat, float *lon) { 00862 uint16_t returncode; 00863 char gpsbuffer[120]; 00864 00865 // make sure we could get a response 00866 if (! getGSMLoc(&returncode, gpsbuffer, 120)) 00867 return false; 00868 00869 // make sure we have a valid return code 00870 if (returncode != 0) 00871 return false; 00872 00873 // tokenize the gps buffer to locate the lat & long 00874 char *latp = strtok(gpsbuffer, ","); 00875 if (! latp) return false; 00876 00877 char *longp = strtok(NULL, ","); 00878 if (! longp) return false; 00879 00880 *lat = atof(latp); 00881 *lon = atof(longp); 00882 00883 return true; 00884 } 00885 00886 /********* TCP FUNCTIONS ************************************/ 00887 00888 00889 bool Adafruit_FONA::TCPconnect(char *server, uint16_t port) { 00890 flushInput(); 00891 00892 // close all old connections 00893 if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000) ) return false; 00894 00895 // single connection at a time 00896 if (! sendCheckReply("AT+CIPMUX=0", "OK") ) return false; 00897 00898 // manually read data 00899 if (! sendCheckReply("AT+CIPRXGET=1", "OK") ) return false; 00900 00901 #ifdef ADAFRUIT_FONA_DEBUG 00902 printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port); 00903 #endif 00904 00905 mySerial.printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port); 00906 00907 if (! expectReply("OK")) return false; 00908 if (! expectReply("CONNECT OK")) return false; 00909 return true; 00910 } 00911 00912 bool Adafruit_FONA::TCPclose(void) { 00913 return sendCheckReply("AT+CIPCLOSE", "OK"); 00914 } 00915 00916 bool Adafruit_FONA::TCPconnected(void) { 00917 if (! sendCheckReply("AT+CIPSTATUS", "OK", 100) ) return false; 00918 readline(100); 00919 #ifdef ADAFRUIT_FONA_DEBUG 00920 printf("\t<--- %s\r\n", replybuffer); 00921 #endif 00922 return (strcmp(replybuffer, "STATE: CONNECT OK") == 0); 00923 } 00924 00925 bool Adafruit_FONA::TCPsend(char *packet, uint8_t len) { 00926 #ifdef ADAFRUIT_FONA_DEBUG 00927 printf("AT+CIPSEND=%d\r\n", len); 00928 00929 for (uint16_t i=0; i<len; i++) { 00930 printf(" 0x%#02x", packet[i]); 00931 } 00932 printf("\r\n"); 00933 #endif 00934 00935 00936 mySerial.printf("AT+CIPSEND=%d\r\n", len); 00937 readline(); 00938 #ifdef ADAFRUIT_FONA_DEBUG 00939 printf("\t<--- %s\r\n", replybuffer); 00940 #endif 00941 if (replybuffer[0] != '>') return false; 00942 00943 for (uint16_t i=0; i<len; i++) { 00944 mySerial.putc(packet[i]); 00945 } 00946 readline(3000); // wait up to 3 seconds to send the data 00947 #ifdef ADAFRUIT_FONA_DEBUG 00948 printf("\t<--- %s\r\n", replybuffer); 00949 #endif 00950 00951 return (strcmp(replybuffer, "SEND OK") == 0); 00952 } 00953 00954 uint16_t Adafruit_FONA::TCPavailable(void) { 00955 uint16_t avail; 00956 00957 if (! sendParseReply("AT+CIPRXGET=4", "+CIPRXGET: 4,", &avail, ',', 0) ) return false; 00958 00959 #ifdef ADAFRUIT_FONA_DEBUG 00960 printf("%d bytes available\r\n", avail); 00961 #endif 00962 00963 return avail; 00964 } 00965 00966 00967 uint16_t Adafruit_FONA::TCPread(uint8_t *buff, uint8_t len) { 00968 uint16_t avail; 00969 00970 mySerial.printf("AT+CIPRXGET=2,%d\r\n", len); 00971 readline(); 00972 if (! parseReply("+CIPRXGET: 2,", &avail, ',', 0)) return false; 00973 00974 readRaw(avail); 00975 00976 #ifdef ADAFRUIT_FONA_DEBUG 00977 printf("%d bytes read\r\n", avail); 00978 for (uint8_t i=0;i<avail;i++) { 00979 printf(" 0x%#02x", replybuffer[i]); 00980 } 00981 printf("\r\n"); 00982 #endif 00983 00984 memcpy(buff, replybuffer, avail); 00985 00986 return avail; 00987 } 00988 00989 /********* HTTP LOW LEVEL FUNCTIONS ************************************/ 00990 00991 bool Adafruit_FONA::HTTP_init() { 00992 return sendCheckReply("AT+HTTPINIT", "OK"); 00993 } 00994 00995 bool Adafruit_FONA::HTTP_term() { 00996 return sendCheckReply("AT+HTTPTERM", "OK"); 00997 } 00998 00999 void Adafruit_FONA::HTTP_para_start(const char* parameter, bool quoted) { 01000 flushInput(); 01001 01002 #ifdef ADAFRUIT_FONA_DEBUG 01003 printf("\t---> AT+HTTPPARA=\"%s\"\r\n", parameter); 01004 #endif 01005 01006 mySerial.printf("AT+HTTPPARA=\"%s", parameter); 01007 if (quoted) 01008 mySerial.printf("\",\""); 01009 else 01010 mySerial.printf("\","); 01011 } 01012 01013 bool Adafruit_FONA::HTTP_para_end(bool quoted) { 01014 if (quoted) 01015 mySerial.printf("\"\r\n"); 01016 else 01017 mySerial.printf("\r\n"); 01018 01019 return expectReply("OK"); 01020 } 01021 01022 bool Adafruit_FONA::HTTP_para(const char* parameter, const char* value) { 01023 HTTP_para_start(parameter, true); 01024 mySerial.printf(value); 01025 return HTTP_para_end(true); 01026 } 01027 01028 bool Adafruit_FONA::HTTP_para(const char* parameter, int32_t value) { 01029 HTTP_para_start(parameter, false); 01030 mySerial.printf("%d", value); 01031 return HTTP_para_end(false); 01032 } 01033 01034 bool Adafruit_FONA::HTTP_data(uint32_t size, uint32_t maxTime) { 01035 flushInput(); 01036 01037 #ifdef ADAFRUIT_FONA_DEBUG 01038 printf("\t---> AT+HTTPDATA=%d,%d\r\n", size, maxTime); 01039 #endif 01040 01041 mySerial.printf("AT+HTTPDATA=%d,%d\r\n", size, maxTime); 01042 01043 return expectReply("DOWNLOAD"); 01044 } 01045 01046 bool Adafruit_FONA::HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout) { 01047 // Send request. 01048 if (! sendCheckReply("AT+HTTPACTION=", method, "OK")) 01049 return false; 01050 01051 // Parse response status and size. 01052 readline(timeout); 01053 if (! parseReply("+HTTPACTION:", status, ',', 1)) 01054 return false; 01055 if (! parseReply("+HTTPACTION:", datalen, ',', 2)) 01056 return false; 01057 01058 return true; 01059 } 01060 01061 bool Adafruit_FONA::HTTP_readall(uint16_t *datalen) { 01062 getReply("AT+HTTPREAD"); 01063 if (! parseReply("+HTTPREAD:", datalen, ',', 0)) 01064 return false; 01065 01066 return true; 01067 } 01068 01069 bool Adafruit_FONA::HTTP_ssl(bool onoff) { 01070 return sendCheckReply("AT+HTTPSSL=", onoff ? 1 : 0, "OK"); 01071 } 01072 01073 /********* HTTP HIGH LEVEL FUNCTIONS ***************************/ 01074 01075 bool Adafruit_FONA::HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen){ 01076 if (! HTTP_setup(url)) 01077 return false; 01078 01079 // HTTP GET 01080 if (! HTTP_action(FONA_HTTP_GET, status, datalen)) 01081 return false; 01082 01083 #ifdef ADAFRUIT_FONA_DEBUG 01084 printf("Status: %d\r\n", *status); 01085 printf("Len: %d\r\n", *datalen); 01086 #endif 01087 01088 // HTTP response data 01089 if (! HTTP_readall(datalen)) 01090 return false; 01091 01092 return true; 01093 } 01094 01095 void Adafruit_FONA::HTTP_GET_end(void) { 01096 HTTP_term(); 01097 } 01098 01099 bool Adafruit_FONA::HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen) { 01100 if (! HTTP_setup(url)) 01101 return false; 01102 01103 if (! HTTP_para("CONTENT", contenttype)) { 01104 return false; 01105 } 01106 01107 // HTTP POST data 01108 if (! HTTP_data(postdatalen, 10000)) 01109 return false; 01110 for (uint16_t i = 0; i < postdatalen; i++) { 01111 mySerial.putc(postdata[i]); 01112 } 01113 if (! expectReply("OK")) 01114 return false; 01115 01116 // HTTP POST 01117 if (! HTTP_action(FONA_HTTP_POST, status, datalen)) 01118 return false; 01119 01120 #ifdef ADAFRUIT_FONA_DEBUG 01121 printf("Status: %d\r\n", *status); 01122 printf("Len: %d\r\n", *datalen); 01123 #endif 01124 01125 // HTTP response data 01126 if (! HTTP_readall(datalen)) 01127 return false; 01128 01129 return true; 01130 } 01131 01132 void Adafruit_FONA::HTTP_POST_end(void) { 01133 HTTP_term(); 01134 } 01135 01136 void Adafruit_FONA::setUserAgent(const char* useragent) { 01137 this->useragent = (char*) useragent; 01138 } 01139 01140 void Adafruit_FONA::setHTTPSRedirect(bool onoff) { 01141 httpsredirect = onoff; 01142 } 01143 01144 /********* HTTP HELPERS ****************************************/ 01145 01146 bool Adafruit_FONA::HTTP_setup(char *url) { 01147 // Handle any pending 01148 HTTP_term(); 01149 01150 // Initialize and set parameters 01151 if (! HTTP_init()) 01152 return false; 01153 if (! HTTP_para("CID", 1)) 01154 return false; 01155 if (! HTTP_para("UA", useragent)) 01156 return false; 01157 if (! HTTP_para("URL", url)) 01158 return false; 01159 01160 // HTTPS redirect 01161 if (httpsredirect) { 01162 if (! HTTP_para("REDIR",1)) 01163 return false; 01164 01165 if (! HTTP_ssl(true)) 01166 return false; 01167 } 01168 01169 return true; 01170 } 01171 01172 01173 /********* HELPERS *********************************************/ 01174 01175 bool Adafruit_FONA::expectReply(const char* reply, uint16_t timeout) { 01176 readline(timeout); 01177 #ifdef ADAFRUIT_FONA_DEBUG 01178 printf("\t<--- %s\r\n", replybuffer); 01179 #endif 01180 return (strcmp(replybuffer, reply) == 0); 01181 } 01182 01183 /********* LOW LEVEL *******************************************/ 01184 01185 void Adafruit_FONA::flushInput() { 01186 // Read all available serial input to flush pending data. 01187 uint16_t timeoutloop = 0; 01188 while (timeoutloop++ < 40) { 01189 while(readable()) { 01190 getc(); 01191 timeoutloop = 0; // If char was received reset the timer 01192 } 01193 wait_ms(1); 01194 } 01195 } 01196 01197 uint16_t Adafruit_FONA::readRaw(uint16_t b) { 01198 uint16_t idx = 0; 01199 01200 while (b && (idx < sizeof(replybuffer)-1)) { 01201 if (readable()) { 01202 replybuffer[idx] = getc(); 01203 idx++; 01204 b--; 01205 } 01206 } 01207 replybuffer[idx] = 0; 01208 01209 return idx; 01210 } 01211 01212 // This function just reads the output from FONA after an AT command is sent to it 01213 uint8_t Adafruit_FONA::readline(uint16_t timeout, bool multiline) { 01214 uint16_t replyidx = 0; 01215 01216 while (timeout--) { 01217 if (replyidx >= 254) { 01218 break; 01219 } 01220 01221 while(readable()) { 01222 char c = getc(); 01223 if (c == '\r') continue; 01224 if (c == 0xA) { 01225 if (replyidx == 0) // the first 0x0A is ignored 01226 continue; 01227 01228 if (!multiline) { 01229 timeout = 0; // the second 0x0A is the end of the line 01230 break; 01231 } 01232 } 01233 replybuffer[replyidx] = c; 01234 replyidx++; 01235 } 01236 01237 if (timeout == 0) { 01238 break; 01239 } 01240 wait_ms(1); 01241 } 01242 replybuffer[replyidx] = 0; // null term 01243 return replyidx; 01244 } 01245 01246 uint8_t Adafruit_FONA::getReply(const char* send, uint16_t timeout) { 01247 flushInput(); 01248 01249 #ifdef ADAFRUIT_FONA_DEBUG 01250 printf("\t---> %s\r\n", send); 01251 #endif 01252 01253 mySerial.printf("%s\r\n",send); 01254 01255 uint8_t l = readline(timeout); 01256 #ifdef ADAFRUIT_FONA_DEBUG 01257 printf("\t<--- %s\r\n", replybuffer); 01258 #endif 01259 return l; 01260 } 01261 01262 // Send prefix, suffix, and newline. Return response (and also set replybuffer with response). 01263 uint8_t Adafruit_FONA::getReply(const char* prefix, char* suffix, uint16_t timeout) { 01264 flushInput(); 01265 01266 #ifdef ADAFRUIT_FONA_DEBUG 01267 printf("\t---> %s%s\r\n", prefix, suffix); 01268 #endif 01269 01270 mySerial.printf("%s%s\r\n", prefix, suffix); 01271 01272 uint8_t l = readline(timeout); 01273 #ifdef ADAFRUIT_FONA_DEBUG 01274 printf("\t<--- %s\r\n", replybuffer); 01275 #endif 01276 return l; 01277 } 01278 01279 // Send prefix, suffix, and newline. Return response (and also set replybuffer with response). 01280 uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix, uint16_t timeout) { 01281 flushInput(); 01282 01283 #ifdef ADAFRUIT_FONA_DEBUG 01284 printf("\t---> %s%d\r\n", prefix, suffix); 01285 #endif 01286 01287 mySerial.printf("%s%d\r\n", prefix, suffix); 01288 01289 uint8_t l = readline(timeout); 01290 #ifdef ADAFRUIT_FONA_DEBUG 01291 printf("\t<--- %s\r\n", replybuffer); 01292 #endif 01293 return l; 01294 } 01295 01296 // Send prefix, suffix, suffix2, and newline. Return response (and also set replybuffer with response). 01297 uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix1, int32_t suffix2, uint16_t timeout) { 01298 flushInput(); 01299 01300 #ifdef ADAFRUIT_FONA_DEBUG 01301 printf("\t---> %s%d,%d\r\n", prefix, suffix1, suffix2); 01302 #endif 01303 01304 mySerial.printf("%s%d,%d\r\n", prefix, suffix1, suffix2); 01305 01306 uint8_t l = readline(timeout); 01307 #ifdef ADAFRUIT_FONA_DEBUG 01308 printf("\t<--- %s\r\n", replybuffer); 01309 #endif 01310 return l; 01311 } 01312 01313 // Send prefix, ", suffix, ", and newline. Return response (and also set replybuffer with response). 01314 uint8_t Adafruit_FONA::getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout) { 01315 flushInput(); 01316 01317 #ifdef ADAFRUIT_FONA_DEBUG 01318 printf("\t---> %s\"%s\"\r\n", prefix, suffix); 01319 #endif 01320 01321 mySerial.printf("%s\"%s\"\r\n", prefix, suffix); 01322 01323 uint8_t l = readline(timeout); 01324 #ifdef ADAFRUIT_FONA_DEBUG 01325 printf("\t<--- %s\r\n", replybuffer); 01326 #endif 01327 return l; 01328 } 01329 01330 01331 bool Adafruit_FONA::sendCheckReply(const char *send, const char *reply, uint16_t timeout) { 01332 getReply(send, timeout); 01333 01334 return (strcmp(replybuffer, reply) == 0); 01335 } 01336 01337 // Send prefix, suffix, and newline. Verify FONA response matches reply parameter. 01338 bool Adafruit_FONA::sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout) { 01339 getReply(prefix, suffix, timeout); 01340 return (strcmp(replybuffer, reply) == 0); 01341 } 01342 01343 // Send prefix, suffix, and newline. Verify FONA response matches reply parameter. 01344 bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout) { 01345 getReply(prefix, suffix, timeout); 01346 return (strcmp(replybuffer, reply) == 0); 01347 } 01348 01349 // Send prefix, suffix, suffix2, and newline. Verify FONA response matches reply parameter. 01350 bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix1, int32_t suffix2, const char* reply, uint16_t timeout) { 01351 getReply(prefix, suffix1, suffix2, timeout); 01352 return (strcmp(replybuffer, reply) == 0); 01353 } 01354 01355 // Send prefix, ", suffix, ", and newline. Verify FONA response matches reply parameter. 01356 bool Adafruit_FONA::sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout) { 01357 getReplyQuoted(prefix, suffix, timeout); 01358 return (strcmp(replybuffer, reply) == 0); 01359 } 01360 01361 bool Adafruit_FONA::parseReply(const char* toreply, uint16_t *v, char divider, uint8_t index) { 01362 char *p = strstr(replybuffer, toreply); // get the pointer to the voltage 01363 if (p == 0) return false; 01364 p += strlen(toreply); 01365 01366 for (uint8_t i=0; i<index;i++) { 01367 // increment dividers 01368 p = strchr(p, divider); 01369 if (!p) return false; 01370 p++; 01371 } 01372 01373 *v = atoi(p); 01374 01375 return true; 01376 } 01377 01378 bool Adafruit_FONA::parseReply(const char* toreply, char *v, char divider, uint8_t index) { 01379 uint8_t i=0; 01380 char *p = strstr(replybuffer, toreply); 01381 if (p == 0) return false; 01382 p+=strlen(toreply); 01383 01384 for (i=0; i<index;i++) { 01385 // increment dividers 01386 p = strchr(p, divider); 01387 if (!p) return false; 01388 p++; 01389 } 01390 01391 for(i=0; i<strlen(p);i++) { 01392 if(p[i] == divider) 01393 break; 01394 v[i] = p[i]; 01395 } 01396 01397 v[i] = '\0'; 01398 01399 return true; 01400 } 01401 01402 // Parse a quoted string in the response fields and copy its value (without quotes) 01403 // to the specified character array (v). Only up to maxlen characters are copied 01404 // into the result buffer, so make sure to pass a large enough buffer to handle the 01405 // response. 01406 bool Adafruit_FONA::parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index) { 01407 uint8_t i=0, j; 01408 // Verify response starts with toreply. 01409 char *p = strstr(replybuffer, toreply); 01410 if (p == 0) return false; 01411 p+=strlen(toreply); 01412 01413 // Find location of desired response field. 01414 for (i=0; i<index;i++) { 01415 // increment dividers 01416 p = strchr(p, divider); 01417 if (!p) return false; 01418 p++; 01419 } 01420 01421 // Copy characters from response field into result string. 01422 for(i=0, j=0; j<maxlen && i<strlen(p); ++i) { 01423 // Stop if a divier is found. 01424 if(p[i] == divider) 01425 break; 01426 // Skip any quotation marks. 01427 else if(p[i] == '"') 01428 continue; 01429 v[j++] = p[i]; 01430 } 01431 01432 // Add a null terminator if result string buffer was not filled. 01433 if (j < maxlen) 01434 v[j] = '\0'; 01435 01436 return true; 01437 } 01438 01439 bool Adafruit_FONA::sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider, uint8_t index) { 01440 getReply(tosend); 01441 01442 if (! parseReply(toreply, v, divider, index)) return false; 01443 01444 readline(); // eat 'OK' 01445 01446 return true; 01447 }
Generated on Fri Jul 15 2022 04:25:10 by 1.7.2