Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of FONA_CellPhone by
Adafruit_FONA.cpp@19:06dd156420a5, 2017-01-27 (annotated)
- Committer:
- michaelVisimid
- Date:
- Fri Jan 27 00:22:31 2017 +0000
- Revision:
- 19:06dd156420a5
- Parent:
- 18:d52017f1d087
Pre-compiled mbed libraries don't work correctly when exported
Who changed what in which revision?
User | Revision | Line number | New 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 | } |