Merge branch 'master' of https://github.com/vshymanskyy/TinyGSM
This commit is contained in:
		
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -35,7 +35,7 @@ TinyGSM also pulls data gently from the modem (whenever possible), so it can ope
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Features
 | 
					## Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Feature \ Modem              | SIM8xx | U2     | A6/A7/A20 | M590 | ESP8266 | XBee 
 | 
					Feature \ Modem              | SIM8xx | u-Blox | A6/A7/A20 | M590 | ESP8266 | XBee
 | 
				
			||||||
---                          | ---    | ---    | ---       | ---  | ---     | ---
 | 
					---                          | ---    | ---    | ---       | ---  | ---     | ---
 | 
				
			||||||
**Data connections**
 | 
					**Data connections**
 | 
				
			||||||
TCP (HTTP, MQTT, Blynk, ...) | ✔      | ✔      | ✔         | ✔    | ✔       | ✔
 | 
					TCP (HTTP, MQTT, Blynk, ...) | ✔      | ✔      | ✔         | ✔    | ✔       | ✔
 | 
				
			||||||
@@ -45,7 +45,7 @@ SSL/TLS (HTTPS)              | ✔¹     | ✔      | 🅧        | 🅧    | 
 | 
				
			|||||||
Sending USSD requests        | ✔      |        | ✔         | ✔    | 🅧       |
 | 
					Sending USSD requests        | ✔      |        | ✔         | ✔    | 🅧       |
 | 
				
			||||||
Decoding 7,8,16-bit response | ✔      |        | ✔         | ✔    | 🅧      |
 | 
					Decoding 7,8,16-bit response | ✔      |        | ✔         | ✔    | 🅧      |
 | 
				
			||||||
**SMS**
 | 
					**SMS**
 | 
				
			||||||
Sending                      | ✔      |        | ✔         | ✔    | 🅧      | ✔
 | 
					Sending                      | ✔      | ✔      | ✔         | ✔    | 🅧      | ✔
 | 
				
			||||||
Sending Unicode              | ✔      |        | ◌         | 🅧   | 🅧      |
 | 
					Sending Unicode              | ✔      |        | ◌         | 🅧   | 🅧      |
 | 
				
			||||||
Reading                      |        |        |           |      | 🅧      |
 | 
					Reading                      |        |        |           |      | 🅧      |
 | 
				
			||||||
Incoming message event       |        |        |           | ?    | 🅧      |
 | 
					Incoming message event       |        |        |           | ?    | 🅧      |
 | 
				
			||||||
@@ -70,7 +70,7 @@ GPS/GNSS                     | ✔¹     | 🅧     | ◌¹        | 🅧   | 
 | 
				
			|||||||
- ESP8266 (AT commands interface, similar to GSM modems)
 | 
					- ESP8266 (AT commands interface, similar to GSM modems)
 | 
				
			||||||
- Digi XBee WiFi and Cellular (using XBee command mode)
 | 
					- Digi XBee WiFi and Cellular (using XBee command mode)
 | 
				
			||||||
- Neoway M590
 | 
					- Neoway M590
 | 
				
			||||||
- U-blox SARA U2
 | 
					- u-blox Cellular Modems (LEON-G100, LISA-U2xx, SARA-G3xx, SARA-U2xx, TOBY-L2xx, LARA-R2xx, MPCI-L2xx)
 | 
				
			||||||
- Quectel BG96 ***(alpha)***
 | 
					- Quectel BG96 ***(alpha)***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Supported boards/modules
 | 
					### Supported boards/modules
 | 
				
			||||||
@@ -180,11 +180,11 @@ This may result in problems such as:
 | 
				
			|||||||
 * etc.
 | 
					 * etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To return module to **Factory Defaults**, use this sketch:  
 | 
					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
 | 
					### Goouuu Tech IOT-GA6 vs AI-Thinker A6 confusion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It turns out that **Goouuu Tech IOT-GA6** is not the same as **AI-Thinker A6**. Unfortunately IOT-GA6 is not supported out of the box yet. There are some hints that IOT-GA6 firmware may be updated to match A6... But no one confirmed that up to my knowledge.
 | 
					It turns out that **Goouuu Tech IOT-GA6** is not the same as **AI-Thinker A6**. Unfortunately IOT-GA6 is not supported out of the box yet. There are some hints that IOT-GA6 firmware may be updated to match A6... See [this topic](https://github.com/vshymanskyy/TinyGSM/issues/164).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__________
 | 
					__________
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,9 +34,9 @@
 | 
				
			|||||||
#elif defined(TINY_GSM_MODEM_UBLOX)
 | 
					#elif defined(TINY_GSM_MODEM_UBLOX)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
					  #define TINY_GSM_MODEM_HAS_GPRS
 | 
				
			||||||
  #include <TinyGsmClientUBLOX.h>
 | 
					  #include <TinyGsmClientUBLOX.h>
 | 
				
			||||||
  typedef TinyGsmU201 TinyGsm;
 | 
					  typedef TinyGsmUBLOX TinyGsm;
 | 
				
			||||||
  typedef TinyGsmU201::GsmClient TinyGsmClient;
 | 
					  typedef TinyGsmUBLOX::GsmClient TinyGsmClient;
 | 
				
			||||||
  typedef TinyGsmU201::GsmClientSecure TinyGsmClientSecure;
 | 
					  typedef TinyGsmUBLOX::GsmClientSecure TinyGsmClientSecure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_BG96)
 | 
					#elif defined(TINY_GSM_MODEM_BG96)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
					  #define TINY_GSM_MODEM_HAS_GPRS
 | 
				
			||||||
@@ -47,24 +47,29 @@
 | 
				
			|||||||
#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
 | 
					#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
					  #define TINY_GSM_MODEM_HAS_GPRS
 | 
				
			||||||
  #include <TinyGsmClientA6.h>
 | 
					  #include <TinyGsmClientA6.h>
 | 
				
			||||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					  typedef TinyGsmA6 TinyGsm;
 | 
				
			||||||
 | 
					  typedef TinyGsmA6::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_M590)
 | 
					#elif defined(TINY_GSM_MODEM_M590)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
					  #define TINY_GSM_MODEM_HAS_GPRS
 | 
				
			||||||
  #include <TinyGsmClientM590.h>
 | 
					  #include <TinyGsmClientM590.h>
 | 
				
			||||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					  typedef TinyGsmM590 TinyGsm;
 | 
				
			||||||
 | 
					  typedef TinyGsmM590::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_ESP8266)
 | 
					#elif defined(TINY_GSM_MODEM_ESP8266)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_WIFI
 | 
					  #define TINY_GSM_MODEM_HAS_WIFI
 | 
				
			||||||
  #include <TinyGsmClientESP8266.h>
 | 
					  #include <TinyGsmClientESP8266.h>
 | 
				
			||||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					  typedef TinyGsmESP8266 TinyGsm;
 | 
				
			||||||
  typedef TinyGsm::GsmClientSecure TinyGsmClientSecure;
 | 
					  typedef TinyGsmESP8266::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					  typedef TinyGsmESP8266::GsmClientSecure TinyGsmClientSecure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_XBEE)
 | 
					#elif defined(TINY_GSM_MODEM_XBEE)
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_GPRS
 | 
					  #define TINY_GSM_MODEM_HAS_GPRS
 | 
				
			||||||
  #define TINY_GSM_MODEM_HAS_WIFI
 | 
					  #define TINY_GSM_MODEM_HAS_WIFI
 | 
				
			||||||
  #include <TinyGsmClientXBee.h>
 | 
					  #include <TinyGsmClientXBee.h>
 | 
				
			||||||
  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					  typedef TinyGsmXBee TinyGsm;
 | 
				
			||||||
 | 
					  typedef TinyGsmXBee::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					  typedef TinyGsmXBee::GsmClientSecure TinyGsmClientSecure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  #error "Please define GSM modem model"
 | 
					  #error "Please define GSM modem model"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,25 +38,37 @@ enum RegStatus {
 | 
				
			|||||||
  REG_UNKNOWN      = 4,
 | 
					  REG_UNKNOWN      = 4,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                       Declaration of the TinyGsmA6 Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsm
 | 
					class TinyGsmA6
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The Internal A6 Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsm;
 | 
					  friend class TinyGsmA6;
 | 
				
			||||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
					  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClient() {}
 | 
					  GsmClient() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClient(TinyGsm& modem) {
 | 
					  GsmClient(TinyGsmA6& modem) {
 | 
				
			||||||
    init(&modem);
 | 
					    init(&modem);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsm* modem) {
 | 
					  bool init(TinyGsmA6* modem) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = -1;
 | 
					    this->mux = -1;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
@@ -167,15 +179,33 @@ public:
 | 
				
			|||||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsmA6*      at;
 | 
				
			||||||
  uint8_t         mux;
 | 
					  uint8_t         mux;
 | 
				
			||||||
  bool            sock_connected;
 | 
					  bool            sock_connected;
 | 
				
			||||||
  RxFifo          rx;
 | 
					  RxFifo          rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                      The A6 does not have a secure client!
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The A6 Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmA6(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsmA6(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
@@ -375,6 +405,10 @@ public:
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * WiFi functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -655,9 +689,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -742,6 +780,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
  #define TINY_GSM_RX_BUFFER 64
 | 
					  #define TINY_GSM_RX_BUFFER 64
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TINY_GSM_MUX_COUNT 5
 | 
					#define TINY_GSM_MUX_COUNT 12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmCommon.h>
 | 
					#include <TinyGsmCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,10 +39,22 @@ enum RegStatus {
 | 
				
			|||||||
  REG_UNKNOWN      = 4,
 | 
					  REG_UNKNOWN      = 4,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                    Declaration of the TinyGsmBG96 Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsmBG96
 | 
					class TinyGsmBG96
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                         The Internal BG96 Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
@@ -178,6 +190,13 @@ private:
 | 
				
			|||||||
  RxFifo        rx;
 | 
					  RxFifo        rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The BG96 Secure Client
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClientSecure : public GsmClient
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -197,9 +216,19 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The BG96 Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmBG96(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  TinyGsmBG96(Stream& stream)
 | 
					  TinyGsmBG96(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
@@ -409,6 +438,10 @@ public:
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * WiFi functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -665,9 +698,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -748,6 +785,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return 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 const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;
 | 
				
			||||||
static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120;
 | 
					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:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsm;
 | 
					  friend class TinyGsmESP8266;
 | 
				
			||||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
					  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClient() {}
 | 
					  GsmClient() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClient(TinyGsm& modem, uint8_t mux = 1) {
 | 
					  GsmClient(TinyGsmESP8266& modem, uint8_t mux = 1) {
 | 
				
			||||||
    init(&modem, mux);
 | 
					    init(&modem, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsm* modem, uint8_t mux = 1) {
 | 
					  bool init(TinyGsmESP8266* modem, uint8_t mux = 1) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = mux;
 | 
					    this->mux = mux;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
@@ -149,18 +176,25 @@ public:
 | 
				
			|||||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsmESP8266* at;
 | 
				
			||||||
  uint8_t         mux;
 | 
					  uint8_t         mux;
 | 
				
			||||||
  bool            sock_connected;
 | 
					  bool            sock_connected;
 | 
				
			||||||
  RxFifo          rx;
 | 
					  RxFifo          rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The Secure ESP8266 Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClientSecure : public GsmClient
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClientSecure() {}
 | 
					  GsmClientSecure() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClientSecure(TinyGsm& modem, uint8_t mux = 1)
 | 
					  GsmClientSecure(TinyGsmESP8266& modem, uint8_t mux = 1)
 | 
				
			||||||
    : GsmClient(modem, mux)
 | 
					    : GsmClient(modem, mux)
 | 
				
			||||||
  {}
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -174,9 +208,20 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The ESP8266 Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmESP8266(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsmESP8266(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
@@ -197,6 +242,14 @@ public:
 | 
				
			|||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
      return false;
 | 
					      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;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -260,6 +313,23 @@ public:
 | 
				
			|||||||
    return init();
 | 
					    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
 | 
					   * Generic network functions
 | 
				
			||||||
@@ -281,20 +351,8 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool isNetworkConnected()  {
 | 
					  bool isNetworkConnected()  {
 | 
				
			||||||
    sendAT(GF("+CIPSTATUS"));
 | 
					    RegStatus s = getRegistrationStatus();
 | 
				
			||||||
    int res1 = waitResponse(3000, GF("STATUS:"));
 | 
					    return (s == REG_OK_IP || s == REG_OK_TCP);
 | 
				
			||||||
    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 waitForNetwork(unsigned long timeout = 60000L) {
 | 
					  bool waitForNetwork(unsigned long timeout = 60000L) {
 | 
				
			||||||
@@ -303,7 +361,7 @@ public:
 | 
				
			|||||||
      int res1 = waitResponse(3000, GF("busy p..."), GF("STATUS:"));
 | 
					      int res1 = waitResponse(3000, GF("busy p..."), GF("STATUS:"));
 | 
				
			||||||
      if (res1 == 2) {
 | 
					      if (res1 == 2) {
 | 
				
			||||||
        int res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
 | 
					        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();
 | 
					            waitResponse();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
@@ -317,17 +375,6 @@ public:
 | 
				
			|||||||
   * WiFi functions
 | 
					   * WiFi functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  bool networkConnect(const char* ssid, const char* pwd) {
 | 
					  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("\""));
 | 
					    sendAT(GF("+CWJAP_CUR=\""), ssid, GF("\",\""), pwd, GF("\""));
 | 
				
			||||||
    if (waitResponse(30000L, GFP(GSM_OK), GF(GSM_NL "FAIL" GSM_NL)) != 1) {
 | 
					    if (waitResponse(30000L, GFP(GSM_OK), GF(GSM_NL "FAIL" GSM_NL)) != 1) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -358,6 +405,28 @@ public:
 | 
				
			|||||||
    return TinyGsmIpFromString(getLocalIP());
 | 
					    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:
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = false) {
 | 
					  bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = false) {
 | 
				
			||||||
@@ -389,21 +458,8 @@ protected:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool modemGetConnected(uint8_t mux) {
 | 
					  bool modemGetConnected(uint8_t mux) {
 | 
				
			||||||
    // TODO: re-check this
 | 
					    RegStatus s = getRegistrationStatus();
 | 
				
			||||||
    sendAT(GF("+CIPSTATUS="), mux);
 | 
					    return (s == REG_OK_IP || s == REG_OK_TCP);
 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -421,9 +477,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -510,6 +570,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,24 +39,37 @@ enum RegStatus {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsm
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                    Declaration of the TinyGsmM590 Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TinyGsmM590
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The M590 Internal Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsm;
 | 
					  friend class TinyGsmM590;
 | 
				
			||||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
					  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClient() {}
 | 
					  GsmClient() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClient(TinyGsm& modem, uint8_t mux = 1) {
 | 
					  GsmClient(TinyGsmM590& modem, uint8_t mux = 1) {
 | 
				
			||||||
    init(&modem, mux);
 | 
					    init(&modem, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsm* modem, uint8_t mux = 1) {
 | 
					  bool init(TinyGsmM590* modem, uint8_t mux = 1) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = mux;
 | 
					    this->mux = mux;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
@@ -164,15 +177,33 @@ public:
 | 
				
			|||||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsmM590*  at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
  bool          sock_connected;
 | 
					  bool          sock_connected;
 | 
				
			||||||
  RxFifo        rx;
 | 
					  RxFifo        rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The M590 Has no Secure client!
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The M590 Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmM590(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsmM590(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
@@ -383,6 +414,10 @@ public:
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * WiFi functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -413,12 +448,12 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set_dns:
 | 
					// set_dns:  // TODO
 | 
				
			||||||
    sendAT(GF("+DNSSERVER=1,8.8.8.8"));
 | 
					//     sendAT(GF("+DNSSERVER=1,8.8.8.8"));
 | 
				
			||||||
    waitResponse();
 | 
					//     waitResponse();
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
    sendAT(GF("+DNSSERVER=2,8.8.4.4"));
 | 
					//     sendAT(GF("+DNSSERVER=2,8.8.4.4"));
 | 
				
			||||||
    waitResponse();
 | 
					//     waitResponse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -600,9 +635,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -688,6 +727,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,15 +39,28 @@ enum RegStatus {
 | 
				
			|||||||
  REG_UNKNOWN      = 4,
 | 
					  REG_UNKNOWN      = 4,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum DateTime {
 | 
					enum TinyGSMDateTimeFormat {
 | 
				
			||||||
  DATE_FULL = 0,
 | 
					  DATE_FULL = 0,
 | 
				
			||||||
  DATE_TIME = 1,
 | 
					  DATE_TIME = 1,
 | 
				
			||||||
  DATE_DATE = 2
 | 
					  DATE_DATE = 2
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                    Declaration of the TinyGsmSim800 Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsmSim800
 | 
					class TinyGsmSim800
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The Sim800 Internal Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
@@ -192,6 +205,13 @@ private:
 | 
				
			|||||||
  RxFifo         rx;
 | 
					  RxFifo         rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The SIM800 Secure Client
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClientSecure : public GsmClient
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -211,9 +231,19 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The SIM800 Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmSim800(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  TinyGsmSim800(Stream& stream)
 | 
					  TinyGsmSim800(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
@@ -462,6 +492,10 @@ public:
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * WiFi functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -740,7 +774,7 @@ public:
 | 
				
			|||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Time functions
 | 
					   * Time functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  String getGSMDateTime(DateTime format) {
 | 
					  String getGSMDateTime(TinyGSMDateTimeFormat format) {
 | 
				
			||||||
    sendAT(GF("+CCLK?"));
 | 
					    sendAT(GF("+CCLK?"));
 | 
				
			||||||
    if (waitResponse(2000L, GF(GSM_NL "+CCLK: \"")) != 1) {
 | 
					    if (waitResponse(2000L, GF(GSM_NL "+CCLK: \"")) != 1) {
 | 
				
			||||||
      return "";
 | 
					      return "";
 | 
				
			||||||
@@ -898,9 +932,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -981,6 +1019,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmClientSIM800.h>
 | 
					#include <TinyGsmClientSIM800.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//              Declaration and Definitio of the TinyGsmSim808 Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsmSim808: public TinyGsmSim800
 | 
					class TinyGsmSim808: public TinyGsmSim800
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * @file       TinyGsmClientU201.h
 | 
					 * @file       TinyGsmClientUBLOX.h
 | 
				
			||||||
 * @author     Volodymyr Shymanskyy
 | 
					 * @author     Volodymyr Shymanskyy
 | 
				
			||||||
 * @license    LGPL-3.0
 | 
					 * @license    LGPL-3.0
 | 
				
			||||||
 * @copyright  Copyright (c) 2016 Volodymyr Shymanskyy
 | 
					 * @copyright  Copyright (c) 2016 Volodymyr Shymanskyy
 | 
				
			||||||
 * @date       Nov 2016
 | 
					 * @date       Nov 2016
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef TinyGsmClientU201_h
 | 
					#ifndef TinyGsmClientUBLOX_h
 | 
				
			||||||
#define TinyGsmClientU201_h
 | 
					#define TinyGsmClientUBLOX_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#define TINY_GSM_DEBUG Serial
 | 
					//#define TINY_GSM_DEBUG Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,31 +39,42 @@ enum RegStatus {
 | 
				
			|||||||
  REG_UNKNOWN      = 4,
 | 
					  REG_UNKNOWN      = 4,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                   Declaration of the TinyGsmUBLOX Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsmU201
 | 
					class TinyGsmUBLOX
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The UBLOX Internal Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsmU201;
 | 
					  friend class TinyGsmUBLOX;
 | 
				
			||||||
  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
					  typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClient() {}
 | 
					  GsmClient() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClient(TinyGsmU201& modem, uint8_t mux = 1) {
 | 
					  GsmClient(TinyGsmUBLOX& modem, uint8_t mux = 1) {
 | 
				
			||||||
    init(&modem, mux);
 | 
					    init(&modem, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsmU201* modem, uint8_t mux = 1) {
 | 
					  bool init(TinyGsmUBLOX* modem, uint8_t mux = 1) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = mux;
 | 
					    this->mux = mux;
 | 
				
			||||||
    sock_available = 0;
 | 
					    sock_available = 0;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
    got_data = false;
 | 
					    got_data = false;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -114,7 +125,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  virtual int available() {
 | 
					  virtual int available() {
 | 
				
			||||||
    TINY_GSM_YIELD();
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
    if (!rx.size()) {
 | 
					    if (!rx.size() && sock_connected) {
 | 
				
			||||||
      at->maintain();
 | 
					      at->maintain();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return rx.size() + sock_available;
 | 
					    return rx.size() + sock_available;
 | 
				
			||||||
@@ -169,7 +180,7 @@ public:
 | 
				
			|||||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsmU201*  at;
 | 
					  TinyGsmUBLOX* at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
  uint16_t      sock_available;
 | 
					  uint16_t      sock_available;
 | 
				
			||||||
  bool          sock_connected;
 | 
					  bool          sock_connected;
 | 
				
			||||||
@@ -177,12 +188,19 @@ private:
 | 
				
			|||||||
  RxFifo        rx;
 | 
					  RxFifo        rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The Secure UBLOX Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClientSecure : public GsmClient
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClientSecure() {}
 | 
					  GsmClientSecure() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClientSecure(TinyGsmU201& modem, uint8_t mux = 1)
 | 
					  GsmClientSecure(TinyGsmUBLOX& modem, uint8_t mux = 1)
 | 
				
			||||||
    : GsmClient(modem, mux)
 | 
					    : GsmClient(modem, mux)
 | 
				
			||||||
  {}
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,12 +215,18 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The UBLOX Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GSM_DEFAULT_STREAM
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
  TinyGsmU201(Stream& stream = GSM_DEFAULT_STREAM)
 | 
					  TinyGsmUBLOX(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  TinyGsmU201(Stream& stream)
 | 
					  TinyGsmUBLOX(Stream& stream)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -310,6 +334,8 @@ public:
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * SIM card functions
 | 
					   * SIM card functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -411,6 +437,10 @@ public:
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * WiFi functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -512,7 +542,20 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  String sendUSSD(const String& code) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  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;
 | 
					  bool sendSMS_UTF16(const String& number, const void* text, size_t len) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -654,9 +697,13 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool streamSkipUntil(char c) { //TODO: timeout
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    while (true) {
 | 
					    const unsigned long timeout = 1000L;
 | 
				
			||||||
      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
 | 
					    while (millis() - startMillis < timeout) {
 | 
				
			||||||
 | 
					      while (millis() - startMillis < timeout && !stream.available()) {
 | 
				
			||||||
 | 
					        TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (stream.read() == c)
 | 
					      if (stream.read() == c)
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -732,6 +779,7 @@ finish:
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      data = "";
 | 
					      data = "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    //DBG('<', index, '>');
 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,9 +11,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//#define TINY_GSM_DEBUG Serial
 | 
					//#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
 | 
					#define TINY_GSM_MUX_COUNT 1  // Multi-plexing isn't supported using command mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,38 +26,54 @@ enum SimStatus {
 | 
				
			|||||||
  SIM_LOCKED = 2,
 | 
					  SIM_LOCKED = 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum XBeeType {
 | 
					 | 
				
			||||||
  S6B    = 0,
 | 
					 | 
				
			||||||
  LTEC1  = 1,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum RegStatus {
 | 
					enum RegStatus {
 | 
				
			||||||
  REG_UNREGISTERED = 0,
 | 
					  REG_OK           = 0,
 | 
				
			||||||
 | 
					  REG_UNREGISTERED = 1,
 | 
				
			||||||
  REG_SEARCHING    = 2,
 | 
					  REG_SEARCHING    = 2,
 | 
				
			||||||
  REG_DENIED       = 3,
 | 
					  REG_DENIED       = 3,
 | 
				
			||||||
  REG_OK_HOME      = 1,
 | 
					 | 
				
			||||||
  REG_OK_ROAMING   = 5,
 | 
					 | 
				
			||||||
  REG_UNKNOWN      = 4,
 | 
					  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:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsm;
 | 
					  friend class TinyGsmXBee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClient() {}
 | 
					  GsmClient() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClient(TinyGsm& modem, uint8_t mux = 0) {
 | 
					  GsmClient(TinyGsmXBee& modem, uint8_t mux = 0) {
 | 
				
			||||||
    init(&modem, mux);
 | 
					    init(&modem, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsm* modem, uint8_t mux = 0) {
 | 
					  bool init(TinyGsmXBee* modem, uint8_t mux = 0) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = mux;
 | 
					    this->mux = mux;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
@@ -73,19 +86,25 @@ public:
 | 
				
			|||||||
public:
 | 
					public:
 | 
				
			||||||
  virtual int connect(const char *host, uint16_t port) {
 | 
					  virtual int connect(const char *host, uint16_t port) {
 | 
				
			||||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    at->commandMode();
 | 
					    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);
 | 
					      sock_connected = at->modemConnect(host, port, mux, false);
 | 
				
			||||||
      at->writeChanges();
 | 
					      at->writeChanges();
 | 
				
			||||||
      at->exitCommand();
 | 
					      at->exitCommand();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual int connect(IPAddress ip, uint16_t port) {
 | 
					  virtual int connect(IPAddress ip, uint16_t port) {
 | 
				
			||||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    at->commandMode();
 | 
					    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);
 | 
					      sock_connected = at->modemConnect(ip, port, mux, false);
 | 
				
			||||||
      at->writeChanges();
 | 
					      at->writeChanges();
 | 
				
			||||||
      at->exitCommand();
 | 
					      at->exitCommand();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,7 +129,6 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  virtual size_t write(const uint8_t *buf, size_t size) {
 | 
					  virtual size_t write(const uint8_t *buf, size_t size) {
 | 
				
			||||||
    TINY_GSM_YIELD();
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
    //at->maintain();
 | 
					 | 
				
			||||||
    return at->modemSend(buf, size, mux);
 | 
					    return at->modemSend(buf, size, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,7 +148,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  virtual int read(uint8_t *buf, size_t size) {
 | 
					  virtual int read(uint8_t *buf, size_t size) {
 | 
				
			||||||
    TINY_GSM_YIELD();
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
    return at->stream.readBytes(buf, size);
 | 
					    return at->stream.readBytes((char*)buf, size);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual int read() {
 | 
					  virtual int read() {
 | 
				
			||||||
@@ -156,47 +174,69 @@ public:
 | 
				
			|||||||
  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsmXBee*  at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
  bool          sock_connected;
 | 
					  bool          sock_connected;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The Secure XBee Client Class
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClientSecure : public GsmClient
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  GsmClientSecure() {}
 | 
					  GsmClientSecure() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GsmClientSecure(TinyGsm& modem, uint8_t mux = 1)
 | 
					  GsmClientSecure(TinyGsmXBee& modem, uint8_t mux = 1)
 | 
				
			||||||
    : GsmClient(modem, mux)
 | 
					    : GsmClient(modem, mux)
 | 
				
			||||||
  {}
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  virtual int connect(const char *host, uint16_t port) {
 | 
					  virtual int connect(const char *host, uint16_t port) {
 | 
				
			||||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    at->commandMode();
 | 
					    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);
 | 
					      sock_connected = at->modemConnect(host, port, mux, true);
 | 
				
			||||||
      at->writeChanges();
 | 
					      at->writeChanges();
 | 
				
			||||||
      at->exitCommand();
 | 
					      at->exitCommand();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual int connect(IPAddress ip, uint16_t port) {
 | 
					  virtual int connect(IPAddress ip, uint16_t port) {
 | 
				
			||||||
    at->streamClear();  // Empty anything remaining in the buffer;
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    at->commandMode();
 | 
					    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);
 | 
					      sock_connected = at->modemConnect(ip, port, mux, true);
 | 
				
			||||||
      at->writeChanges();
 | 
					      at->writeChanges();
 | 
				
			||||||
      at->exitCommand();
 | 
					      at->exitCommand();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    at->streamClear();  // Empty anything remaining in the buffer;
 | 
				
			||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//                          The XBee Modem Functions
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					//============================================================================//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					#ifdef GSM_DEFAULT_STREAM
 | 
				
			||||||
 | 
					  TinyGsmXBee(Stream& stream = GSM_DEFAULT_STREAM)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsmXBee(Stream& stream)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    : stream(stream)
 | 
					    : stream(stream)
 | 
				
			||||||
  {
 | 
					  {}
 | 
				
			||||||
    memset(sockets, 0, sizeof(sockets));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Basic functions
 | 
					   * Basic functions
 | 
				
			||||||
@@ -206,23 +246,53 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init() {
 | 
					  bool init() {
 | 
				
			||||||
    guardTime = 1100;
 | 
					    guardTime = 1100;  // Start with a default guard time of 1 second
 | 
				
			||||||
    commandMode();
 | 
					
 | 
				
			||||||
 | 
					    if (!commandMode(10)) return false;  // Try up to 10 times for the init
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("AP0"));  // Put in transparent mode
 | 
					    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
 | 
					    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();
 | 
					    waitResponse();
 | 
				
			||||||
    writeChanges();
 | 
					    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();
 | 
					    exitCommand();
 | 
				
			||||||
    if (res == "601") beeType = S6B;
 | 
					 | 
				
			||||||
    else beeType = LTEC1;
 | 
					 | 
				
			||||||
    guardTime = 125;
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool testAT(unsigned long timeout = 10000L) {
 | 
					  bool testAT(unsigned long timeout = 10000L) {
 | 
				
			||||||
@@ -243,52 +313,100 @@ public:
 | 
				
			|||||||
  void maintain() {}
 | 
					  void maintain() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool factoryDefault() {
 | 
					  bool factoryDefault() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return false;  // Return immediately
 | 
				
			||||||
    sendAT(GF("RE"));
 | 
					    sendAT(GF("RE"));
 | 
				
			||||||
    bool ret_val = waitResponse() == 1;
 | 
					    bool ret_val = waitResponse() == 1;
 | 
				
			||||||
    writeChanges();
 | 
					    ret_val &= writeChanges();
 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    return ret_val;
 | 
					    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() {
 | 
					  bool hasSSL() {
 | 
				
			||||||
    if (beeType == S6B) return false;
 | 
					    if (beeType == XBEE_S6B_WIFI) return false;
 | 
				
			||||||
    else return true;
 | 
					    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
 | 
					   * Power functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool restart() {
 | 
					  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"));
 | 
					    sendAT(GF("FR"));
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    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(1)) {
 | 
				
			||||||
 | 
					        sendAT(GF("AM0"));  // Turn off airplane mode
 | 
				
			||||||
 | 
					        writeChanges();
 | 
				
			||||||
 | 
					        exitCommand();
 | 
				
			||||||
 | 
					        delay(250);  // wait a litle before trying again
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fail:
 | 
				
			||||||
 | 
					      exitCommand();
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    delay (2000);  // Actually resets about 2 seconds later
 | 
					 | 
				
			||||||
    for (unsigned long start = millis(); millis() - start < 60000L; ) {
 | 
					 | 
				
			||||||
      if (commandMode()) {
 | 
					 | 
				
			||||||
        exitCommand();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    exitCommand();
 | 
					 | 
				
			||||||
    return false;;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void setupPinSleep() {
 | 
					  void setupPinSleep(bool maintainAssociation = false) {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return;  // Return immediately
 | 
				
			||||||
    sendAT(GF("SM"),1);
 | 
					    sendAT(GF("SM"),1);  // Pin sleep
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    if (beeType == S6B) {
 | 
					    if (beeType == XBEE_S6B_WIFI && !maintainAssociation) {
 | 
				
			||||||
        sendAT(GF("SO"),200);
 | 
					        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();
 | 
					        waitResponse();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    writeChanges();
 | 
					    writeChanges();
 | 
				
			||||||
    exitCommand();
 | 
					    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
 | 
					   * SIM card functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -298,23 +416,17 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String getSimCCID() {
 | 
					  String getSimCCID() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return "";  // Return immediately
 | 
				
			||||||
    sendAT(GF("S#"));
 | 
					    sendAT(GF("S#"));
 | 
				
			||||||
    // wait for the response
 | 
					    String res = readResponse();
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					 | 
				
			||||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
					 | 
				
			||||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
					 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String getIMEI() {
 | 
					  String getIMEI() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return "";  // Return immediately
 | 
				
			||||||
    sendAT(GF("IM"));
 | 
					    sendAT(GF("IM"));
 | 
				
			||||||
    // wait for the response
 | 
					    String res = readResponse();
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					 | 
				
			||||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
					 | 
				
			||||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
					 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -324,37 +436,82 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RegStatus getRegistrationStatus() {
 | 
					  RegStatus getRegistrationStatus() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return REG_UNKNOWN;  // Return immediately
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("AI"));
 | 
					    sendAT(GF("AI"));
 | 
				
			||||||
    // wait for the response
 | 
					    String res = readResponse();
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					    char buf[3] = {0,};  // Set up buffer for response
 | 
				
			||||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
					    res.toCharArray(buf, 3);
 | 
				
			||||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
					    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();
 | 
					    exitCommand();
 | 
				
			||||||
 | 
					    return stat;
 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String getOperator() {
 | 
					  String getOperator() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return "";  // Return immediately
 | 
				
			||||||
    sendAT(GF("MN"));
 | 
					    sendAT(GF("MN"));
 | 
				
			||||||
    // wait for the response
 | 
					    String res = readResponse();
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					 | 
				
			||||||
    while (!stream.available() && millis() - startMillis < 1000) {};
 | 
					 | 
				
			||||||
    String res = streamReadUntil('\r');  // Does not send an OK, just the result
 | 
					 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -364,25 +521,21 @@ public:
 | 
				
			|||||||
  */
 | 
					  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int getSignalQuality() {
 | 
					  int getSignalQuality() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return 0;  // Return immediately
 | 
				
			||||||
    if (beeType == S6B) sendAT(GF("LM"));  // ask for the "link margin" - the dB above sensitivity
 | 
					    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
 | 
					    else sendAT(GF("DB"));  // ask for the cell strength in dBm
 | 
				
			||||||
    // wait for the response
 | 
					    String res = readResponse();  // it works better if we read in as a string
 | 
				
			||||||
    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");
 | 
					 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    int intr = strtol(buf, 0, 16);
 | 
					    char buf[3] = {0,};  // Set up buffer for response
 | 
				
			||||||
    if (beeType == S6B) return -93 + intr;  // the maximum sensitivity is -93dBm
 | 
					    res.toCharArray(buf, 3);
 | 
				
			||||||
    else return -1*intr; // need to convert to negative number
 | 
					    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() {
 | 
					  bool isNetworkConnected() {
 | 
				
			||||||
    RegStatus s = getRegistrationStatus();
 | 
					    RegStatus s = getRegistrationStatus();
 | 
				
			||||||
    return (s == REG_OK_HOME || s == REG_OK_ROAMING);
 | 
					    return (s == REG_OK);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool waitForNetwork(unsigned long timeout = 60000L) {
 | 
					  bool waitForNetwork(unsigned long timeout = 60000L) {
 | 
				
			||||||
@@ -390,7 +543,7 @@ public:
 | 
				
			|||||||
      if (isNetworkConnected()) {
 | 
					      if (isNetworkConnected()) {
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      delay(250);
 | 
					      // delay(250);  // Enough delay going in and out of command mode
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -400,20 +553,16 @@ public:
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  bool networkConnect(const char* ssid, const char* pwd) {
 | 
					  bool networkConnect(const char* ssid, const char* pwd) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return false;  // return immediately
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("EE"), 2);  // Set security to WPA2
 | 
					    sendAT(GF("EE"), 2);  // Set security to WPA2
 | 
				
			||||||
    waitResponse();
 | 
					    if (waitResponse() != 1) goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("ID"), ssid);
 | 
					    sendAT(GF("ID"), ssid);
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) goto fail;
 | 
				
			||||||
      goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("PK"), pwd);
 | 
					    sendAT(GF("PK"), pwd);
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) goto fail;
 | 
				
			||||||
      goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    writeChanges();
 | 
					    writeChanges();
 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
@@ -426,17 +575,22 @@ fail:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool networkDisconnect() {
 | 
					  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() {
 | 
					  String getLocalIP() {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return "";  // Return immediately
 | 
				
			||||||
    sendAT(GF("MY"));
 | 
					    sendAT(GF("MY"));
 | 
				
			||||||
    String IPaddr; IPaddr.reserve(16);
 | 
					    String IPaddr; IPaddr.reserve(16);
 | 
				
			||||||
    // wait for the response
 | 
					    // wait for the response - this response can be very slow
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					    IPaddr = readResponse(30000);
 | 
				
			||||||
    while (stream.available() < 8 && millis() - startMillis < 30000) {};
 | 
					    exitCommand();
 | 
				
			||||||
    IPaddr = streamReadUntil('\r');  // read result
 | 
					    IPaddr.trim();
 | 
				
			||||||
    return IPaddr;
 | 
					    return IPaddr;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -448,7 +602,7 @@ fail:
 | 
				
			|||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  bool gprsConnect(const char* apn, const char* user = NULL, const char* pwd = NULL) {
 | 
					  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
 | 
					    sendAT(GF("AN"), apn);  // Set the APN
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    writeChanges();
 | 
					    writeChanges();
 | 
				
			||||||
@@ -456,8 +610,20 @@ fail:
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool gprsDisconnect() {  // TODO
 | 
					  bool gprsDisconnect() {
 | 
				
			||||||
    return false;
 | 
					    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();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
@@ -467,35 +633,67 @@ fail:
 | 
				
			|||||||
  String sendUSSD(const String& code) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
					  String sendUSSD(const String& code) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool sendSMS(const String& number, const String& text) {
 | 
					  bool sendSMS(const String& number, const String& text) {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return false;  // Return immediately
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("IP"), 2);  // Put in text messaging mode
 | 
					    sendAT(GF("IP"), 2);  // Put in text messaging mode
 | 
				
			||||||
    waitResponse();
 | 
					    if (waitResponse() !=1) goto fail;
 | 
				
			||||||
    sendAT(GF("PH"), number);  // Set the phone number
 | 
					    sendAT(GF("PH"), number);  // Set the phone number
 | 
				
			||||||
    waitResponse();
 | 
					    if (waitResponse() !=1) goto fail;
 | 
				
			||||||
    sendAT(GF("TDD"));  // Set the text delimiter to the standard 0x0D (carriabe return)
 | 
					    sendAT(GF("TDD"));  // Set the text delimiter to the standard 0x0D (carriage return)
 | 
				
			||||||
    waitResponse();
 | 
					    if (waitResponse() !=1) goto fail;
 | 
				
			||||||
    writeChanges();
 | 
					    if (!writeChanges()) goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
    stream.print(text);
 | 
					    streamWrite(text);
 | 
				
			||||||
    stream.write((char)0x0D);  // close off with the carriage return
 | 
					    stream.write((char)0x0D);  // close off with the carriage return
 | 
				
			||||||
    return true;
 | 
					    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);
 | 
					    String strIP; strIP.reserve(16);
 | 
				
			||||||
    // wait for the response
 | 
					 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
    while (stream.available() < 8 && millis() - startMillis < 30000) {};
 | 
					    bool gotIP = false;
 | 
				
			||||||
    strIP = streamReadUntil('\r');  // read result
 | 
					    // 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);
 | 
					      IPAddress ip = TinyGsmIpFromString(strIP);
 | 
				
			||||||
      return modemConnect(ip, port, mux, ssl);
 | 
					      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);
 | 
					    String host; host.reserve(16);
 | 
				
			||||||
    host += ip[0];
 | 
					    host += ip[0];
 | 
				
			||||||
    host += ".";
 | 
					    host += ".";
 | 
				
			||||||
@@ -505,17 +703,17 @@ private:
 | 
				
			|||||||
    host += ".";
 | 
					    host += ".";
 | 
				
			||||||
    host += ip[3];
 | 
					    host += ip[3];
 | 
				
			||||||
    if (ssl) {
 | 
					    if (ssl) {
 | 
				
			||||||
      sendAT(GF("IP"), 4);  // Put in TCP mode
 | 
					      sendAT(GF("IP"), 4);  // Put in SSL over TCP communication mode
 | 
				
			||||||
      waitResponse();
 | 
					      success &= (1 == waitResponse());
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      sendAT(GF("IP"), 1);  // Put in TCP mode
 | 
					      sendAT(GF("IP"), 1);  // Put in TCP mode
 | 
				
			||||||
      waitResponse();
 | 
					      success &= (1 == waitResponse());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sendAT(GF("DL"), host);  // Set the "Destination Address Low"
 | 
					    sendAT(GF("DL"), host);  // Set the "Destination Address Low"
 | 
				
			||||||
    waitResponse();
 | 
					    success &= (1 == waitResponse());
 | 
				
			||||||
    sendAT(GF("DE"), String(port, HEX));  // Set the destination port
 | 
					    sendAT(GF("DE"), String(port, HEX));  // Set the destination port
 | 
				
			||||||
    int rsp = waitResponse();
 | 
					    success &= (1 == waitResponse());
 | 
				
			||||||
    return rsp;
 | 
					    return success;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int modemSend(const void* buff, size_t len, uint8_t mux = 0) {
 | 
					  int modemSend(const void* buff, size_t len, uint8_t mux = 0) {
 | 
				
			||||||
@@ -525,7 +723,7 @@ private:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool modemGetConnected(uint8_t mux = 0) {
 | 
					  bool modemGetConnected(uint8_t mux = 0) {
 | 
				
			||||||
    commandMode();
 | 
					    if (!commandMode()) return false;
 | 
				
			||||||
    sendAT(GF("AI"));
 | 
					    sendAT(GF("AI"));
 | 
				
			||||||
    int res = waitResponse(GF("0"));
 | 
					    int res = waitResponse(GF("0"));
 | 
				
			||||||
    exitCommand();
 | 
					    exitCommand();
 | 
				
			||||||
@@ -547,32 +745,33 @@ public:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    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) {
 | 
					  void streamClear(void) {
 | 
				
			||||||
    while (stream.available()) { streamRead(); }
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					    while (stream.available()) { stream.read(); }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool commandMode(void) {
 | 
					  bool commandMode(int retries = 2) {
 | 
				
			||||||
    delay(guardTime);  // cannot send anything for 1 second before entering command mode
 | 
					    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
 | 
					      streamWrite(GF("+++"));  // enter command mode
 | 
				
			||||||
    // DBG("\r\n+++\r\n");
 | 
					      DBG("+++");
 | 
				
			||||||
    return 1 == waitResponse(guardTime*2);
 | 
					      success = (1 == waitResponse(guardTime*2));
 | 
				
			||||||
 | 
					      triesMade ++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return success;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void writeChanges(void) {
 | 
					  bool writeChanges(void) {
 | 
				
			||||||
    sendAT(GF("WR"));  // Write changes to flash
 | 
					    sendAT(GF("WR"));  // Write changes to flash
 | 
				
			||||||
    waitResponse();
 | 
					    if (1 != waitResponse()) return false;
 | 
				
			||||||
    sendAT(GF("AC"));  // Apply changes
 | 
					    sendAT(GF("AC"));  // Apply changes
 | 
				
			||||||
    waitResponse();
 | 
					    if (1 != waitResponse()) return false;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void exitCommand(void) {
 | 
					  void exitCommand(void) {
 | 
				
			||||||
@@ -580,6 +779,16 @@ public:
 | 
				
			|||||||
    waitResponse();
 | 
					    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>
 | 
					  template<typename... Args>
 | 
				
			||||||
  void sendAT(Args... cmd) {
 | 
					  void sendAT(Args... cmd) {
 | 
				
			||||||
    streamWrite("AT", cmd..., GSM_NL);
 | 
					    streamWrite("AT", cmd..., GSM_NL);
 | 
				
			||||||
@@ -599,13 +808,13 @@ public:
 | 
				
			|||||||
    String r4s(r4); r4s.trim();
 | 
					    String r4s(r4); r4s.trim();
 | 
				
			||||||
    String r5s(r5); r5s.trim();
 | 
					    String r5s(r5); r5s.trim();
 | 
				
			||||||
    DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
 | 
					    DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
 | 
				
			||||||
    data.reserve(64);
 | 
					    data.reserve(16);  // Should never be getting much here for the XBee
 | 
				
			||||||
    int index = 0;
 | 
					    int index = 0;
 | 
				
			||||||
    unsigned long startMillis = millis();
 | 
					    unsigned long startMillis = millis();
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      TINY_GSM_YIELD();
 | 
					      TINY_GSM_YIELD();
 | 
				
			||||||
      while (stream.available() > 0) {
 | 
					      while (stream.available() > 0) {
 | 
				
			||||||
        int a = streamRead();
 | 
					        int a = stream.read();
 | 
				
			||||||
        if (a <= 0) continue; // Skip 0x00 bytes, just in case
 | 
					        if (a <= 0) continue; // Skip 0x00 bytes, just in case
 | 
				
			||||||
        data += (char)a;
 | 
					        data += (char)a;
 | 
				
			||||||
        if (r1 && data.endsWith(r1)) {
 | 
					        if (r1 && data.endsWith(r1)) {
 | 
				
			||||||
@@ -630,7 +839,7 @@ finish:
 | 
				
			|||||||
    if (!index) {
 | 
					    if (!index) {
 | 
				
			||||||
      data.trim();
 | 
					      data.trim();
 | 
				
			||||||
      data.replace(GSM_NL GSM_NL, GSM_NL);
 | 
					      data.replace(GSM_NL GSM_NL, GSM_NL);
 | 
				
			||||||
      data.replace(GSM_NL, "\r\n" "    ");
 | 
					      data.replace(GSM_NL, "\r\n    ");
 | 
				
			||||||
      if (data.length()) {
 | 
					      if (data.length()) {
 | 
				
			||||||
        DBG("### Unhandled:", data, "\r\n");
 | 
					        DBG("### Unhandled:", data, "\r\n");
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user