Library for the Adafruit FONA. This is a port of the original Arduino library available at: https://github.com/adafruit/Adafruit_FONA_Library . - Modified by Marc PLOUHINEC 27/06/2015 for use in mbed - Modified by lionel VOIRIN 05/08/2018 for use Adafruit FONA 3

Dependents:   Adafruit_FONA_3G_Library_Test

Committer:
Nels885
Date:
Sun Aug 05 14:06:59 2018 +0000
Revision:
0:bf67af6b3913
Child:
1:c0ae7ecfa511
Modified for use Adafruit FONA 3G

Who changed what in which revision?

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