program to test exporting mbed-dev

Dependencies:   mbed-dev

Fork of FONA_CellPhone by Michael Baker

Committer:
michaelVisimid
Date:
Wed Jan 25 12:56:31 2017 +0000
Revision:
18:d52017f1d087
Parent:
9:06eca688f2a3
Update to work with latest mBed

Who changed what in which revision?

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