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:
Mon Feb 25 20:27:24 2019 +0000
Revision:
10:7951d9691cb2
Parent:
9:b18cfba4283a
Child:
11:5f66d83249ea
Various fona 3G patch

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