Better support for Cellular XBEE3 modules
Also some minor documentation and naming changes for consistency.
This commit is contained in:
		@@ -35,7 +35,7 @@ TinyGSM also pulls data gently from the modem (whenever possible), so it can ope
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
Feature \ Modem              | SIM8xx | Ublox  | A6/A7/A20 | M590 | ESP8266 | XBee 
 | 
			
		||||
Feature \ Modem              | SIM8xx | u-Blox | A6/A7/A20 | M590 | ESP8266 | XBee
 | 
			
		||||
---                          | ---    | ---    | ---       | ---  | ---     | ---
 | 
			
		||||
**Data connections**
 | 
			
		||||
TCP (HTTP, MQTT, Blynk, ...) | ✔      | ✔      | ✔         | ✔    | ✔       | ✔
 | 
			
		||||
@@ -45,7 +45,7 @@ SSL/TLS (HTTPS)              | ✔¹     | ✔      | 🅧        | 🅧    | 
 | 
			
		||||
Sending USSD requests        | ✔      |        | ✔         | ✔    | 🅧       |
 | 
			
		||||
Decoding 7,8,16-bit response | ✔      |        | ✔         | ✔    | 🅧      |
 | 
			
		||||
**SMS**
 | 
			
		||||
Sending                      | ✔      |        | ✔         | ✔    | 🅧      | ✔
 | 
			
		||||
Sending                      | ✔      | ✔      | ✔         | ✔    | 🅧      | ✔
 | 
			
		||||
Sending Unicode              | ✔      |        | ◌         | 🅧   | 🅧      |
 | 
			
		||||
Reading                      |        |        |           |      | 🅧      |
 | 
			
		||||
Incoming message event       |        |        |           | ?    | 🅧      |
 | 
			
		||||
@@ -70,7 +70,7 @@ GPS/GNSS                     | ✔¹     | 🅧     | ◌¹        | 🅧   | 
 | 
			
		||||
- ESP8266 (AT commands interface, similar to GSM modems)
 | 
			
		||||
- Digi XBee WiFi and Cellular (using XBee command mode)
 | 
			
		||||
- Neoway M590
 | 
			
		||||
- U-blox SARA U2 (U201, U260, U270)
 | 
			
		||||
- u-blox Cellular Modems (LEON-G100, LISA-U2xx, SARA-G3xx, SARA-U2xx, TOBY-L2xx, LARA-R2xx, MPCI-L2xx)
 | 
			
		||||
- Quectel BG96 ***(alpha)***
 | 
			
		||||
 | 
			
		||||
### Supported boards/modules
 | 
			
		||||
@@ -180,7 +180,7 @@ This may result in problems such as:
 | 
			
		||||
 * etc.
 | 
			
		||||
 | 
			
		||||
To return module to **Factory Defaults**, use this sketch:  
 | 
			
		||||
  File -> Examples -> TynyGSM -> tools -> [FactoryReset](https://github.com/vshymanskyy/TinyGSM/blob/master/tools/FactoryReset/FactoryReset.ino)
 | 
			
		||||
  File -> Examples -> TinyGSM -> tools -> [FactoryReset](https://github.com/vshymanskyy/TinyGSM/blob/master/tools/FactoryReset/FactoryReset.ino)
 | 
			
		||||
 | 
			
		||||
### Goouuu Tech IOT-GA6 vs AI-Thinker A6 confusion
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,9 @@
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_UBLOX)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
			
		||||
  #include <TinyGsmClientUBLOX.h>
 | 
			
		||||
  typedef TinyGsmU201 TinyGsm;
 | 
			
		||||
  typedef TinyGsmU201::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmU201::GsmClientSecure TinyGsmClientSecure;
 | 
			
		||||
  typedef TinyGsmUBLOX TinyGsm;
 | 
			
		||||
  typedef TinyGsmUBLOX::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmUBLOX::GsmClientSecure TinyGsmClientSecure;
 | 
			
		||||
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_BG96)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
			
		||||
@@ -47,24 +47,29 @@
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
			
		||||
  #include <TinyGsmClientA6.h>
 | 
			
		||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmA6 TinyGsm;
 | 
			
		||||
  typedef TinyGsmA6::GsmClient TinyGsmClient;
 | 
			
		||||
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_M590)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
			
		||||
  #include <TinyGsmClientM590.h>
 | 
			
		||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmM590 TinyGsm;
 | 
			
		||||
  typedef TinyGsmM590::GsmClient TinyGsmClient;
 | 
			
		||||
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_ESP8266)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_WIFI
 | 
			
		||||
  #include <TinyGsmClientESP8266.h>
 | 
			
		||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsm::GsmClientSecure TinyGsmClientSecure;
 | 
			
		||||
  typedef TinyGsmESP8266 TinyGsm;
 | 
			
		||||
  typedef TinyGsmESP8266::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmESP8266::GsmClientSecure TinyGsmClientSecure;
 | 
			
		||||
 | 
			
		||||
#elif defined(TINY_GSM_MODEM_XBEE)
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
			
		||||
  #define TINY_GSM_MODEM_HAS_WIFI
 | 
			
		||||
  #include <TinyGsmClientXBee.h>
 | 
			
		||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmXBee TinyGsm;
 | 
			
		||||
  typedef TinyGsmXBee::GsmClient TinyGsmClient;
 | 
			
		||||
  typedef TinyGsmXBee::GsmClientSecure TinyGsmClientSecure;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  #error "Please define GSM modem model"
 | 
			
		||||
 
 | 
			
		||||
@@ -38,25 +38,37 @@ enum RegStatus {
 | 
			
		||||
  REG_UNKNOWN      = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                       Declaration of the TinyGsmA6 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsm
 | 
			
		||||
class TinyGsmA6
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The Internal A6 Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
{
 | 
			
		||||
  friend class TinyGsm;
 | 
			
		||||
  friend class TinyGsmA6;
 | 
			
		||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  GsmClient() {}
 | 
			
		||||
 | 
			
		||||
  GsmClient(TinyGsm& modem) {
 | 
			
		||||
  GsmClient(TinyGsmA6& modem) {
 | 
			
		||||
    init(&modem);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init(TinyGsm* modem) {
 | 
			
		||||
  bool init(TinyGsmA6* modem) {
 | 
			
		||||
    this->at = modem;
 | 
			
		||||
    this->mux = -1;
 | 
			
		||||
    sock_connected = false;
 | 
			
		||||
@@ -162,15 +174,33 @@ public:
 | 
			
		||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsm*      at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
  TinyGsmA6*      at;
 | 
			
		||||
  uint8_t         mux;
 | 
			
		||||
  bool            sock_connected;
 | 
			
		||||
  RxFifo          rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                      The A6 does not have a secure client!
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The A6 Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  TinyGsm(Stream& stream)
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmA6(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmA6(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
@@ -209,8 +239,8 @@ public:
 | 
			
		||||
    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
			
		||||
      sendAT(GF(""));
 | 
			
		||||
      if (waitResponse(200) == 1) {
 | 
			
		||||
          delay(100);
 | 
			
		||||
          return true;
 | 
			
		||||
        delay(100);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      delay(100);
 | 
			
		||||
    }
 | 
			
		||||
@@ -307,10 +337,10 @@ public:
 | 
			
		||||
      int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"));
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      switch (status) {
 | 
			
		||||
      case 2:
 | 
			
		||||
      case 3:  return SIM_LOCKED;
 | 
			
		||||
      case 1:  return SIM_READY;
 | 
			
		||||
      default: return SIM_ERROR;
 | 
			
		||||
        case 2:
 | 
			
		||||
        case 3:  return SIM_LOCKED;
 | 
			
		||||
        case 1:  return SIM_READY;
 | 
			
		||||
        default: return SIM_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return SIM_ERROR;
 | 
			
		||||
@@ -370,6 +400,10 @@ public:
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -650,9 +684,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -737,6 +775,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
  #define TINY_GSM_RX_BUFFER 64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TINY_GSM_MUX_COUNT 5
 | 
			
		||||
#define TINY_GSM_MUX_COUNT 12
 | 
			
		||||
 | 
			
		||||
#include <TinyGsmCommon.h>
 | 
			
		||||
 | 
			
		||||
@@ -39,10 +39,22 @@ enum RegStatus {
 | 
			
		||||
  REG_UNKNOWN      = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                    Declaration of the TinyGsmBG96 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmBG96
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                         The Internal BG96 Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
@@ -173,6 +185,13 @@ private:
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The BG96 Secure Client
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GsmClientSecure : public GsmClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@@ -192,9 +211,19 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The BG96 Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmBG96(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmBG96(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
@@ -344,10 +373,10 @@ public:
 | 
			
		||||
      int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"), GF("NOT INSERTED"));
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      switch (status) {
 | 
			
		||||
      case 2:
 | 
			
		||||
      case 3:  return SIM_LOCKED;
 | 
			
		||||
      case 1:  return SIM_READY;
 | 
			
		||||
      default: return SIM_ERROR;
 | 
			
		||||
        case 2:
 | 
			
		||||
        case 3:  return SIM_LOCKED;
 | 
			
		||||
        case 1:  return SIM_READY;
 | 
			
		||||
        default: return SIM_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return SIM_ERROR;
 | 
			
		||||
@@ -404,6 +433,10 @@ public:
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -660,9 +693,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -743,6 +780,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,24 +24,51 @@ static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL;
 | 
			
		||||
static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;
 | 
			
		||||
static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120;
 | 
			
		||||
 | 
			
		||||
class TinyGsm
 | 
			
		||||
// <stat> status of ESP8266 station interface
 | 
			
		||||
// 2 : ESP8266 station connected to an AP and has obtained IP
 | 
			
		||||
// 3 : ESP8266 station created a TCP or UDP transmission
 | 
			
		||||
// 4 : the TCP or UDP transmission of ESP8266 station disconnected
 | 
			
		||||
// 5 : ESP8266 station did NOT connect to an AP
 | 
			
		||||
enum RegStatus {
 | 
			
		||||
  REG_OK_IP        = 2,
 | 
			
		||||
  REG_OK_TCP       = 3,
 | 
			
		||||
  REG_UNREGISTERED = 4,
 | 
			
		||||
  REG_DENIED       = 5,
 | 
			
		||||
  REG_UNKNOWN      = 6,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                     Declaration of the TinyGsmESP8266 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TinyGsmESP8266
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  //============================================================================//
 | 
			
		||||
  //============================================================================//
 | 
			
		||||
  //                      The ESP8266 Internal Client Class
 | 
			
		||||
  //============================================================================//
 | 
			
		||||
  //============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
{
 | 
			
		||||
  friend class TinyGsm;
 | 
			
		||||
  friend class TinyGsmESP8266;
 | 
			
		||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  GsmClient() {}
 | 
			
		||||
 | 
			
		||||
  GsmClient(TinyGsm& modem, uint8_t mux = 1) {
 | 
			
		||||
  GsmClient(TinyGsmESP8266& modem, uint8_t mux = 1) {
 | 
			
		||||
    init(&modem, mux);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init(TinyGsm* modem, uint8_t mux = 1) {
 | 
			
		||||
  bool init(TinyGsmESP8266* modem, uint8_t mux = 1) {
 | 
			
		||||
    this->at = modem;
 | 
			
		||||
    this->mux = mux;
 | 
			
		||||
    sock_connected = false;
 | 
			
		||||
@@ -144,18 +171,25 @@ public:
 | 
			
		||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsm*      at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
  TinyGsmESP8266* at;
 | 
			
		||||
  uint8_t         mux;
 | 
			
		||||
  bool            sock_connected;
 | 
			
		||||
  RxFifo          rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The Secure ESP8266 Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GsmClientSecure : public GsmClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  GsmClientSecure() {}
 | 
			
		||||
 | 
			
		||||
  GsmClientSecure(TinyGsm& modem, uint8_t mux = 1)
 | 
			
		||||
  GsmClientSecure(TinyGsmESP8266& modem, uint8_t mux = 1)
 | 
			
		||||
    : GsmClient(modem, mux)
 | 
			
		||||
  {}
 | 
			
		||||
 | 
			
		||||
@@ -169,9 +203,20 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The ESP8266 Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  TinyGsm(Stream& stream)
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmESP8266(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmESP8266(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
@@ -192,6 +237,14 @@ public:
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    sendAT(GF("+CIPMUX=1"));  // Enable Multiple Connections
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    sendAT(GF("+CWMODE_CUR=1"));  // Put into "station" mode
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -203,8 +256,8 @@ public:
 | 
			
		||||
    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
			
		||||
      sendAT(GF(""));
 | 
			
		||||
      if (waitResponse(200) == 1) {
 | 
			
		||||
          delay(100);
 | 
			
		||||
          return true;
 | 
			
		||||
        delay(100);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      delay(100);
 | 
			
		||||
    }
 | 
			
		||||
@@ -255,6 +308,23 @@ public:
 | 
			
		||||
    return init();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool poweroff() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * SIM card functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  RegStatus getRegistrationStatus() {
 | 
			
		||||
    sendAT(GF("+CIPSTATUS"));
 | 
			
		||||
    if (waitResponse(3000, GF("STATUS:")) != 1) return REG_UNKNOWN;
 | 
			
		||||
    int status = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
 | 
			
		||||
    waitResponse();  // Returns an OK after the status
 | 
			
		||||
    return (RegStatus)status;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Generic network functions
 | 
			
		||||
@@ -275,21 +345,9 @@ public:
 | 
			
		||||
    return res2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool isNetworkConnected() {
 | 
			
		||||
    sendAT(GF("+CIPSTATUS"));
 | 
			
		||||
    int res1 = waitResponse(3000, GF("STATUS:"));
 | 
			
		||||
    int res2 = 0;
 | 
			
		||||
    if (res1 == 1) {
 | 
			
		||||
      res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
 | 
			
		||||
    }
 | 
			
		||||
    // <stat> status of ESP8266 station interface
 | 
			
		||||
    // 2 : ESP8266 station connected to an AP and has obtained IP
 | 
			
		||||
    // 3 : ESP8266 station created a TCP or UDP transmission
 | 
			
		||||
    // 4 : the TCP or UDP transmission of ESP8266 station disconnected (but AP is connected)
 | 
			
		||||
    // 5 : ESP8266 station did NOT connect to an AP
 | 
			
		||||
    waitResponse();  // Returns an OK after the status
 | 
			
		||||
    if (res2 == 2 || res2 == 3 || res2 == 4) return true;
 | 
			
		||||
    else return false;
 | 
			
		||||
  bool isNetworkConnected()  {
 | 
			
		||||
    RegStatus s = getRegistrationStatus();
 | 
			
		||||
    return (s == REG_OK_IP || s == REG_OK_TCP);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool waitForNetwork(unsigned long timeout = 60000L) {
 | 
			
		||||
@@ -298,7 +356,7 @@ public:
 | 
			
		||||
      int res1 = waitResponse(3000, GF("busy p..."), GF("STATUS:"));
 | 
			
		||||
      if (res1 == 2) {
 | 
			
		||||
        int res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
 | 
			
		||||
        if (res2 == 2 || res2 == 3 || res2 == 4) {
 | 
			
		||||
        if (res2 == 2 || res2 == 3) {
 | 
			
		||||
            waitResponse();
 | 
			
		||||
            return true;
 | 
			
		||||
         }
 | 
			
		||||
@@ -312,17 +370,6 @@ public:
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
  bool networkConnect(const char* ssid, const char* pwd) {
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("+CIPMUX=1"));
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("+CWMODE_CUR=1"));
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("+CWJAP_CUR=\""), ssid, GF("\",\""), pwd, GF("\""));
 | 
			
		||||
    if (waitResponse(30000L, GFP(GSM_OK), GF(GSM_NL "FAIL" GSM_NL)) != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
@@ -353,6 +400,28 @@ public:
 | 
			
		||||
    return TinyGsmIpFromString(getLocalIP());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Messaging functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Location functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Battery functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
  int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
  bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = false) {
 | 
			
		||||
@@ -384,21 +453,8 @@ protected:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool modemGetConnected(uint8_t mux) {
 | 
			
		||||
    // TODO: re-check this
 | 
			
		||||
    sendAT(GF("+CIPSTATUS="), mux);
 | 
			
		||||
    int res1 = waitResponse(3000, GF("STATUS:"));
 | 
			
		||||
    int res2;
 | 
			
		||||
    if (res1 == 1) {
 | 
			
		||||
      res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
 | 
			
		||||
    }
 | 
			
		||||
    // <stat> status of ESP8266 station interface
 | 
			
		||||
    // 2 : ESP8266 station connected to an AP and has obtained IP
 | 
			
		||||
    // 3 : ESP8266 station created a TCP or UDP transmission
 | 
			
		||||
    // 4 : the TCP or UDP transmission of ESP8266 station disconnected (but AP is connected)
 | 
			
		||||
    // 5 : ESP8266 station did NOT connect to an AP
 | 
			
		||||
    waitResponse();  // Returns an OK after the status
 | 
			
		||||
    if (res2 == 2 || res2 == 3 || res2 == 4) return true;
 | 
			
		||||
    else return false;
 | 
			
		||||
    RegStatus s = getRegistrationStatus();
 | 
			
		||||
    return (s == REG_OK_IP || s == REG_OK_TCP);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
@@ -416,9 +472,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -505,6 +565,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,24 +39,37 @@ enum RegStatus {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TinyGsm
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                    Declaration of the TinyGsmM590 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmM590
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The M590 Internal Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
{
 | 
			
		||||
  friend class TinyGsm;
 | 
			
		||||
  friend class TinyGsmM590;
 | 
			
		||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  GsmClient() {}
 | 
			
		||||
 | 
			
		||||
  GsmClient(TinyGsm& modem, uint8_t mux = 1) {
 | 
			
		||||
  GsmClient(TinyGsmM590& modem, uint8_t mux = 1) {
 | 
			
		||||
    init(&modem, mux);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init(TinyGsm* modem, uint8_t mux = 1) {
 | 
			
		||||
  bool init(TinyGsmM590* modem, uint8_t mux = 1) {
 | 
			
		||||
    this->at = modem;
 | 
			
		||||
    this->mux = mux;
 | 
			
		||||
    sock_connected = false;
 | 
			
		||||
@@ -159,15 +172,33 @@ public:
 | 
			
		||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsm*      at;
 | 
			
		||||
  TinyGsmM590*  at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The M590 Has no Secure client!
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The M590 Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  TinyGsm(Stream& stream)
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmM590(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmM590(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
@@ -205,8 +236,8 @@ public:
 | 
			
		||||
    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
			
		||||
      sendAT(GF(""));
 | 
			
		||||
      if (waitResponse(200) == 1) {
 | 
			
		||||
          delay(100);
 | 
			
		||||
          return true;
 | 
			
		||||
        delay(100);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      delay(100);
 | 
			
		||||
    }
 | 
			
		||||
@@ -318,10 +349,10 @@ public:
 | 
			
		||||
      int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"));
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      switch (status) {
 | 
			
		||||
      case 2:
 | 
			
		||||
      case 3:  return SIM_LOCKED;
 | 
			
		||||
      case 1:  return SIM_READY;
 | 
			
		||||
      default: return SIM_ERROR;
 | 
			
		||||
        case 2:
 | 
			
		||||
        case 3:  return SIM_LOCKED;
 | 
			
		||||
        case 1:  return SIM_READY;
 | 
			
		||||
        default: return SIM_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return SIM_ERROR;
 | 
			
		||||
@@ -378,6 +409,10 @@ public:
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -408,12 +443,12 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
set_dns:
 | 
			
		||||
    sendAT(GF("+DNSSERVER=1,8.8.8.8"));
 | 
			
		||||
    waitResponse();
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("+DNSSERVER=2,8.8.4.4"));
 | 
			
		||||
    waitResponse();
 | 
			
		||||
// set_dns:  // TODO
 | 
			
		||||
//     sendAT(GF("+DNSSERVER=1,8.8.8.8"));
 | 
			
		||||
//     waitResponse();
 | 
			
		||||
//
 | 
			
		||||
//     sendAT(GF("+DNSSERVER=2,8.8.4.4"));
 | 
			
		||||
//     waitResponse();
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -595,9 +630,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -683,6 +722,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,15 +39,28 @@ enum RegStatus {
 | 
			
		||||
  REG_UNKNOWN      = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum DateTime {
 | 
			
		||||
enum TinyGSMDateTimeFormat {
 | 
			
		||||
  DATE_FULL = 0,
 | 
			
		||||
  DATE_TIME = 1,
 | 
			
		||||
  DATE_DATE = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                    Declaration of the TinyGsmSim800 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmSim800
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The Sim800 Internal Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
@@ -179,14 +192,21 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsmSim800* at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  uint16_t      sock_available;
 | 
			
		||||
  uint32_t      prev_check;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
  bool          got_data;
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
  uint8_t        mux;
 | 
			
		||||
  uint16_t       sock_available;
 | 
			
		||||
  uint32_t       prev_check;
 | 
			
		||||
  bool           sock_connected;
 | 
			
		||||
  bool           got_data;
 | 
			
		||||
  RxFifo         rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The SIM800 Secure Client
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GsmClientSecure : public GsmClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@@ -206,9 +226,19 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The SIM800 Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmSim800(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmSim800(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
@@ -244,8 +274,8 @@ public:
 | 
			
		||||
    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
			
		||||
      sendAT(GF(""));
 | 
			
		||||
      if (waitResponse(200) == 1) {
 | 
			
		||||
          delay(100);
 | 
			
		||||
          return true;
 | 
			
		||||
        delay(100);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      delay(100);
 | 
			
		||||
    }
 | 
			
		||||
@@ -396,10 +426,10 @@ public:
 | 
			
		||||
      int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"), GF("NOT INSERTED"));
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      switch (status) {
 | 
			
		||||
      case 2:
 | 
			
		||||
      case 3:  return SIM_LOCKED;
 | 
			
		||||
      case 1:  return SIM_READY;
 | 
			
		||||
      default: return SIM_ERROR;
 | 
			
		||||
        case 2:
 | 
			
		||||
        case 3:  return SIM_LOCKED;
 | 
			
		||||
        case 1:  return SIM_READY;
 | 
			
		||||
        default: return SIM_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return SIM_ERROR;
 | 
			
		||||
@@ -456,6 +486,10 @@ public:
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -734,7 +768,7 @@ public:
 | 
			
		||||
  /*
 | 
			
		||||
   * Time functions
 | 
			
		||||
   */
 | 
			
		||||
  String getGSMDateTime(DateTime format) {
 | 
			
		||||
  String getGSMDateTime(TinyGSMDateTimeFormat format) {
 | 
			
		||||
    sendAT(GF("+CCLK?"));
 | 
			
		||||
    if (waitResponse(2000L, GF(GSM_NL "+CCLK: \"")) != 1) {
 | 
			
		||||
      return "";
 | 
			
		||||
@@ -892,9 +926,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -975,6 +1013,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,13 @@
 | 
			
		||||
 | 
			
		||||
#include <TinyGsmClientSIM800.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//              Declaration and Definitio of the TinyGsmSim808 Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmSim808: public TinyGsmSim800
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file       TinyGsmClientU201.h
 | 
			
		||||
 * @file       TinyGsmClientUBLOX.h
 | 
			
		||||
 * @author     Volodymyr Shymanskyy
 | 
			
		||||
 * @license    LGPL-3.0
 | 
			
		||||
 * @copyright  Copyright (c) 2016 Volodymyr Shymanskyy
 | 
			
		||||
 * @date       Nov 2016
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef TinyGsmClientU201_h
 | 
			
		||||
#define TinyGsmClientU201_h
 | 
			
		||||
#ifndef TinyGsmClientUBLOX_h
 | 
			
		||||
#define TinyGsmClientUBLOX_h
 | 
			
		||||
 | 
			
		||||
//#define TINY_GSM_DEBUG Serial
 | 
			
		||||
 | 
			
		||||
@@ -39,31 +39,42 @@ enum RegStatus {
 | 
			
		||||
  REG_UNKNOWN      = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                   Declaration of the TinyGsmUBLOX Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmU201
 | 
			
		||||
class TinyGsmUBLOX
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The UBLOX Internal Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
{
 | 
			
		||||
  friend class TinyGsmU201;
 | 
			
		||||
  friend class TinyGsmUBLOX;
 | 
			
		||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  GsmClient() {}
 | 
			
		||||
 | 
			
		||||
  GsmClient(TinyGsmU201& modem, uint8_t mux = 1) {
 | 
			
		||||
  GsmClient(TinyGsmUBLOX& modem, uint8_t mux = 1) {
 | 
			
		||||
    init(&modem, mux);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init(TinyGsmU201* modem, uint8_t mux = 1) {
 | 
			
		||||
  bool init(TinyGsmUBLOX* modem, uint8_t mux = 1) {
 | 
			
		||||
    this->at = modem;
 | 
			
		||||
    this->mux = mux;
 | 
			
		||||
    sock_available = 0;
 | 
			
		||||
    sock_connected = false;
 | 
			
		||||
    got_data = false;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -109,7 +120,7 @@ public:
 | 
			
		||||
 | 
			
		||||
  virtual int available() {
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    if (!rx.size()) {
 | 
			
		||||
    if (!rx.size() && sock_connected) {
 | 
			
		||||
      at->maintain();
 | 
			
		||||
    }
 | 
			
		||||
    return rx.size() + sock_available;
 | 
			
		||||
@@ -164,7 +175,7 @@ public:
 | 
			
		||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsmU201*  at;
 | 
			
		||||
  TinyGsmUBLOX* at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  uint16_t      sock_available;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
@@ -172,12 +183,19 @@ private:
 | 
			
		||||
  RxFifo        rx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The Secure UBLOX Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GsmClientSecure : public GsmClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  GsmClientSecure() {}
 | 
			
		||||
 | 
			
		||||
  GsmClientSecure(TinyGsmU201& modem, uint8_t mux = 1)
 | 
			
		||||
  GsmClientSecure(TinyGsmUBLOX& modem, uint8_t mux = 1)
 | 
			
		||||
    : GsmClient(modem, mux)
 | 
			
		||||
  {}
 | 
			
		||||
 | 
			
		||||
@@ -192,12 +210,18 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The UBLOX Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmU201(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
  TinyGsmUBLOX(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmU201(Stream& stream)
 | 
			
		||||
  TinyGsmUBLOX(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
@@ -305,6 +329,8 @@ public:
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * SIM card functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -346,10 +372,10 @@ public:
 | 
			
		||||
      int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"), GF("NOT INSERTED"));
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      switch (status) {
 | 
			
		||||
      case 2:
 | 
			
		||||
      case 3:  return SIM_LOCKED;
 | 
			
		||||
      case 1:  return SIM_READY;
 | 
			
		||||
      default: return SIM_ERROR;
 | 
			
		||||
        case 2:
 | 
			
		||||
        case 3:  return SIM_LOCKED;
 | 
			
		||||
        case 1:  return SIM_READY;
 | 
			
		||||
        default: return SIM_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return SIM_ERROR;
 | 
			
		||||
@@ -406,6 +432,10 @@ public:
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * WiFi functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -507,7 +537,20 @@ public:
 | 
			
		||||
 | 
			
		||||
  String sendUSSD(const String& code) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool sendSMS(const String& number, const String& text) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
  bool sendSMS(const String& number, const String& text) {
 | 
			
		||||
    sendAT(GF("+CSCS=\"GSM\""));  // Set GSM default alphabet
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    sendAT(GF("+CMGF=1"));  // Set preferred message format to text mode
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    sendAT(GF("+CMGS=\""), number, GF("\""));  // set the phone number
 | 
			
		||||
    if (waitResponse(GF(">")) != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    stream.print(text);  // Actually send the message
 | 
			
		||||
    stream.write((char)0x1A);
 | 
			
		||||
    stream.flush();
 | 
			
		||||
    return waitResponse(60000L) == 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool sendSMS_UTF16(const String& number, const void* text, size_t len) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
@@ -649,9 +692,13 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
			
		||||
    while (true) {
 | 
			
		||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
			
		||||
  bool streamSkipUntil(char c) {
 | 
			
		||||
    const unsigned long timeout = 1000L;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (millis() - startMillis < timeout) {
 | 
			
		||||
      while (millis() - startMillis < timeout && !stream.available()) {
 | 
			
		||||
        TINY_GSM_YIELD();
 | 
			
		||||
      }
 | 
			
		||||
      if (stream.read() == c)
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -727,6 +774,7 @@ finish:
 | 
			
		||||
      }
 | 
			
		||||
      data = "";
 | 
			
		||||
    }
 | 
			
		||||
    //DBG('<', index, '>');
 | 
			
		||||
    return index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,6 @@
 | 
			
		||||
 | 
			
		||||
//#define TINY_GSM_DEBUG Serial
 | 
			
		||||
 | 
			
		||||
#if !defined(TINY_GSM_RX_BUFFER)
 | 
			
		||||
  #define TINY_GSM_RX_BUFFER 256
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TINY_GSM_MUX_COUNT 1  // Multi-plexing isn't supported using command mode
 | 
			
		||||
 | 
			
		||||
@@ -29,38 +26,54 @@ enum SimStatus {
 | 
			
		||||
  SIM_LOCKED = 2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum XBeeType {
 | 
			
		||||
  S6B    = 0,
 | 
			
		||||
  LTEC1  = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum RegStatus {
 | 
			
		||||
  REG_UNREGISTERED = 0,
 | 
			
		||||
  REG_OK           = 0,
 | 
			
		||||
  REG_UNREGISTERED = 1,
 | 
			
		||||
  REG_SEARCHING    = 2,
 | 
			
		||||
  REG_DENIED       = 3,
 | 
			
		||||
  REG_OK_HOME      = 1,
 | 
			
		||||
  REG_OK_ROAMING   = 5,
 | 
			
		||||
  REG_UNKNOWN      = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// These are responses to the HS command to get "hardware series"
 | 
			
		||||
enum XBeeType {
 | 
			
		||||
  XBEE_S6B_WIFI  = 0x601,  // Digi XBee® Wi-Fi
 | 
			
		||||
  XBEE_LTE1_VZN  = 0xB01,  // Digi XBee® Cellular LTE Cat 1
 | 
			
		||||
  XBEE_3G        = 0xB02,  // Digi XBee® Cellular 3G
 | 
			
		||||
  XBEE3_LTE1_ATT = 1,  // Digi XBee3™ Cellular LTE CAT 1  -- HS unknown to SRGD
 | 
			
		||||
  XBEE3_LTEM_ATT = 2,  // Digi XBee3™ Cellular LTE-M  -- HS unknown to SRGD
 | 
			
		||||
  XBEE3_LTENB    = 3,  // Digi XBee3™ Cellular NB-IoT  -- HS unknown to SRGD
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TinyGsm
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                   Declaration of the TinyGsmXBee Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
class TinyGsmXBee
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The XBee Internal Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
class GsmClient : public Client
 | 
			
		||||
{
 | 
			
		||||
  friend class TinyGsm;
 | 
			
		||||
  friend class TinyGsmXBee;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  GsmClient() {}
 | 
			
		||||
 | 
			
		||||
  GsmClient(TinyGsm& modem, uint8_t mux = 0) {
 | 
			
		||||
  GsmClient(TinyGsmXBee& modem, uint8_t mux = 0) {
 | 
			
		||||
    init(&modem, mux);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init(TinyGsm* modem, uint8_t mux = 0) {
 | 
			
		||||
  bool init(TinyGsmXBee* modem, uint8_t mux = 0) {
 | 
			
		||||
    this->at = modem;
 | 
			
		||||
    this->mux = mux;
 | 
			
		||||
    sock_connected = false;
 | 
			
		||||
@@ -73,19 +86,25 @@ public:
 | 
			
		||||
public:
 | 
			
		||||
  virtual int connect(const char *host, uint16_t port) {
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    at->commandMode();
 | 
			
		||||
    sock_connected = at->modemConnect(host, port, mux, false);
 | 
			
		||||
    at->writeChanges();
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
    bool sock_connected = false;
 | 
			
		||||
    if (at->commandMode())  {  // Don't try if we didn't successfully get into command mode
 | 
			
		||||
      sock_connected = at->modemConnect(host, port, mux, false);
 | 
			
		||||
      at->writeChanges();
 | 
			
		||||
      at->exitCommand();
 | 
			
		||||
    }
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    return sock_connected;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual int connect(IPAddress ip, uint16_t port) {
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    at->commandMode();
 | 
			
		||||
    sock_connected = at->modemConnect(ip, port, mux, false);
 | 
			
		||||
    at->writeChanges();
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
    bool sock_connected = false;
 | 
			
		||||
    if (at->commandMode())  {  // Don't try if we didn't successfully get into command mode
 | 
			
		||||
      sock_connected = at->modemConnect(ip, port, mux, false);
 | 
			
		||||
      at->writeChanges();
 | 
			
		||||
      at->exitCommand();
 | 
			
		||||
    }
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    return sock_connected;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -100,7 +119,7 @@ public:
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
    at->modemSend("", 1, mux);
 | 
			
		||||
    at->commandMode();
 | 
			
		||||
    at->sendAT(GF("TM64"));  // Set socket timeout back to 10seconds;
 | 
			
		||||
    at->sendAT(GF("TM64"));  // Set socket timeout back to 10 seconds;
 | 
			
		||||
    at->waitResponse();
 | 
			
		||||
    at->writeChanges();
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
@@ -110,7 +129,6 @@ public:
 | 
			
		||||
 | 
			
		||||
  virtual size_t write(const uint8_t *buf, size_t size) {
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    //at->maintain();
 | 
			
		||||
    return at->modemSend(buf, size, mux);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -125,7 +143,7 @@ public:
 | 
			
		||||
 | 
			
		||||
  virtual int read(uint8_t *buf, size_t size) {
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    return at->stream.readBytes(buf, size);
 | 
			
		||||
    return at->stream.readBytes((char*)buf, size);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual int read() {
 | 
			
		||||
@@ -151,47 +169,69 @@ public:
 | 
			
		||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  TinyGsm*      at;
 | 
			
		||||
  TinyGsmXBee*  at;
 | 
			
		||||
  uint8_t       mux;
 | 
			
		||||
  bool          sock_connected;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The Secure XBee Client Class
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GsmClientSecure : public GsmClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  GsmClientSecure() {}
 | 
			
		||||
 | 
			
		||||
  GsmClientSecure(TinyGsm& modem, uint8_t mux = 1)
 | 
			
		||||
  GsmClientSecure(TinyGsmXBee& modem, uint8_t mux = 1)
 | 
			
		||||
    : GsmClient(modem, mux)
 | 
			
		||||
  {}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  virtual int connect(const char *host, uint16_t port) {
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    at->commandMode();
 | 
			
		||||
    sock_connected = at->modemConnect(host, port, mux, true);
 | 
			
		||||
    at->writeChanges();
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
    bool sock_connected = false;
 | 
			
		||||
    if (at->commandMode())  {  // Don't try if we didn't successfully get into command mode
 | 
			
		||||
      sock_connected = at->modemConnect(host, port, mux, true);
 | 
			
		||||
      at->writeChanges();
 | 
			
		||||
      at->exitCommand();
 | 
			
		||||
    }
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    return sock_connected;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual int connect(IPAddress ip, uint16_t port) {
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    at->commandMode();
 | 
			
		||||
    sock_connected = at->modemConnect(ip, port, mux, true);
 | 
			
		||||
    at->writeChanges();
 | 
			
		||||
    at->exitCommand();
 | 
			
		||||
    bool sock_connected = false;
 | 
			
		||||
    if (at->commandMode())  {  // Don't try if we didn't successfully get into command mode
 | 
			
		||||
      sock_connected = at->modemConnect(ip, port, mux, true);
 | 
			
		||||
      at->writeChanges();
 | 
			
		||||
      at->exitCommand();
 | 
			
		||||
    }
 | 
			
		||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
			
		||||
    return sock_connected;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//                          The XBee Modem Functions
 | 
			
		||||
//============================================================================//
 | 
			
		||||
//============================================================================//
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  TinyGsm(Stream& stream)
 | 
			
		||||
#ifdef GSM_DEFAULT_STREAM
 | 
			
		||||
  TinyGsmXBee(Stream& stream = GSM_DEFAULT_STREAM)
 | 
			
		||||
#else
 | 
			
		||||
  TinyGsmXBee(Stream& stream)
 | 
			
		||||
#endif
 | 
			
		||||
    : stream(stream)
 | 
			
		||||
  {
 | 
			
		||||
    memset(sockets, 0, sizeof(sockets));
 | 
			
		||||
  }
 | 
			
		||||
  {}
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Basic functions
 | 
			
		||||
@@ -201,23 +241,53 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool init() {
 | 
			
		||||
    guardTime = 1100;
 | 
			
		||||
    commandMode();
 | 
			
		||||
    guardTime = 1100;  // Start with a default guard time of 1 second
 | 
			
		||||
 | 
			
		||||
    if (!commandMode(10)) return false;  // Try up to 10 times for the init
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("AP0"));  // Put in transparent mode
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    bool ret_val = waitResponse() == 1;
 | 
			
		||||
    ret_val &= writeChanges();
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("GT64")); // shorten the guard time to 100ms
 | 
			
		||||
    ret_val &= waitResponse();
 | 
			
		||||
    ret_val &= writeChanges();
 | 
			
		||||
    if (ret_val) guardTime = 125;
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("HS"));  // Get the "Hardware Series";
 | 
			
		||||
    String res = readResponse();
 | 
			
		||||
    char buf[4] = {0,};  // Set up buffer for response
 | 
			
		||||
    res.toCharArray(buf, 4);
 | 
			
		||||
    int intRes = strtol(buf, 0, 16);
 | 
			
		||||
    beeType = (XBeeType)intRes;
 | 
			
		||||
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return ret_val;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void setBaud(unsigned long baud) {
 | 
			
		||||
    if (!commandMode()) return;
 | 
			
		||||
    switch(baud)
 | 
			
		||||
    {
 | 
			
		||||
      case 2400: sendAT(GF("BD1")); break;
 | 
			
		||||
      case 4800: sendAT(GF("BD2")); break;
 | 
			
		||||
      case 9600: sendAT(GF("BD3")); break;
 | 
			
		||||
      case 19200: sendAT(GF("BD4")); break;
 | 
			
		||||
      case 38400: sendAT(GF("BD5")); break;
 | 
			
		||||
      case 57600: sendAT(GF("BD6")); break;
 | 
			
		||||
      case 115200: sendAT(GF("BD7")); break;
 | 
			
		||||
      case 230400: sendAT(GF("BD8")); break;
 | 
			
		||||
      case 460800: sendAT(GF("BD9")); break;
 | 
			
		||||
      case 921600: sendAT(GF("BDA")); break;
 | 
			
		||||
      default: {
 | 
			
		||||
          DBG(GF("Specified baud rate is unsupported! Setting to 9600 baud."));
 | 
			
		||||
          sendAT(GF("BD3")); // Set to default of 9600
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    sendAT(GF("HS"));  // Get the "Hardware Series"; 0x601 for S6B (Wifi)
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    if (res == "601") beeType = S6B;
 | 
			
		||||
    else beeType = LTEC1;
 | 
			
		||||
    guardTime = 125;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool testAT(unsigned long timeout = 10000L) {
 | 
			
		||||
@@ -238,52 +308,100 @@ public:
 | 
			
		||||
  void maintain() {}
 | 
			
		||||
 | 
			
		||||
  bool factoryDefault() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;  // Return immediately
 | 
			
		||||
    sendAT(GF("RE"));
 | 
			
		||||
    bool ret_val = waitResponse() == 1;
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    ret_val &= writeChanges();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return ret_val;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getModemInfo() {
 | 
			
		||||
    String modemInf = "";
 | 
			
		||||
    if (!commandMode()) return modemInf;  // Try up to 10 times for the init
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("HS"));  // Get the "Hardware Series"
 | 
			
		||||
    modemInf += readResponse();
 | 
			
		||||
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return modemInf;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool hasSSL() {
 | 
			
		||||
    if (beeType == S6B) return false;
 | 
			
		||||
    if (beeType == XBEE_S6B_WIFI) return false;
 | 
			
		||||
    else return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  XBeeType getBeeType() {
 | 
			
		||||
    return beeType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getBeeName() {
 | 
			
		||||
    switch (beeType){
 | 
			
		||||
      case XBEE_S6B_WIFI: return "Digi XBee® Wi-Fi";
 | 
			
		||||
      case XBEE_LTE1_VZN: return "Digi XBee® Cellular LTE Cat 1";
 | 
			
		||||
      case XBEE_3G: return "Digi XBee® Cellular 3G";
 | 
			
		||||
      case XBEE3_LTE1_ATT: return "Digi XBee3™ Cellular LTE CAT 1";
 | 
			
		||||
      case XBEE3_LTEM_ATT: return "Digi XBee3™ Cellular LTE-M";
 | 
			
		||||
      case XBEE3_LTENB: return "Digi XBee3™ Cellular NB-IoT";
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Power functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  bool restart() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;  // Return immediately
 | 
			
		||||
    sendAT(GF("AM1"));  // Digi suggests putting into airplane mode before restarting
 | 
			
		||||
                       // This allows the sockets and connections to close cleanly
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    if (waitResponse() != 1) goto fail;
 | 
			
		||||
    sendAT(GF("FR"));
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (waitResponse() != 1) goto fail;
 | 
			
		||||
 | 
			
		||||
    delay (2000);  // Actually resets about 2 seconds later
 | 
			
		||||
 | 
			
		||||
    // Wait until reboot complete and responds to command mode call again
 | 
			
		||||
    for (unsigned long start = millis(); millis() - start < 60000L; ) {
 | 
			
		||||
      if (commandMode()) {
 | 
			
		||||
      if (commandMode(1)) {
 | 
			
		||||
        sendAT(GF("AM0"));  // Turn off airplane mode
 | 
			
		||||
        writeChanges();
 | 
			
		||||
        exitCommand();
 | 
			
		||||
        return true;
 | 
			
		||||
        delay(250);  // wait a litle before trying again
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return false;;
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    fail:
 | 
			
		||||
      exitCommand();
 | 
			
		||||
      return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void setupPinSleep() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    sendAT(GF("SM"),1);
 | 
			
		||||
  void setupPinSleep(bool maintainAssociation = false) {
 | 
			
		||||
    if (!commandMode()) return;  // Return immediately
 | 
			
		||||
    sendAT(GF("SM"),1);  // Pin sleep
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    if (beeType == S6B) {
 | 
			
		||||
        sendAT(GF("SO"),200);
 | 
			
		||||
    if (beeType == XBEE_S6B_WIFI && !maintainAssociation) {
 | 
			
		||||
        sendAT(GF("SO"),200);  // For lowest power, dissassociated deep sleep
 | 
			
		||||
        waitResponse();
 | 
			
		||||
    }
 | 
			
		||||
    else if (!maintainAssociation){
 | 
			
		||||
        sendAT(GF("SO"),1);  // For lowest power, dissassociated deep sleep
 | 
			
		||||
                             // Not supported by all modules, will return "ERROR"
 | 
			
		||||
        waitResponse();
 | 
			
		||||
    }
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool poweroff() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * SIM card functions
 | 
			
		||||
   */
 | 
			
		||||
@@ -293,23 +411,17 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getSimCCID() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return "";  // Return immediately
 | 
			
		||||
    sendAT(GF("S#"));
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
			
		||||
    String res = readResponse();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getIMEI() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return "";  // Return immediately
 | 
			
		||||
    sendAT(GF("IM"));
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
			
		||||
    String res = readResponse();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
@@ -319,37 +431,82 @@ public:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RegStatus getRegistrationStatus() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return REG_UNKNOWN;  // Return immediately
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("AI"));
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
			
		||||
    String res = readResponse();
 | 
			
		||||
    char buf[3] = {0,};  // Set up buffer for response
 | 
			
		||||
    res.toCharArray(buf, 3);
 | 
			
		||||
    int intRes = strtol(buf, 0, 16);
 | 
			
		||||
    RegStatus stat = REG_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
    switch (beeType){
 | 
			
		||||
      case XBEE_S6B_WIFI: {
 | 
			
		||||
        if(intRes == 0x00)  // 0x00 Successfully joined an access point, established IP addresses and IP listening sockets
 | 
			
		||||
          stat = REG_OK;
 | 
			
		||||
        else if(intRes == 0x01)  // 0x01 Wi-Fi transceiver initialization in progress.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x02)  // 0x02 Wi-Fi transceiver initialized, but not yet scanning for access point.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x13) { // 0x13 Disconnecting from access point.
 | 
			
		||||
          restart();  // Restart the device; the S6B tends to get stuck "disconnecting"
 | 
			
		||||
          stat = REG_UNREGISTERED;
 | 
			
		||||
        }
 | 
			
		||||
        else if(intRes == 0x23)  // 0x23 SSID not configured.
 | 
			
		||||
          stat = REG_UNREGISTERED;
 | 
			
		||||
        else if(intRes == 0x24)  // 0x24 Encryption key invalid (either NULL or invalid length for WEP).
 | 
			
		||||
          stat = REG_DENIED;
 | 
			
		||||
        else if(intRes == 0x27)  // 0x27 SSID was found, but join failed.
 | 
			
		||||
          stat = REG_DENIED;
 | 
			
		||||
        else if(intRes == 0x40)  // 0x40 Waiting for WPA or WPA2 Authentication.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x41)  // 0x41 Device joined a network and is waiting for IP configuration to complete
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x42)  // 0x42 Device is joined, IP is configured, and listening sockets are being set up.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0xFF)  // 0xFF Device is currently scanning for the configured SSID.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else stat = REG_UNKNOWN;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      default: {
 | 
			
		||||
        if(intRes == 0x00)  // 0x00 Connected to the Internet.
 | 
			
		||||
          stat = REG_OK;
 | 
			
		||||
        else if(intRes == 0x22)  // 0x22 Registering to cellular network.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x23)  // 0x23 Connecting to the Internet.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else if(intRes == 0x24)  // 0x24 The cellular component is missing, corrupt, or otherwise in error.
 | 
			
		||||
          stat = REG_UNKNOWN;
 | 
			
		||||
        else if(intRes == 0x25)  // 0x25 Cellular network registration denied.
 | 
			
		||||
          stat = REG_DENIED;
 | 
			
		||||
        else if(intRes == 0x2A) {  // 0x2A Airplane mode.
 | 
			
		||||
          sendAT(GF("AM0"));  // Turn off airplane mode
 | 
			
		||||
          waitResponse();
 | 
			
		||||
          writeChanges();
 | 
			
		||||
          stat = REG_UNKNOWN;
 | 
			
		||||
        }
 | 
			
		||||
        else if(intRes == 0x2F) {  // 0x2F Bypass mode active.
 | 
			
		||||
          sendAT(GF("AP0"));  // Set back to transparent mode
 | 
			
		||||
          waitResponse();
 | 
			
		||||
          writeChanges();
 | 
			
		||||
          stat = REG_UNKNOWN;
 | 
			
		||||
        }
 | 
			
		||||
        else if(intRes == 0xFF)  // 0xFF Device is currently scanning for the configured SSID.
 | 
			
		||||
          stat = REG_SEARCHING;
 | 
			
		||||
        else stat = REG_UNKNOWN;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    exitCommand();
 | 
			
		||||
 | 
			
		||||
    if(res == GF("0"))
 | 
			
		||||
      return REG_OK_HOME;
 | 
			
		||||
 | 
			
		||||
    else if(res == GF("13") || res == GF("2A"))
 | 
			
		||||
      return REG_UNREGISTERED;
 | 
			
		||||
 | 
			
		||||
    else if(res == GF("FF") || res == GF("22") || res == GF("23") ||
 | 
			
		||||
            res == GF("40") || res == GF("41") || res == GF("42"))
 | 
			
		||||
      return REG_SEARCHING;
 | 
			
		||||
 | 
			
		||||
    else if(res == GF("24") || res == GF("25") || res == GF("27"))
 | 
			
		||||
      return REG_DENIED;
 | 
			
		||||
 | 
			
		||||
    else return REG_UNKNOWN;
 | 
			
		||||
    return stat;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getOperator() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return "";  // Return immediately
 | 
			
		||||
    sendAT(GF("MN"));
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
			
		||||
    String res = readResponse();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
@@ -359,25 +516,21 @@ public:
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  int getSignalQuality() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (beeType == S6B) sendAT(GF("LM"));  // ask for the "link margin" - the dB above sensitivity
 | 
			
		||||
    if (!commandMode()) return 0;  // Return immediately
 | 
			
		||||
    if (beeType == XBEE_S6B_WIFI) sendAT(GF("LM"));  // ask for the "link margin" - the dB above sensitivity
 | 
			
		||||
    else sendAT(GF("DB"));  // ask for the cell strength in dBm
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
			
		||||
    char buf[2] = {0};  // Set up buffer for response
 | 
			
		||||
    buf[0] = streamRead();
 | 
			
		||||
    buf[1] = streamRead();
 | 
			
		||||
    // DBG(buf[0], buf[1], "\n");
 | 
			
		||||
    String res = readResponse();  // it works better if we read in as a string
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    int intr = strtol(buf, 0, 16);
 | 
			
		||||
    if (beeType == S6B) return -93 + intr;  // the maximum sensitivity is -93dBm
 | 
			
		||||
    else return -1*intr; // need to convert to negative number
 | 
			
		||||
    char buf[3] = {0,};  // Set up buffer for response
 | 
			
		||||
    res.toCharArray(buf, 3);
 | 
			
		||||
    int intRes = strtol(buf, 0, 16);
 | 
			
		||||
    if (beeType == XBEE_S6B_WIFI) return -93 + intRes;  // the maximum sensitivity is -93dBm
 | 
			
		||||
    else return -1*intRes; // need to convert to negative number
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool isNetworkConnected() {
 | 
			
		||||
    RegStatus s = getRegistrationStatus();
 | 
			
		||||
    return (s == REG_OK_HOME || s == REG_OK_ROAMING);
 | 
			
		||||
    return (s == REG_OK);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool waitForNetwork(unsigned long timeout = 60000L) {
 | 
			
		||||
@@ -385,7 +538,7 @@ public:
 | 
			
		||||
      if (isNetworkConnected()) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      delay(250);
 | 
			
		||||
      // delay(250);  // Enough delay going in and out of command mode
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
@@ -395,20 +548,16 @@ public:
 | 
			
		||||
   */
 | 
			
		||||
  bool networkConnect(const char* ssid, const char* pwd) {
 | 
			
		||||
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;  // return immediately
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("EE"), 2);  // Set security to WPA2
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    if (waitResponse() != 1) goto fail;
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("ID"), ssid);
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    if (waitResponse() != 1) goto fail;
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("PK"), pwd);
 | 
			
		||||
    if (waitResponse() != 1) {
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    if (waitResponse() != 1) goto fail;
 | 
			
		||||
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
@@ -421,17 +570,22 @@ fail:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool networkDisconnect() {
 | 
			
		||||
    return false;  // Doesn't support disconnecting
 | 
			
		||||
    if (!commandMode()) return false;  // return immediately
 | 
			
		||||
    sendAT(GF("NR0"));  // Do a network reset in order to disconnect
 | 
			
		||||
    int res = (1 == waitResponse(5000));
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getLocalIP() {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return "";  // Return immediately
 | 
			
		||||
    sendAT(GF("MY"));
 | 
			
		||||
    String IPaddr; IPaddr.reserve(16);
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (stream.available() < 8 && millis() - startMillis < 30000) {};
 | 
			
		||||
    IPaddr = streamReadUntil('\r');  // read result
 | 
			
		||||
    // wait for the response - this response can be very slow
 | 
			
		||||
    IPaddr = readResponse(30000);
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    IPaddr.trim();
 | 
			
		||||
    return IPaddr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -443,7 +597,7 @@ fail:
 | 
			
		||||
   * GPRS functions
 | 
			
		||||
   */
 | 
			
		||||
  bool gprsConnect(const char* apn, const char* user = NULL, const char* pwd = NULL) {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;  // Return immediately
 | 
			
		||||
    sendAT(GF("AN"), apn);  // Set the APN
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    writeChanges();
 | 
			
		||||
@@ -451,8 +605,20 @@ fail:
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool gprsDisconnect() {  // TODO
 | 
			
		||||
    return false;
 | 
			
		||||
  bool gprsDisconnect() {
 | 
			
		||||
    if (!commandMode()) return false;  // return immediately
 | 
			
		||||
    sendAT(GF("AM1"));  // Cheating and disconnecting by turning on airplane mode
 | 
			
		||||
    int res = (1 == waitResponse(5000));
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    sendAT(GF("AM0"));  // Airplane mode off
 | 
			
		||||
    waitResponse(5000);
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool isGprsConnected() {
 | 
			
		||||
    return isNetworkConnected();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
@@ -462,35 +628,67 @@ fail:
 | 
			
		||||
  String sendUSSD(const String& code) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
			
		||||
 | 
			
		||||
  bool sendSMS(const String& number, const String& text) {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;  // Return immediately
 | 
			
		||||
 | 
			
		||||
    sendAT(GF("IP"), 2);  // Put in text messaging mode
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    if (waitResponse() !=1) goto fail;
 | 
			
		||||
    sendAT(GF("PH"), number);  // Set the phone number
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    sendAT(GF("TDD"));  // Set the text delimiter to the standard 0x0D (carriabe return)
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    writeChanges();
 | 
			
		||||
    if (waitResponse() !=1) goto fail;
 | 
			
		||||
    sendAT(GF("TDD"));  // Set the text delimiter to the standard 0x0D (carriage return)
 | 
			
		||||
    if (waitResponse() !=1) goto fail;
 | 
			
		||||
    if (!writeChanges()) goto fail;
 | 
			
		||||
 | 
			
		||||
    exitCommand();
 | 
			
		||||
    stream.print(text);
 | 
			
		||||
    streamWrite(text);
 | 
			
		||||
    stream.write((char)0x0D);  // close off with the carriage return
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
    fail:
 | 
			
		||||
      exitCommand();
 | 
			
		||||
      return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Location functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
  int modemConnect(const char* host, uint16_t port, uint8_t mux = 0, bool ssl = false) {
 | 
			
		||||
    sendAT(GF("LA"), host);
 | 
			
		||||
  /*
 | 
			
		||||
   * Battery functions
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
  int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
  bool modemConnect(const char* host, uint16_t port, uint8_t mux = 0, bool ssl = false) {
 | 
			
		||||
    String strIP; strIP.reserve(16);
 | 
			
		||||
    // wait for the response
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (stream.available() < 8 && millis() - startMillis < 30000) {};
 | 
			
		||||
    strIP = streamReadUntil('\r');  // read result
 | 
			
		||||
    IPAddress ip = TinyGsmIpFromString(strIP);
 | 
			
		||||
    return modemConnect(ip, port, mux, ssl);
 | 
			
		||||
    bool gotIP = false;
 | 
			
		||||
    // XBee's require a numeric IP address for connection, but do provide the
 | 
			
		||||
    // functionality to look up the IP address from a fully qualified domain name
 | 
			
		||||
    while (!gotIP && millis() - startMillis < 45000L)  // the lookup can take a while
 | 
			
		||||
    {
 | 
			
		||||
      sendAT(GF("LA"), host);
 | 
			
		||||
      while (stream.available() < 4) {};  // wait for any response
 | 
			
		||||
      strIP = stream.readStringUntil('\r');  // read result
 | 
			
		||||
      strIP.trim();
 | 
			
		||||
      DBG("<<< ", strIP);
 | 
			
		||||
      if (!strIP.endsWith(GF("ERROR"))) gotIP = true;
 | 
			
		||||
      delay(100);  // short wait before trying again
 | 
			
		||||
    }
 | 
			
		||||
    if (gotIP) {  // No reason to continue if we don't know the IP address
 | 
			
		||||
      IPAddress ip = TinyGsmIpFromString(strIP);
 | 
			
		||||
      return modemConnect(ip, port, mux, ssl);
 | 
			
		||||
    }
 | 
			
		||||
    else return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool ssl = false) {
 | 
			
		||||
  bool modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool ssl = false) {
 | 
			
		||||
    bool success = true;
 | 
			
		||||
    String host; host.reserve(16);
 | 
			
		||||
    host += ip[0];
 | 
			
		||||
    host += ".";
 | 
			
		||||
@@ -500,17 +698,17 @@ private:
 | 
			
		||||
    host += ".";
 | 
			
		||||
    host += ip[3];
 | 
			
		||||
    if (ssl) {
 | 
			
		||||
      sendAT(GF("IP"), 4);  // Put in TCP mode
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      sendAT(GF("IP"), 4);  // Put in SSL over TCP communication mode
 | 
			
		||||
      success &= (1 == waitResponse());
 | 
			
		||||
    } else {
 | 
			
		||||
      sendAT(GF("IP"), 1);  // Put in TCP mode
 | 
			
		||||
      waitResponse();
 | 
			
		||||
      success &= (1 == waitResponse());
 | 
			
		||||
    }
 | 
			
		||||
    sendAT(GF("DL"), host);  // Set the "Destination Address Low"
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    success &= (1 == waitResponse());
 | 
			
		||||
    sendAT(GF("DE"), String(port, HEX));  // Set the destination port
 | 
			
		||||
    int rsp = waitResponse();
 | 
			
		||||
    return rsp;
 | 
			
		||||
    success &= (1 == waitResponse());
 | 
			
		||||
    return success;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int modemSend(const void* buff, size_t len, uint8_t mux = 0) {
 | 
			
		||||
@@ -520,7 +718,7 @@ private:
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool modemGetConnected(uint8_t mux = 0) {
 | 
			
		||||
    commandMode();
 | 
			
		||||
    if (!commandMode()) return false;
 | 
			
		||||
    sendAT(GF("AI"));
 | 
			
		||||
    int res = waitResponse(GF("0"));
 | 
			
		||||
    exitCommand();
 | 
			
		||||
@@ -542,32 +740,33 @@ public:
 | 
			
		||||
    streamWrite(tail...);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int streamRead() { return stream.read(); }
 | 
			
		||||
 | 
			
		||||
  String streamReadUntil(char c) {
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    String return_string = stream.readStringUntil(c);
 | 
			
		||||
    return_string.trim();
 | 
			
		||||
    // DBG(return_string, c);
 | 
			
		||||
    return return_string;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void streamClear(void) {
 | 
			
		||||
    while (stream.available()) { streamRead(); }
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    while (stream.available()) { stream.read(); }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool commandMode(void) {
 | 
			
		||||
    delay(guardTime);  // cannot send anything for 1 second before entering command mode
 | 
			
		||||
    streamWrite(GF("+++"));  // enter command mode
 | 
			
		||||
    // DBG("\r\n+++\r\n");
 | 
			
		||||
    return 1 == waitResponse(guardTime*2);
 | 
			
		||||
  bool commandMode(int retries = 2) {
 | 
			
		||||
    int triesMade = 0;
 | 
			
		||||
    bool success = false;
 | 
			
		||||
    streamClear();  // Empty everything in the buffer before starting
 | 
			
		||||
    while (!success and triesMade < retries) {
 | 
			
		||||
      // Cannot send anything for 1 "guard time" before entering command mode
 | 
			
		||||
      // Default guard time is 1s, but the init fxn decreases it to 250 ms
 | 
			
		||||
      delay(guardTime);
 | 
			
		||||
      streamWrite(GF("+++"));  // enter command mode
 | 
			
		||||
      DBG("+++");
 | 
			
		||||
      success = (1 == waitResponse(guardTime*2));
 | 
			
		||||
      triesMade ++;
 | 
			
		||||
    }
 | 
			
		||||
    return success;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeChanges(void) {
 | 
			
		||||
  bool writeChanges(void) {
 | 
			
		||||
    sendAT(GF("WR"));  // Write changes to flash
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    if (1 != waitResponse()) return false;
 | 
			
		||||
    sendAT(GF("AC"));  // Apply changes
 | 
			
		||||
    waitResponse();
 | 
			
		||||
    if (1 != waitResponse()) return false;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void exitCommand(void) {
 | 
			
		||||
@@ -575,6 +774,16 @@ public:
 | 
			
		||||
    waitResponse();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String readResponse(uint32_t timeout = 1000) {
 | 
			
		||||
    TINY_GSM_YIELD();
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    while (!stream.available() && millis() - startMillis < timeout) {};
 | 
			
		||||
    String res = stream.readStringUntil('\r');  // lines end with carriage returns
 | 
			
		||||
    res.trim();
 | 
			
		||||
    DBG("<<< ", res);
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<typename... Args>
 | 
			
		||||
  void sendAT(Args... cmd) {
 | 
			
		||||
    streamWrite("AT", cmd..., GSM_NL);
 | 
			
		||||
@@ -594,13 +803,13 @@ public:
 | 
			
		||||
    String r4s(r4); r4s.trim();
 | 
			
		||||
    String r5s(r5); r5s.trim();
 | 
			
		||||
    DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
 | 
			
		||||
    data.reserve(64);
 | 
			
		||||
    data.reserve(16);  // Should never be getting much here for the XBee
 | 
			
		||||
    int index = 0;
 | 
			
		||||
    unsigned long startMillis = millis();
 | 
			
		||||
    do {
 | 
			
		||||
      TINY_GSM_YIELD();
 | 
			
		||||
      while (stream.available() > 0) {
 | 
			
		||||
        int a = streamRead();
 | 
			
		||||
        int a = stream.read();
 | 
			
		||||
        if (a <= 0) continue; // Skip 0x00 bytes, just in case
 | 
			
		||||
        data += (char)a;
 | 
			
		||||
        if (r1 && data.endsWith(r1)) {
 | 
			
		||||
@@ -625,7 +834,7 @@ finish:
 | 
			
		||||
    if (!index) {
 | 
			
		||||
      data.trim();
 | 
			
		||||
      data.replace(GSM_NL GSM_NL, GSM_NL);
 | 
			
		||||
      data.replace(GSM_NL, "\r\n" "    ");
 | 
			
		||||
      data.replace(GSM_NL, "\r\n    ");
 | 
			
		||||
      if (data.length()) {
 | 
			
		||||
        DBG("### Unhandled:", data, "\r\n");
 | 
			
		||||
      } else {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user