Re-aligned with vshymanskyy-master
This commit is contained in:
		
							
								
								
									
										61
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								README.md
									
									
									
									
									
								
							@@ -14,9 +14,12 @@ If you like **TinyGSM** - give it a star, or fork it and contribute!
 | 
				
			|||||||
[](https://github.com/vshymanskyy/TinyGSM/stargazers) 
 | 
					[](https://github.com/vshymanskyy/TinyGSM/stargazers) 
 | 
				
			||||||
[](https://github.com/vshymanskyy/TinyGSM/network)
 | 
					[](https://github.com/vshymanskyy/TinyGSM/network)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also join our chat:
 | 
				
			||||||
 | 
					[](https://gitter.im/tinygsm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Arduino Client interface support
 | 
					### Arduino Client interface support
 | 
				
			||||||
This library is easy to integrate with lots of sketches, which use Ethernet or WiFi.  
 | 
					This library is easy to integrate with lots of sketches, which use Ethernet or WiFi.  
 | 
				
			||||||
Examples for **PubSubClient ([MQTT](http://mqtt.org/))**, **[Blynk](http://blynk.cc)**, **Web Client** and **File Download** are provided.
 | 
					**PubSubClient ([MQTT](http://mqtt.org/))**, **[Blynk](http://blynk.cc)**, **HTTP Client** and **File Download** examples are provided.
 | 
				
			||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,7 +33,38 @@ Arduino GSM library uses 15868 bytes (49%) of Flash and 1113 bytes (54%) of RAM
 | 
				
			|||||||
TinyGSM also pulls data gently from the modem (whenever possible), so it can operate on very little RAM.  
 | 
					TinyGSM also pulls data gently from the modem (whenever possible), so it can operate on very little RAM.  
 | 
				
			||||||
**Now, you have more space for your experiments.**
 | 
					**Now, you have more space for your experiments.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Supported modem models
 | 
					## Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Feature \ Modem              | SIM800 | SIM8x8 | A6/A7/A20 | M590 | ESP8266
 | 
				
			||||||
 | 
					---                          | ---    | ---    | ---       | ---  | ---
 | 
				
			||||||
 | 
					**Data connections**
 | 
				
			||||||
 | 
					TCP (HTTP, MQTT, Blynk, ...) | ✔      | ✔      | ✔         | ✔    | ✔
 | 
				
			||||||
 | 
					UDP                          |        |        |           |      | 
 | 
				
			||||||
 | 
					SSL/TLS (HTTPS)              | ✔¹     | ✔¹     | 🅧        | 🅧   | ◌
 | 
				
			||||||
 | 
					**USSD**
 | 
				
			||||||
 | 
					Sending USSD requests        | ✔      | ✔      | ✔         | ✔    | 
 | 
				
			||||||
 | 
					Decoding 7,8,16-bit response | ✔      | ✔      | ✔         | ✔    | 
 | 
				
			||||||
 | 
					**SMS**
 | 
				
			||||||
 | 
					Sending                      | ✔      | ✔      | ✔         | ✔    | 
 | 
				
			||||||
 | 
					Sending Unicode              | ✔      | ✔      | ◌         | 🅧   | 
 | 
				
			||||||
 | 
					Reading                      |        |        |           |      | 
 | 
				
			||||||
 | 
					Incoming message event       |        |        |           | ?    | 
 | 
				
			||||||
 | 
					**Calls**
 | 
				
			||||||
 | 
					Dial, hangup                 | ✔      | ✔      | ✔         | 🅧   | 
 | 
				
			||||||
 | 
					Receiving calls              | ✔      | ✔      | ✔         | 🅧   | 
 | 
				
			||||||
 | 
					Incoming event (RING)        | ◌      | ◌      | ◌         | 🅧   | 
 | 
				
			||||||
 | 
					DTMF sending                 | ◌      | ◌      | ◌         | 🅧   | 
 | 
				
			||||||
 | 
					DTMF decoding                | ◌      | ◌      | 🅧        | 🅧   | 
 | 
				
			||||||
 | 
					**Location**
 | 
				
			||||||
 | 
					GSM location service         | ✔      | ✔      | 🅧        | 🅧   | 
 | 
				
			||||||
 | 
					GPS/GNSS                     | 🅧     | ✔²     | ◌¹        | 🅧   | 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					✔ - implemented  ◌ - planned  🅧 - not available for this modem  
 | 
				
			||||||
 | 
					¹ - only some device models or firmware revisions have this feature  
 | 
				
			||||||
 | 
					² - current implementation only supports SIM808 V2 GPS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Supported modems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [x] SIMCom SIM800 series (SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868)
 | 
					- [x] SIMCom SIM800 series (SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868)
 | 
				
			||||||
- [x] SIMCom SIM900 series (SIM900A, SIM900D, SIM908, SIM968)
 | 
					- [x] SIMCom SIM900 series (SIM900A, SIM900D, SIM908, SIM968)
 | 
				
			||||||
- [x] AI-Thinker A6, A6C, A7
 | 
					- [x] AI-Thinker A6, A6C, A7
 | 
				
			||||||
@@ -53,6 +87,19 @@ More modems may be supported later:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Watch this repo for new updates! And of course, contributions are welcome ;)
 | 
					Watch this repo for new updates! And of course, contributions are welcome ;)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Donation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[](https://salt.bountysource.com/checkout/amount?team=tinygsm-dev)
 | 
				
			||||||
 | 
					[](http://tny.im/aen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have found TinyGSM to be useful in your work, research or company, please consider making a donation to the project commensurate with your resources. Any amount helps!  
 | 
				
			||||||
 | 
					**All donations will be used strictly to fund the development of TinyGSM:**
 | 
				
			||||||
 | 
					- Covering cellular network expences
 | 
				
			||||||
 | 
					- Buying new hardware and modems for integration
 | 
				
			||||||
 | 
					- Bounty Budget (to reward other developers for their contributions)
 | 
				
			||||||
 | 
					- Implementing new features
 | 
				
			||||||
 | 
					- Quality Assurance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Getting Started
 | 
					## Getting Started
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  1. Using your phone:
 | 
					  1. Using your phone:
 | 
				
			||||||
@@ -65,6 +112,16 @@ Watch this repo for new updates! And of course, contributions are welcome ;)
 | 
				
			|||||||
     Send an ```AT``` command using [this sketch](tools/AT_Debug/AT_Debug.ino)
 | 
					     Send an ```AT``` command using [this sketch](tools/AT_Debug/AT_Debug.ino)
 | 
				
			||||||
  5. Check if GSM antenna is attached
 | 
					  5. Check if GSM antenna is attached
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How does it work?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many GSM modems, WiFi and radio modules can be controlled by sending AT commands over Serial.  
 | 
				
			||||||
 | 
					TinyGSM knows which commands to send, and how to handle AT responses, and wraps that into standard Arduino Client interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## API Reference
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For GPRS data streams, this library provides the standard [Arduino Client](https://www.arduino.cc/en/Reference/ClientConstructor) interface.  
 | 
				
			||||||
 | 
					For additional functions, please refer to [this example sketch](examples/AllFunctions/AllFunctions.ino)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Troubleshooting
 | 
					## Troubleshooting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### SoftwareSerial problems
 | 
					### SoftwareSerial problems
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,14 +11,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined(TINY_GSM_MODEM_SIM800) || defined(TINY_GSM_MODEM_SIM900)
 | 
					#if defined(TINY_GSM_MODEM_SIM800) || defined(TINY_GSM_MODEM_SIM900)
 | 
				
			||||||
  #include <TinyGsmClientSIM800.h>
 | 
					  #include <TinyGsmClientSIM800.h>
 | 
				
			||||||
 | 
					  typedef TinyGsmSim800 TinyGsm;
 | 
				
			||||||
 | 
					  typedef TinyGsmSim800::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					  typedef TinyGsmSim800::GsmClientSecure TinyGsmClientSecure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(TINY_GSM_MODEM_SIM808) || defined(TINY_GSM_MODEM_SIM868)
 | 
				
			||||||
 | 
					  #include <TinyGsmClientSIM808.h>
 | 
				
			||||||
 | 
					  typedef TinyGsmSim808 TinyGsm;
 | 
				
			||||||
 | 
					  typedef TinyGsmSim808::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					  typedef TinyGsmSim808::GsmClientSecure TinyGsmClientSecure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
 | 
					#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
 | 
				
			||||||
  #include <TinyGsmClientA6.h>
 | 
					  #include <TinyGsmClientA6.h>
 | 
				
			||||||
 | 
					  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_M590)
 | 
					#elif defined(TINY_GSM_MODEM_M590)
 | 
				
			||||||
  #include <TinyGsmClientM590.h>
 | 
					  #include <TinyGsmClientM590.h>
 | 
				
			||||||
 | 
					  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_ESP8266)
 | 
					#elif defined(TINY_GSM_MODEM_ESP8266)
 | 
				
			||||||
  #include <TinyGsmClientESP8266.h>
 | 
					  #include <TinyGsmClientESP8266.h>
 | 
				
			||||||
 | 
					  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#elif defined(TINY_GSM_MODEM_XBEE)
 | 
					#elif defined(TINY_GSM_MODEM_XBEE)
 | 
				
			||||||
  #include <TinyGsmClientXBee.h>
 | 
					  #include <TinyGsmClientXBee.h>
 | 
				
			||||||
 | 
					  typedef TinyGsm::GsmClient TinyGsmClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  #error "Please define GSM modem model"
 | 
					  #error "Please define GSM modem model"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,8 @@
 | 
				
			|||||||
  #define TINY_GSM_RX_BUFFER 256
 | 
					  #define TINY_GSM_RX_BUFFER 256
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TINY_GSM_MUX_COUNT 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmCommon.h>
 | 
					#include <TinyGsmCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_NL "\r\n"
 | 
					#define GSM_NL "\r\n"
 | 
				
			||||||
@@ -40,11 +42,6 @@ enum RegStatus {
 | 
				
			|||||||
class TinyGsm
 | 
					class TinyGsm
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					 | 
				
			||||||
    : stream(stream)
 | 
					 | 
				
			||||||
  {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
@@ -111,7 +108,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();
 | 
					    return rx.size();
 | 
				
			||||||
@@ -155,6 +152,13 @@ public:
 | 
				
			|||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  virtual operator bool() { return connected(); }
 | 
					  virtual operator bool() { return connected(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Extended API
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsm*      at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
@@ -164,6 +168,12 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TinyGsm(Stream& stream)
 | 
				
			||||||
 | 
					    : stream(stream)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Basic functions
 | 
					   * Basic functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -211,6 +221,18 @@ public:
 | 
				
			|||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getModemInfo() {
 | 
				
			||||||
 | 
					    sendAT(GF("I"));
 | 
				
			||||||
 | 
					    String res;
 | 
				
			||||||
 | 
					    if (waitResponse(1000L, res) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.replace(GSM_NL "OK" GSM_NL, "");
 | 
				
			||||||
 | 
					    res.replace(GSM_NL, " ");
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Power functions
 | 
					   * Power functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -224,6 +246,11 @@ public:
 | 
				
			|||||||
    return init();
 | 
					    return init();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool poweroff() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CPOF"));
 | 
				
			||||||
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * SIM card functions
 | 
					   * SIM card functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -235,7 +262,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  String getSimCCID() {
 | 
					  String getSimCCID() {
 | 
				
			||||||
    sendAT(GF("+CCID"));
 | 
					    sendAT(GF("+CCID"));
 | 
				
			||||||
    if (waitResponse(GF(GSM_NL "+ICCID:")) != 1) {
 | 
					    if (waitResponse(GF(GSM_NL "+SCID: SIM Card ID:")) != 1) {
 | 
				
			||||||
      return "";
 | 
					      return "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    String res = streamReadUntil('\n');
 | 
					    String res = streamReadUntil('\n');
 | 
				
			||||||
@@ -303,7 +330,7 @@ public:
 | 
				
			|||||||
    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
					    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
				
			||||||
      return 99;
 | 
					      return 99;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    int res = streamReadUntil(',').toInt();
 | 
					    int res = stream.readStringUntil(',').toInt();
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -336,9 +363,17 @@ public:
 | 
				
			|||||||
  bool gprsConnect(const char* apn, const char* user, const char* pwd) {
 | 
					  bool gprsConnect(const char* apn, const char* user, const char* pwd) {
 | 
				
			||||||
    gprsDisconnect();
 | 
					    gprsDisconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sendAT(GF("+CGATT=1"));
 | 
				
			||||||
 | 
					    if (waitResponse(60000L) != 1)
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: wait AT+CGATT?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
 | 
					    sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!user) user = "";
 | 
				
			||||||
 | 
					    if (!pwd)  pwd = "";
 | 
				
			||||||
    sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\""));
 | 
					    sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\""));
 | 
				
			||||||
    if (waitResponse(60000L) != 1) {
 | 
					    if (waitResponse(60000L) != 1) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
@@ -347,24 +382,11 @@ public:
 | 
				
			|||||||
    sendAT(GF("+CGACT=1,1"));
 | 
					    sendAT(GF("+CGACT=1,1"));
 | 
				
			||||||
    waitResponse(60000L);
 | 
					    waitResponse(60000L);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("+CGATT=1"));
 | 
					 | 
				
			||||||
    if (waitResponse(60000L) != 1)
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO: wait AT+CGATT?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sendAT(GF("+CIPMUX=1"));
 | 
					    sendAT(GF("+CIPMUX=1"));
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*sendAT(GF("+CIFSR"));
 | 
					 | 
				
			||||||
    String data;
 | 
					 | 
				
			||||||
    if (waitResponse(10000L, data) != 1) {
 | 
					 | 
				
			||||||
      data.replace(GSM_NL, "");
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -373,22 +395,58 @@ public:
 | 
				
			|||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getLocalIP() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CIFSR"));
 | 
				
			||||||
 | 
					    String res;
 | 
				
			||||||
 | 
					    if (waitResponse(10000L, res) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  IPAddress localIP() {
 | 
				
			||||||
 | 
					    IPAddress res;
 | 
				
			||||||
 | 
					    res.fromString(getLocalIP());
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Phone Call functions
 | 
					   * Phone Call functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callAnswer() {
 | 
					  bool callAnswer() {
 | 
				
			||||||
    sendAT(GF("A"));
 | 
					    sendAT(GF("A"));
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Returns true on pick-up, false on error/busy
 | 
				
			||||||
  bool callNumber(const String& number) {
 | 
					  bool callNumber(const String& number) {
 | 
				
			||||||
    sendAT(GF("D"), number);
 | 
					    sendAT(GF("D\""), number, "\";");
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (waitResponse(60000L, GF(GSM_NL "+CIEV: \"CALL\",1"), GF(GSM_NL "+CIEV: \"CALL\",0")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rsp = waitResponse(60000L, GF(GSM_NL "+CIEV: \"SOUNDER\",0"), GF(GSM_NL "+CIEV: \"CALL\",0"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rsp2 = waitResponse(300L, GF(GSM_NL "BUSY" GSM_NL), GF(GSM_NL "NO ANSWER" GSM_NL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rsp == 1 && rsp2 == 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callHangup(const String& number) {
 | 
					  //bool callRedial() {
 | 
				
			||||||
    sendAT(GF("H"), number);
 | 
					  //  sendAT(GF("DLST"));
 | 
				
			||||||
 | 
					  //  return waitResponse() == 1;
 | 
				
			||||||
 | 
					  //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool callHangup() {
 | 
				
			||||||
 | 
					    sendAT(GF("H"));
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -396,6 +454,32 @@ public:
 | 
				
			|||||||
   * Messaging functions
 | 
					   * Messaging functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String sendUSSD(const String& code) {
 | 
				
			||||||
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("+CSCS=\"HEX\""));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("+CUSD=1,\""), code, GF("\",15"));
 | 
				
			||||||
 | 
					    if (waitResponse(10000L) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CUSD:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    String hex = stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    int dcs = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dcs == 15) {
 | 
				
			||||||
 | 
					      return decodeHex7bit(hex);
 | 
				
			||||||
 | 
					    } else if (dcs == 72) {
 | 
				
			||||||
 | 
					      return decodeHex16bit(hex);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return hex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool sendSMS(const String& number, const String& text) {
 | 
					  bool sendSMS(const String& number, const String& text) {
 | 
				
			||||||
    sendAT(GF("+CMGF=1"));
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
@@ -405,24 +489,41 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.print(text);
 | 
					    stream.print(text);
 | 
				
			||||||
    stream.write((char)0x1A);
 | 
					    stream.write((char)0x1A);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Location functions
 | 
					   * Location functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Battery functions
 | 
					   * Battery functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int getBattPercent() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CBC?"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    int res = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  int modemConnect(const char* host, uint16_t port, uint8_t* mux) {
 | 
					
 | 
				
			||||||
 | 
					  bool modemConnect(const char* host, uint16_t port, uint8_t* mux) {
 | 
				
			||||||
    sendAT(GF("+CIPSTART="),  GF("\"TCP"), GF("\",\""), host, GF("\","), port);
 | 
					    sendAT(GF("+CIPSTART="),  GF("\"TCP"), GF("\",\""), host, GF("\","), port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (waitResponse(75000L, GF(GSM_NL "+CIPNUM:")) != 1) {
 | 
					    if (waitResponse(75000L, GF(GSM_NL "+CIPNUM:")) != 1) {
 | 
				
			||||||
      return -1;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    int newMux = streamReadUntil('\n').toInt();
 | 
					    int newMux = streamReadUntil('\n').toInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -431,7 +532,7 @@ private:
 | 
				
			|||||||
                           GF("CONNECT FAIL" GSM_NL),
 | 
					                           GF("CONNECT FAIL" GSM_NL),
 | 
				
			||||||
                           GF("ALREADY CONNECT" GSM_NL));
 | 
					                           GF("ALREADY CONNECT" GSM_NL));
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
      return -1;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *mux = newMux;
 | 
					    *mux = newMux;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -440,7 +541,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  int modemSend(const void* buff, size_t len, uint8_t mux) {
 | 
					  int modemSend(const void* buff, size_t len, uint8_t mux) {
 | 
				
			||||||
    sendAT(GF("+CIPSEND="), mux, ',', len);
 | 
					    sendAT(GF("+CIPSEND="), mux, ',', len);
 | 
				
			||||||
    if (waitResponse(10000L, GF(GSM_NL ">")) != 1) {
 | 
					    if (waitResponse(2000L, GF(GSM_NL ">")) != 1) {
 | 
				
			||||||
      return -1;
 | 
					      return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.write((uint8_t*)buff, len);
 | 
					    stream.write((uint8_t*)buff, len);
 | 
				
			||||||
@@ -451,14 +552,61 @@ private:
 | 
				
			|||||||
    return len;
 | 
					    return len;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool modemGetConnected(uint8_t mux) { //TODO mux?
 | 
					  bool modemGetConnected(uint8_t mux) {
 | 
				
			||||||
    sendAT(GF("+CIPSTATUS"));
 | 
					    sendAT(GF("+CIPSTATUS")); //TODO mux?
 | 
				
			||||||
    int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\""));
 | 
					    int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\""));
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    return 1 == res;
 | 
					    return 1 == res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Private Utilities */
 | 
					  static String decodeHex7bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    byte reminder = 0;
 | 
				
			||||||
 | 
					    int bitstate = 7;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=2) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      byte b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      byte bb = b << (7 - bitstate);
 | 
				
			||||||
 | 
					      char c = (bb + reminder) & 0x7F;
 | 
				
			||||||
 | 
					      result += c;
 | 
				
			||||||
 | 
					      reminder = b >> bitstate;
 | 
				
			||||||
 | 
					      bitstate--;
 | 
				
			||||||
 | 
					      if (bitstate == 0) {
 | 
				
			||||||
 | 
					        char c = reminder;
 | 
				
			||||||
 | 
					        result += c;
 | 
				
			||||||
 | 
					        reminder = 0;
 | 
				
			||||||
 | 
					        bitstate = 7;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static String decodeHex16bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=4) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      char b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      if (b) { // If high byte is non-zero, we can't handle it ;(
 | 
				
			||||||
 | 
					        b = '?';
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        buf[0] = instr[i+2];
 | 
				
			||||||
 | 
					        buf[1] = instr[i+3];
 | 
				
			||||||
 | 
					        b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      result += b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Utilities */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename T>
 | 
					  template<typename T>
 | 
				
			||||||
  void streamWrite(T last) {
 | 
					  void streamWrite(T last) {
 | 
				
			||||||
    stream.print(last);
 | 
					    stream.print(last);
 | 
				
			||||||
@@ -470,17 +618,6 @@ private:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int streamRead() { return stream.read(); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  String streamReadUntil(char c) {
 | 
					 | 
				
			||||||
    String return_string = stream.readStringUntil(c);
 | 
					 | 
				
			||||||
    return_string.trim();
 | 
					 | 
				
			||||||
    if (String(c) == GSM_NL || String(c) == "\n"){
 | 
					 | 
				
			||||||
      DBG(return_string, c, "    ");
 | 
					 | 
				
			||||||
    } else DBG(return_string, c);
 | 
					 | 
				
			||||||
    return return_string;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool streamSkipUntil(char c) {
 | 
					  bool streamSkipUntil(char c) {
 | 
				
			||||||
    String skipped = stream.readStringUntil(c);
 | 
					    String skipped = stream.readStringUntil(c);
 | 
				
			||||||
    skipped.trim();
 | 
					    skipped.trim();
 | 
				
			||||||
@@ -520,7 +657,7 @@ private:
 | 
				
			|||||||
    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)) {
 | 
				
			||||||
@@ -539,24 +676,25 @@ private:
 | 
				
			|||||||
          index = 5;
 | 
					          index = 5;
 | 
				
			||||||
          goto finish;
 | 
					          goto finish;
 | 
				
			||||||
        } else if (data.endsWith(GF("+CIPRCV:"))) {
 | 
					        } else if (data.endsWith(GF("+CIPRCV:"))) {
 | 
				
			||||||
          mux = stream.readStringUntil(',').toInt();
 | 
					          int mux = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += mux;
 | 
					          int len = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += (',');
 | 
					          if (len > sockets[mux]->rx.free()) {
 | 
				
			||||||
          len = stream.readStringUntil(',').toInt();
 | 
					            DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          data += len;
 | 
					          } else {
 | 
				
			||||||
          data += (',');
 | 
					            DBG("### Got: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          gotData = true;
 | 
					          }
 | 
				
			||||||
          index = 6;
 | 
					          while (len--) {
 | 
				
			||||||
          goto finish;
 | 
					            while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
 | 
					            sockets[mux]->rx.put(stream.read());
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          data = "";
 | 
				
			||||||
        } else if (data.endsWith(GF("+TCPCLOSED:"))) {
 | 
					        } else if (data.endsWith(GF("+TCPCLOSED:"))) {
 | 
				
			||||||
          mux = stream.readStringUntil(',').toInt();
 | 
					          int mux = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
          data += mux;
 | 
					          if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
 | 
				
			||||||
          data += (',');
 | 
					            sockets[mux]->sock_connected = false;
 | 
				
			||||||
          String concl = stream.readStringUntil('\n');
 | 
					          }
 | 
				
			||||||
          data += concl;
 | 
					          data = "";
 | 
				
			||||||
         sockets[mux]->sock_connected = false;
 | 
					          DBG("### Closed: ", mux);
 | 
				
			||||||
          index = 7;
 | 
					 | 
				
			||||||
          goto finish;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } while (millis() - startMillis < timeout);
 | 
					    } while (millis() - startMillis < timeout);
 | 
				
			||||||
@@ -611,9 +749,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  Stream&       stream;
 | 
					  Stream&       stream;
 | 
				
			||||||
  GsmClient*    sockets[8];
 | 
					  GsmClient*    sockets[TINY_GSM_MUX_COUNT];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * @file       TinyWiFiClientESP8266.h
 | 
					 * @file       TinyGsmClientESP8266.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 TinyWiFiClientESP8266_h
 | 
					#ifndef TinyGsmClientESP8266_h
 | 
				
			||||||
#define TinyWiFiClientESP8266_h
 | 
					#define TinyGsmClientESP8266_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#define TINY_GSM_DEBUG Serial
 | 
					//#define TINY_GSM_DEBUG Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,21 +15,18 @@
 | 
				
			|||||||
  #define TINY_GSM_RX_BUFFER 256
 | 
					  #define TINY_GSM_RX_BUFFER 256
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TINY_GSM_MUX_COUNT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmCommon.h>
 | 
					#include <TinyGsmCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_NL "\r\n"
 | 
					#define GSM_NL "\r\n"
 | 
				
			||||||
static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL;
 | 
					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 int TCP_KEEP_ALIVE = 120;
 | 
					static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsm
 | 
					class TinyGsm
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					 | 
				
			||||||
    : stream(stream)
 | 
					 | 
				
			||||||
  {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
@@ -94,7 +91,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();
 | 
					    return rx.size();
 | 
				
			||||||
@@ -138,6 +135,13 @@ public:
 | 
				
			|||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  virtual operator bool() { return connected(); }
 | 
					  virtual operator bool() { return connected(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Extended API
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsm*      at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
@@ -147,6 +151,12 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TinyGsm(Stream& stream)
 | 
				
			||||||
 | 
					    : stream(stream)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Basic functions
 | 
					   * Basic functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -273,20 +283,21 @@ public:
 | 
				
			|||||||
    return waitResponse(10000L) == 1;
 | 
					    return waitResponse(10000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getLocalIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  IPAddress localIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * GPRS functions
 | 
					   * GPRS functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  bool gprsConnect(const char* apn, const char* user, const char* pwd) {
 | 
					  bool gprsConnect(const char* apn, const char* user, const char* pwd) TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool gprsDisconnect() {
 | 
					  bool gprsDisconnect() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int modemConnect(const char* host, uint16_t port, uint8_t mux) {
 | 
					  int modemConnect(const char* host, uint16_t port, uint8_t mux) {
 | 
				
			||||||
    sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port, GF(","), TCP_KEEP_ALIVE);
 | 
					    sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port, GF(","), TINY_GSM_TCP_KEEP_ALIVE);
 | 
				
			||||||
    int rsp = waitResponse(75000L,
 | 
					    int rsp = waitResponse(75000L,
 | 
				
			||||||
                           GFP(GSM_OK),
 | 
					                           GFP(GSM_OK),
 | 
				
			||||||
                           GFP(GSM_ERROR),
 | 
					                           GFP(GSM_ERROR),
 | 
				
			||||||
@@ -301,6 +312,7 @@ private:
 | 
				
			|||||||
      return -1;
 | 
					      return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.write((uint8_t*)buff, len);
 | 
					    stream.write((uint8_t*)buff, len);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
 | 
					    if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
 | 
				
			||||||
      return -1;
 | 
					      return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -314,7 +326,10 @@ private:
 | 
				
			|||||||
    return 1 == res;
 | 
					    return 1 == res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Private Utilities */
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Utilities */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename T>
 | 
					  template<typename T>
 | 
				
			||||||
  void streamWrite(T last) {
 | 
					  void streamWrite(T last) {
 | 
				
			||||||
    stream.print(last);
 | 
					    stream.print(last);
 | 
				
			||||||
@@ -326,7 +341,14 @@ private:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int streamRead() { return stream.read(); }
 | 
					  bool streamSkipUntil(char c) { //TODO: timeout
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
 | 
					      if (stream.read() == c)
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String streamReadUntil(char c) {
 | 
					  String streamReadUntil(char c) {
 | 
				
			||||||
    String return_string = stream.readStringUntil(c);
 | 
					    String return_string = stream.readStringUntil(c);
 | 
				
			||||||
@@ -376,7 +398,7 @@ private:
 | 
				
			|||||||
    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)) {
 | 
				
			||||||
@@ -395,16 +417,20 @@ private:
 | 
				
			|||||||
          index = 5;
 | 
					          index = 5;
 | 
				
			||||||
          goto finish;
 | 
					          goto finish;
 | 
				
			||||||
        } else if (data.endsWith(GF(GSM_NL "+IPD,"))) {
 | 
					        } else if (data.endsWith(GF(GSM_NL "+IPD,"))) {
 | 
				
			||||||
          mux = stream.readStringUntil(',').toInt();
 | 
					          int mux = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += mux;
 | 
					          int len = stream.readStringUntil(':').toInt();
 | 
				
			||||||
          data += (',');
 | 
					          if (len > sockets[mux]->rx.free()) {
 | 
				
			||||||
          len = stream.readStringUntil(':').toInt();
 | 
					            DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          data += len;
 | 
					          } else {
 | 
				
			||||||
          data += (':');
 | 
					            DBG("### Got: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          gotData = true;
 | 
					          }
 | 
				
			||||||
          index = 6;
 | 
					          while (len--) {
 | 
				
			||||||
          goto finish;
 | 
					            while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
        } else if (data.endsWith(GF("1,CLOSED" GSM_NL))) { //TODO: use mux
 | 
					            sockets[mux]->rx.put(stream.read());
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          data = "";
 | 
				
			||||||
 | 
					          return index;
 | 
				
			||||||
 | 
					        } else if (data.endsWith(GF(GSM_NL "1,CLOSED" GSM_NL))) { //TODO: use mux
 | 
				
			||||||
          sockets[1]->sock_connected = false;
 | 
					          sockets[1]->sock_connected = false;
 | 
				
			||||||
          index = 7;
 | 
					          index = 7;
 | 
				
			||||||
          goto finish;
 | 
					          goto finish;
 | 
				
			||||||
@@ -462,9 +488,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  Stream&       stream;
 | 
					  Stream&       stream;
 | 
				
			||||||
  GsmClient*    sockets[5];
 | 
					  GsmClient*    sockets[TINY_GSM_MUX_COUNT];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,8 @@
 | 
				
			|||||||
  #define TINY_GSM_RX_BUFFER 256
 | 
					  #define TINY_GSM_RX_BUFFER 256
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TINY_GSM_MUX_COUNT 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmCommon.h>
 | 
					#include <TinyGsmCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_NL "\r\n"
 | 
					#define GSM_NL "\r\n"
 | 
				
			||||||
@@ -40,11 +42,6 @@ enum RegStatus {
 | 
				
			|||||||
class TinyGsm
 | 
					class TinyGsm
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					 | 
				
			||||||
    : stream(stream)
 | 
					 | 
				
			||||||
  {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
@@ -108,7 +105,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();
 | 
					    return rx.size();
 | 
				
			||||||
@@ -152,6 +149,13 @@ public:
 | 
				
			|||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  virtual operator bool() { return connected(); }
 | 
					  virtual operator bool() { return connected(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Extended API
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsm*      at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
@@ -161,6 +165,12 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TinyGsm(Stream& stream)
 | 
				
			||||||
 | 
					    : stream(stream)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Basic functions
 | 
					   * Basic functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -216,6 +226,18 @@ public:
 | 
				
			|||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getModemInfo() {
 | 
				
			||||||
 | 
					    sendAT(GF("I"));
 | 
				
			||||||
 | 
					    String res;
 | 
				
			||||||
 | 
					    if (waitResponse(1000L, res) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.replace(GSM_NL "OK" GSM_NL, "");
 | 
				
			||||||
 | 
					    res.replace(GSM_NL, " ");
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Power functions
 | 
					   * Power functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -233,6 +255,11 @@ public:
 | 
				
			|||||||
    return init();
 | 
					    return init();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool poweroff() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CPWROFF"));
 | 
				
			||||||
 | 
					    return waitResponse(3000L) == 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * SIM card functions
 | 
					   * SIM card functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -303,16 +330,16 @@ public:
 | 
				
			|||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 /*
 | 
					  /*
 | 
				
			||||||
  * Generic network functions
 | 
					   * Generic network functions
 | 
				
			||||||
  */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int getSignalQuality() {
 | 
					  int getSignalQuality() {
 | 
				
			||||||
    sendAT(GF("+CSQ"));
 | 
					    sendAT(GF("+CSQ"));
 | 
				
			||||||
    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
					    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
				
			||||||
      return 99;
 | 
					      return 99;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    int res = streamReadUntil(',').toInt();
 | 
					    int res = stream.readStringUntil(',').toInt();
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -364,13 +391,15 @@ public:
 | 
				
			|||||||
    sendAT(GF("+XIIC?"));
 | 
					    sendAT(GF("+XIIC?"));
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*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"));
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }*/
 | 
					    }
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -380,30 +409,72 @@ public:
 | 
				
			|||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getLocalIP() {
 | 
				
			||||||
 | 
					    sendAT(GF("+XIIC?"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+XIIC:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    String res = stream.readStringUntil('\n');
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  IPAddress localIP() {
 | 
				
			||||||
 | 
					    IPAddress res;
 | 
				
			||||||
 | 
					    res.fromString(getLocalIP());
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Phone Call functions
 | 
					   * Phone Call functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callAnswer() {
 | 
					  bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
    sendAT(GF("A"));
 | 
					 | 
				
			||||||
    return waitResponse() == 1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callNumber(const String& number) {
 | 
					  bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
    sendAT(GF("D"), number);
 | 
					 | 
				
			||||||
    return waitResponse() == 1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callHangup(const String& number) {
 | 
					  bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
    sendAT(GF("H"), number);
 | 
					
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					  bool callRedial() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
  }
 | 
					
 | 
				
			||||||
 | 
					  bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Messaging functions
 | 
					   * Messaging functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String sendUSSD(const String& code) {
 | 
				
			||||||
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("+CSCS=\"HEX\""));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("D"), code);
 | 
				
			||||||
 | 
					    if (waitResponse(10000L, GF(GSM_NL "+CUSD:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    String hex = stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    int dcs = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dcs == 15) {
 | 
				
			||||||
 | 
					      return decodeHex8bit(hex);
 | 
				
			||||||
 | 
					    } else if (dcs == 72) {
 | 
				
			||||||
 | 
					      return decodeHex16bit(hex);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return hex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool sendSMS(const String& number, const String& text) {
 | 
					  bool sendSMS(const String& number, const String& text) {
 | 
				
			||||||
 | 
					    sendAT(GF("+CSCS=\"GSM\""));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
    sendAT(GF("+CMGF=1"));
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    sendAT(GF("+CMGS=\""), number, GF("\""));
 | 
					    sendAT(GF("+CMGS=\""), number, GF("\""));
 | 
				
			||||||
@@ -412,31 +483,31 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.print(text);
 | 
					    stream.print(text);
 | 
				
			||||||
    stream.write((char)0x1A);
 | 
					    stream.write((char)0x1A);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool sendSMS_UTF16(const String& number, const void* text, size_t len)
 | 
				
			||||||
 | 
					  TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Location functions
 | 
					   * Location functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Battery functions
 | 
					   * Battery functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					  uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
  String dnsIpQuery(const char* host) {
 | 
					 | 
				
			||||||
   sendAT(GF("+DNS=\""), host, GF("\""));
 | 
					 | 
				
			||||||
   if (waitResponse(10000L, GF(GSM_NL "+DNS:")) != 1) {
 | 
					 | 
				
			||||||
     return "";
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
   String res = streamReadUntil('\n');
 | 
					 | 
				
			||||||
   waitResponse(GF("+DNS:OK" GSM_NL));
 | 
					 | 
				
			||||||
   res.trim();
 | 
					 | 
				
			||||||
   return res;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int modemConnect(const char* host, uint16_t port, uint8_t mux) {
 | 
					  int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
 | 
				
			||||||
    for (int i=0; i<3; i++) {
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool modemConnect(const char* host, uint16_t port, uint8_t mux) {
 | 
				
			||||||
 | 
					    for (int i=0; i<3; i++) { // TODO: no need for loop?
 | 
				
			||||||
      String ip = dnsIpQuery(host);
 | 
					      String ip = dnsIpQuery(host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      sendAT(GF("+TCPSETUP="), mux, GF(","), ip, GF(","), port);
 | 
					      sendAT(GF("+TCPSETUP="), mux, GF(","), ip, GF(","), port);
 | 
				
			||||||
@@ -462,7 +533,7 @@ private:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.write((uint8_t*)buff, len);
 | 
					    stream.write((uint8_t*)buff, len);
 | 
				
			||||||
    stream.write((char)0x0D);
 | 
					    stream.write((char)0x0D);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    if (waitResponse(30000L, GF(GSM_NL "+TCPSEND:")) != 1) {
 | 
					    if (waitResponse(30000L, GF(GSM_NL "+TCPSEND:")) != 1) {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -477,7 +548,52 @@ private:
 | 
				
			|||||||
    return 1 == res;
 | 
					    return 1 == res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Private Utilities */
 | 
					  String dnsIpQuery(const char* host) {
 | 
				
			||||||
 | 
					    sendAT(GF("+DNS=\""), host, GF("\""));
 | 
				
			||||||
 | 
					    if (waitResponse(10000L, GF(GSM_NL "+DNS:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    String res = stream.readStringUntil('\n');
 | 
				
			||||||
 | 
					    waitResponse(GF("+DNS:OK" GSM_NL));
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static String decodeHex8bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=2) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      char b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      result += b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static String decodeHex16bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=4) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      char b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      if (b) { // If high byte is non-zero, we can't handle it ;(
 | 
				
			||||||
 | 
					        b = '?';
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        buf[0] = instr[i+2];
 | 
				
			||||||
 | 
					        buf[1] = instr[i+3];
 | 
				
			||||||
 | 
					        b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      result += b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Utilities */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename T>
 | 
					  template<typename T>
 | 
				
			||||||
  void streamWrite(T last) {
 | 
					  void streamWrite(T last) {
 | 
				
			||||||
    stream.print(last);
 | 
					    stream.print(last);
 | 
				
			||||||
@@ -489,26 +605,13 @@ private:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int streamRead() { return stream.read(); }
 | 
					  bool streamSkipUntil(char c) { //TODO: timeout
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
  String streamReadUntil(char c) {
 | 
					      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
    String return_string = stream.readStringUntil(c);
 | 
					      if (stream.read() == c)
 | 
				
			||||||
    return_string.trim();
 | 
					        return true;
 | 
				
			||||||
    if (String(c) == GSM_NL || String(c) == "\n"){
 | 
					    }
 | 
				
			||||||
      DBG(return_string, c, "    ");
 | 
					    return false;
 | 
				
			||||||
    } else DBG(return_string, c);
 | 
					 | 
				
			||||||
    return return_string;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool streamSkipUntil(char c) {
 | 
					 | 
				
			||||||
    String skipped = stream.readStringUntil(c);
 | 
					 | 
				
			||||||
    skipped.trim();
 | 
					 | 
				
			||||||
    if (skipped.length()) {
 | 
					 | 
				
			||||||
      if (String(c) == GSM_NL || String(c) == "\n"){
 | 
					 | 
				
			||||||
        DBG(skipped, c, "    ");
 | 
					 | 
				
			||||||
      } else DBG(skipped, c);
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    } else return false;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename... Args>
 | 
					  template<typename... Args>
 | 
				
			||||||
@@ -539,7 +642,7 @@ private:
 | 
				
			|||||||
    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)) {
 | 
				
			||||||
@@ -558,24 +661,26 @@ private:
 | 
				
			|||||||
          index = 5;
 | 
					          index = 5;
 | 
				
			||||||
          goto finish;
 | 
					          goto finish;
 | 
				
			||||||
        } else if (data.endsWith(GF("+TCPRECV:"))) {
 | 
					        } else if (data.endsWith(GF("+TCPRECV:"))) {
 | 
				
			||||||
          mux = stream.readStringUntil(',').toInt();
 | 
					          int mux = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += mux;
 | 
					          int len = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += (',');
 | 
					          if (len > sockets[mux]->rx.free()) {
 | 
				
			||||||
          len = stream.readStringUntil(',').toInt();
 | 
					            DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          data += len;
 | 
					          } else {
 | 
				
			||||||
          data += (',');
 | 
					            DBG("### Got: ", len, "->", sockets[mux]->rx.free());
 | 
				
			||||||
          gotData = true;
 | 
					          }
 | 
				
			||||||
          index = 6;
 | 
					          while (len--) {
 | 
				
			||||||
          goto finish;
 | 
					            while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
 | 
					            sockets[mux]->rx.put(stream.read());
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          data = "";
 | 
				
			||||||
        } else if (data.endsWith(GF("+TCPCLOSE:"))) {
 | 
					        } else if (data.endsWith(GF("+TCPCLOSE:"))) {
 | 
				
			||||||
          mux = stream.readStringUntil(',').toInt();
 | 
					          int mux = stream.readStringUntil(',').toInt();
 | 
				
			||||||
          data += mux;
 | 
					          stream.readStringUntil('\n');
 | 
				
			||||||
          data += (',');
 | 
					          if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
 | 
				
			||||||
          String concl = stream.readStringUntil('\n');
 | 
					            sockets[mux]->sock_connected = false;
 | 
				
			||||||
          data += concl;
 | 
					          }
 | 
				
			||||||
          sockets[mux]->sock_connected = false;
 | 
					          data = "";
 | 
				
			||||||
          index = 7;
 | 
					          DBG("### Closed: ", mux);
 | 
				
			||||||
          goto finish;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } while (millis() - startMillis < timeout);
 | 
					    } while (millis() - startMillis < timeout);
 | 
				
			||||||
@@ -630,9 +735,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  Stream&       stream;
 | 
					  Stream&       stream;
 | 
				
			||||||
  GsmClient*    sockets[2];
 | 
					  GsmClient*    sockets[TINY_GSM_MUX_COUNT];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,8 @@
 | 
				
			|||||||
  #define TINY_GSM_RX_BUFFER 64
 | 
					  #define TINY_GSM_RX_BUFFER 64
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TINY_GSM_MUX_COUNT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmCommon.h>
 | 
					#include <TinyGsmCommon.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_NL "\r\n"
 | 
					#define GSM_NL "\r\n"
 | 
				
			||||||
@@ -38,33 +40,30 @@ enum RegStatus {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TinyGsm
 | 
					class TinyGsmSim800
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  TinyGsm(Stream& stream)
 | 
					 | 
				
			||||||
    : stream(stream)
 | 
					 | 
				
			||||||
  {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GsmClient : public Client
 | 
					class GsmClient : public Client
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  friend class TinyGsm;
 | 
					  friend class TinyGsmSim800;
 | 
				
			||||||
  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(TinyGsmSim800& modem, uint8_t mux = 1) {
 | 
				
			||||||
    init(&modem, mux);
 | 
					    init(&modem, mux);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool init(TinyGsm* modem, uint8_t mux = 1) {
 | 
					  bool init(TinyGsmSim800* modem, uint8_t mux = 1) {
 | 
				
			||||||
    this->at = modem;
 | 
					    this->at = modem;
 | 
				
			||||||
    this->mux = mux;
 | 
					    this->mux = mux;
 | 
				
			||||||
    sock_available = 0;
 | 
					    sock_available = 0;
 | 
				
			||||||
 | 
					    prev_check = 0;
 | 
				
			||||||
    sock_connected = false;
 | 
					    sock_connected = false;
 | 
				
			||||||
 | 
					    got_data = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    at->sockets[mux] = this;
 | 
					    at->sockets[mux] = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,7 +109,14 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  virtual int available() {
 | 
					  virtual int available() {
 | 
				
			||||||
    TINY_GSM_YIELD();
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
    if (!rx.size()) {
 | 
					    if (!rx.size() && sock_connected) {
 | 
				
			||||||
 | 
					      // Workaround: sometimes SIM800 forgets to notify about data arrival.
 | 
				
			||||||
 | 
					      // TODO: Currently we ping the module periodically,
 | 
				
			||||||
 | 
					      // but maybe there's a better indicator that we need to poll
 | 
				
			||||||
 | 
					      if (millis() - prev_check > 500) {
 | 
				
			||||||
 | 
					        got_data = true;
 | 
				
			||||||
 | 
					        prev_check = millis();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      at->maintain();
 | 
					      at->maintain();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return rx.size() + sock_available;
 | 
					    return rx.size() + sock_available;
 | 
				
			||||||
@@ -157,15 +163,48 @@ public:
 | 
				
			|||||||
    return sock_connected;
 | 
					    return sock_connected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  virtual operator bool() { return connected(); }
 | 
					  virtual operator bool() { return connected(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Extended API
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  TinyGsm*      at;
 | 
					  TinyGsmSim800*      at;
 | 
				
			||||||
  uint8_t       mux;
 | 
					  uint8_t       mux;
 | 
				
			||||||
  uint16_t      sock_available;
 | 
					  uint16_t      sock_available;
 | 
				
			||||||
 | 
					  uint32_t      prev_check;
 | 
				
			||||||
  bool          sock_connected;
 | 
					  bool          sock_connected;
 | 
				
			||||||
 | 
					  bool          got_data;
 | 
				
			||||||
  RxFifo        rx;
 | 
					  RxFifo        rx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GsmClientSecure : public GsmClient
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  GsmClientSecure() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GsmClientSecure(TinyGsmSim800& modem, uint8_t mux = 1)
 | 
				
			||||||
 | 
					    : GsmClient(modem, mux)
 | 
				
			||||||
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual int connect(const char *host, uint16_t port) {
 | 
				
			||||||
 | 
					    TINY_GSM_YIELD();
 | 
				
			||||||
 | 
					    rx.clear();
 | 
				
			||||||
 | 
					    sock_connected = at->modemConnect(host, port, mux, true);
 | 
				
			||||||
 | 
					    return sock_connected;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TinyGsmSim800(Stream& stream)
 | 
				
			||||||
 | 
					    : stream(stream)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    memset(sockets, 0, sizeof(sockets));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Basic functions
 | 
					   * Basic functions
 | 
				
			||||||
@@ -178,7 +217,9 @@ public:
 | 
				
			|||||||
    if (!autoBaud()) {
 | 
					    if (!autoBaud()) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sendAT(GF("&FZE0"));  // Factory + Reset + Echo Off
 | 
					    sendAT(GF("&FZ"));  // Factory + Reset
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("E0"));   // Echo Off
 | 
				
			||||||
    if (waitResponse() != 1) {
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -187,7 +228,7 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool autoBaud(unsigned long timeout = 10000L) {
 | 
					  bool autoBaud(unsigned long timeout = 10000L) {
 | 
				
			||||||
    streamWrite(GF("AAAAAAAAAAAAA"));  // extra A's to help detect the baud rate
 | 
					    //streamWrite(GF("AAAAA" GSM_NL));  // TODO: extra A's to help detect the baud rate
 | 
				
			||||||
    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
					    for (unsigned long start = millis(); millis() - start < timeout; ) {
 | 
				
			||||||
      sendAT(GF(""));
 | 
					      sendAT(GF(""));
 | 
				
			||||||
      if (waitResponse(200) == 1) {
 | 
					      if (waitResponse(200) == 1) {
 | 
				
			||||||
@@ -200,6 +241,13 @@ public:
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void maintain() {
 | 
					  void maintain() {
 | 
				
			||||||
 | 
					    for (int mux = 0; mux < TINY_GSM_MUX_COUNT; mux++) {
 | 
				
			||||||
 | 
					      GsmClient* sock = sockets[mux];
 | 
				
			||||||
 | 
					      if (sock && sock->got_data) {
 | 
				
			||||||
 | 
					        sock->got_data = false;
 | 
				
			||||||
 | 
					        sock->sock_available = modemGetAvailable(mux);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    while (stream.available()) {
 | 
					    while (stream.available()) {
 | 
				
			||||||
      waitResponse(10, NULL, NULL);
 | 
					      waitResponse(10, NULL, NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -220,6 +268,26 @@ public:
 | 
				
			|||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getModemInfo() {
 | 
				
			||||||
 | 
					    sendAT(GF("I"));
 | 
				
			||||||
 | 
					    String res;
 | 
				
			||||||
 | 
					    if (waitResponse(1000L, res) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.replace(GSM_NL "OK" GSM_NL, "");
 | 
				
			||||||
 | 
					    res.replace(GSM_NL, " ");
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool hasSSL() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CIPSSL=?"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CIPSSL:")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Power functions
 | 
					   * Power functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -240,6 +308,23 @@ public:
 | 
				
			|||||||
    return init();
 | 
					    return init();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool poweroff() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CPOWD=1"));
 | 
				
			||||||
 | 
					    return waitResponse(GF("NORMAL POWER DOWN")) == 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool radioOff() {
 | 
				
			||||||
 | 
					    if (!autoBaud()) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sendAT(GF("+CFUN=0"));
 | 
				
			||||||
 | 
					    if (waitResponse(10000L) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    delay(3000);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * SIM card functions
 | 
					   * SIM card functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -310,16 +395,16 @@ public:
 | 
				
			|||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 /*
 | 
					  /*
 | 
				
			||||||
  * Generic network functions
 | 
					   * Generic network functions
 | 
				
			||||||
  */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int getSignalQuality() {
 | 
					  int getSignalQuality() {
 | 
				
			||||||
    sendAT(GF("+CSQ"));
 | 
					    sendAT(GF("+CSQ"));
 | 
				
			||||||
    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
					    if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
 | 
				
			||||||
      return 99;
 | 
					      return 99;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    int res = streamReadUntil(',').toInt();
 | 
					    int res = stream.readStringUntil(',').toInt();
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -413,9 +498,7 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendAT(GF("+CIFSR;E0"));
 | 
					    sendAT(GF("+CIFSR;E0"));
 | 
				
			||||||
    String data;
 | 
					    if (waitResponse(10000L) != 1) {
 | 
				
			||||||
    if (waitResponse(10000L, data) != 1) {
 | 
					 | 
				
			||||||
      data.replace(GSM_NL, "");
 | 
					 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -432,6 +515,22 @@ public:
 | 
				
			|||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getLocalIP() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CIFSR;E0"));
 | 
				
			||||||
 | 
					    String res;
 | 
				
			||||||
 | 
					    if (waitResponse(10000L, res) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  IPAddress localIP() {
 | 
				
			||||||
 | 
					    IPAddress res;
 | 
				
			||||||
 | 
					    res.fromString(getLocalIP());
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Phone Call functions
 | 
					   * Phone Call functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -446,13 +545,25 @@ public:
 | 
				
			|||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Returns true on pick-up, false on error/busy
 | 
				
			||||||
  bool callNumber(const String& number) {
 | 
					  bool callNumber(const String& number) {
 | 
				
			||||||
    sendAT(GF("D"), number);
 | 
					    sendAT(GF("D"), number, ";");
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					    int status = waitResponse(60000L, GF("OK"), GF("BUSY"), GF("NO ANSWER"), GF("NO CARRIER"));
 | 
				
			||||||
 | 
					    switch (status) {
 | 
				
			||||||
 | 
					    case 1:  return true;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					    case 3:  return false;
 | 
				
			||||||
 | 
					    default: return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool callHangup(const String& number) {
 | 
					  //bool callRedial() {
 | 
				
			||||||
    sendAT(GF("H"), number);
 | 
					  //  sendAT(GF("DL"));
 | 
				
			||||||
 | 
					  //  return waitResponse() == 1;
 | 
				
			||||||
 | 
					  //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool callHangup() {
 | 
				
			||||||
 | 
					    sendAT(GF("H"));
 | 
				
			||||||
    return waitResponse() == 1;
 | 
					    return waitResponse() == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -460,6 +571,32 @@ public:
 | 
				
			|||||||
   * Messaging functions
 | 
					   * Messaging functions
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String sendUSSD(const String& code) {
 | 
				
			||||||
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("+CSCS=\"HEX\""));
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    sendAT(GF("+CUSD=1,\""), code, GF("\""));
 | 
				
			||||||
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (waitResponse(10000L, GF(GSM_NL "+CUSD:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    String hex = stream.readStringUntil('"');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    int dcs = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dcs == 15) {
 | 
				
			||||||
 | 
					      return decodeHex8bit(hex);
 | 
				
			||||||
 | 
					    } else if (dcs == 72) {
 | 
				
			||||||
 | 
					      return decodeHex16bit(hex);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return hex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool sendSMS(const String& number, const String& text) {
 | 
					  bool sendSMS(const String& number, const String& text) {
 | 
				
			||||||
    sendAT(GF("+CMGF=1"));
 | 
					    sendAT(GF("+CMGF=1"));
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
@@ -469,6 +606,7 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.print(text);
 | 
					    stream.print(text);
 | 
				
			||||||
    stream.write((char)0x1A);
 | 
					    stream.write((char)0x1A);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -495,6 +633,7 @@ public:
 | 
				
			|||||||
      stream.print(c, HEX);
 | 
					      stream.print(c, HEX);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    stream.write((char)0x1A);
 | 
					    stream.write((char)0x1A);
 | 
				
			||||||
 | 
					    stream.flush();
 | 
				
			||||||
    return waitResponse(60000L) == 1;
 | 
					    return waitResponse(60000L) == 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -505,11 +644,12 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  String getGsmLocation() {
 | 
					  String getGsmLocation() {
 | 
				
			||||||
    sendAT(GF("+CIPGSMLOC=1,1"));
 | 
					    sendAT(GF("+CIPGSMLOC=1,1"));
 | 
				
			||||||
    if (waitResponse(GF(GSM_NL "+CIPGSMLOC:")) != 1) {
 | 
					    if (waitResponse(10000L, GF(GSM_NL "+CIPGSMLOC:")) != 1) {
 | 
				
			||||||
      return "";
 | 
					      return "";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    String res = streamReadUntil('\n');
 | 
					    String res = stream.readStringUntil('\n');
 | 
				
			||||||
    waitResponse();
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -530,13 +670,30 @@ public:
 | 
				
			|||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					  int getBattPercent() {
 | 
				
			||||||
  int modemConnect(const char* host, uint16_t port, uint8_t mux) {
 | 
					    sendAT(GF("+CBC"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    int res = stream.readStringUntil(',').toInt();
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = false) {
 | 
				
			||||||
 | 
					    sendAT(GF("+CIPSSL="), ssl);
 | 
				
			||||||
 | 
					    int rsp = waitResponse();
 | 
				
			||||||
 | 
					    if (ssl && rsp != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
 | 
					    sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
 | 
				
			||||||
    int rsp = waitResponse(75000L,
 | 
					    rsp = waitResponse(75000L,
 | 
				
			||||||
                           GF("CONNECT OK" GSM_NL),
 | 
					                       GF("CONNECT OK" GSM_NL),
 | 
				
			||||||
                           GF("CONNECT FAIL" GSM_NL),
 | 
					                       GF("CONNECT FAIL" GSM_NL),
 | 
				
			||||||
                           GF("ALREADY CONNECT" GSM_NL));
 | 
					                       GF("ALREADY CONNECT" GSM_NL));
 | 
				
			||||||
    return (1 == rsp);
 | 
					    return (1 == rsp);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -573,16 +730,15 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (size_t i=0; i<len; i++) {
 | 
					    for (size_t i=0; i<len; i++) {
 | 
				
			||||||
#ifdef TINY_GSM_USE_HEX
 | 
					#ifdef TINY_GSM_USE_HEX
 | 
				
			||||||
      while (stream.available() < 2) {}
 | 
					      while (stream.available() < 2) { TINY_GSM_YIELD(); }
 | 
				
			||||||
      char buf[4] = { 0, };
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
      buf[0] = streamRead();
 | 
					      buf[0] = streamRead();
 | 
				
			||||||
      buf[1] = streamRead();
 | 
					      buf[1] = streamRead();
 | 
				
			||||||
      char c = strtol(buf, NULL, 16);
 | 
					      char c = strtol(buf, NULL, 16);
 | 
				
			||||||
      DBG(c);
 | 
					      DBG(c);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
      while (!stream.available()) {}
 | 
					      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
      char c = streamRead();
 | 
					      char c = stream.read();
 | 
				
			||||||
      DBG(c);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
      sockets[mux]->rx.put(c);
 | 
					      sockets[mux]->rx.put(c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -612,7 +768,41 @@ private:
 | 
				
			|||||||
    return 1 == res;
 | 
					    return 1 == res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Private Utilities */
 | 
					  static String decodeHex8bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=2) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      char b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      result += b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static String decodeHex16bit(String &instr) {
 | 
				
			||||||
 | 
					    String result;
 | 
				
			||||||
 | 
					    for (unsigned i=0; i<instr.length(); i+=4) {
 | 
				
			||||||
 | 
					      char buf[4] = { 0, };
 | 
				
			||||||
 | 
					      buf[0] = instr[i];
 | 
				
			||||||
 | 
					      buf[1] = instr[i+1];
 | 
				
			||||||
 | 
					      char b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      if (b) { // If high byte is non-zero, we can't handle it ;(
 | 
				
			||||||
 | 
					        b = '?';
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        buf[0] = instr[i+2];
 | 
				
			||||||
 | 
					        buf[1] = instr[i+3];
 | 
				
			||||||
 | 
					        b = strtol(buf, NULL, 16);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      result += b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Utilities */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename T>
 | 
					  template<typename T>
 | 
				
			||||||
  void streamWrite(T last) {
 | 
					  void streamWrite(T last) {
 | 
				
			||||||
    stream.print(last);
 | 
					    stream.print(last);
 | 
				
			||||||
@@ -624,26 +814,13 @@ private:
 | 
				
			|||||||
    streamWrite(tail...);
 | 
					    streamWrite(tail...);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int streamRead() { return stream.read(); }
 | 
					  bool streamSkipUntil(char c) { //TODO: timeout
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
  String streamReadUntil(char c) {
 | 
					      while (!stream.available()) { TINY_GSM_YIELD(); }
 | 
				
			||||||
    String return_string = stream.readStringUntil(c);
 | 
					      if (stream.read() == c)
 | 
				
			||||||
    return_string.trim();
 | 
					        return true;
 | 
				
			||||||
    if (String(c) == GSM_NL || String(c) == "\n"){
 | 
					    }
 | 
				
			||||||
      DBG(return_string, c, "    ");
 | 
					    return false;
 | 
				
			||||||
    } else DBG(return_string, c);
 | 
					 | 
				
			||||||
    return return_string;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool streamSkipUntil(char c) {
 | 
					 | 
				
			||||||
    String skipped = stream.readStringUntil(c);
 | 
					 | 
				
			||||||
    skipped.trim();
 | 
					 | 
				
			||||||
    if (skipped.length()) {
 | 
					 | 
				
			||||||
      if (String(c) == GSM_NL || String(c) == "\n"){
 | 
					 | 
				
			||||||
        DBG(skipped, c, "    ");
 | 
					 | 
				
			||||||
      } else DBG(skipped, c);
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    } else return false;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<typename... Args>
 | 
					  template<typename... Args>
 | 
				
			||||||
@@ -666,14 +843,12 @@ private:
 | 
				
			|||||||
    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(64);
 | 
				
			||||||
    bool gotData = false;
 | 
					 | 
				
			||||||
    int mux = -1;
 | 
					 | 
				
			||||||
    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)) {
 | 
				
			||||||
@@ -695,8 +870,11 @@ private:
 | 
				
			|||||||
          index = 6;
 | 
					          index = 6;
 | 
				
			||||||
          String mode = streamReadUntil(',');
 | 
					          String mode = streamReadUntil(',');
 | 
				
			||||||
          if (mode.toInt() == 1) {
 | 
					          if (mode.toInt() == 1) {
 | 
				
			||||||
            mux = streamReadUntil('\n').toInt();
 | 
					            int mux = stream.readStringUntil('\n').toInt();
 | 
				
			||||||
            gotData = true;
 | 
					            if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
 | 
				
			||||||
 | 
					              sockets[mux]->got_data = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            data = "";
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            data += mode;
 | 
					            data += mode;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@@ -704,10 +882,12 @@ private:
 | 
				
			|||||||
          index = 7;
 | 
					          index = 7;
 | 
				
			||||||
          int nl = data.lastIndexOf(GSM_NL, data.length()-8);
 | 
					          int nl = data.lastIndexOf(GSM_NL, data.length()-8);
 | 
				
			||||||
          int coma = data.indexOf(',', nl+2);
 | 
					          int coma = data.indexOf(',', nl+2);
 | 
				
			||||||
          mux = data.substring(nl+2, coma).toInt();
 | 
					          int mux = data.substring(nl+2, coma).toInt();
 | 
				
			||||||
          if (mux) {
 | 
					          if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
 | 
				
			||||||
            sockets[mux]->sock_connected = false;
 | 
					            sockets[mux]->sock_connected = false;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          data = "";
 | 
				
			||||||
 | 
					          DBG("### Closed: ", mux);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } while (millis() - startMillis < timeout);
 | 
					    } while (millis() - startMillis < timeout);
 | 
				
			||||||
@@ -718,17 +898,6 @@ private:
 | 
				
			|||||||
        DBG(GSM_NL, "### Unhandled:", data);
 | 
					        DBG(GSM_NL, "### Unhandled:", data);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      data.trim();
 | 
					 | 
				
			||||||
      data.replace(GSM_NL GSM_NL, GSM_NL);
 | 
					 | 
				
			||||||
      data.replace(GSM_NL, GSM_NL "    ");
 | 
					 | 
				
			||||||
      if (data.length()) {
 | 
					 | 
				
			||||||
        DBG(GSM_NL, "<<< ", data);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (gotData) {
 | 
					 | 
				
			||||||
      sockets[mux]->sock_available = modemGetAvailable(mux);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return index;
 | 
					    return index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -746,11 +915,9 @@ private:
 | 
				
			|||||||
    return waitResponse(1000, r1, r2, r3, r4, r5);
 | 
					    return waitResponse(1000, r1, r2, r3, r4, r5);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					protected:
 | 
				
			||||||
  Stream&       stream;
 | 
					  Stream&       stream;
 | 
				
			||||||
  GsmClient*    sockets[5];
 | 
					  GsmClient*    sockets[TINY_GSM_MUX_COUNT];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef TinyGsm::GsmClient TinyGsmClient;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										148
									
								
								TinyGsmClientSIM808.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								TinyGsmClientSIM808.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file     TinyGsmClientSIM808.h
 | 
				
			||||||
 | 
					 * @author   Volodymyr Shymanskyy
 | 
				
			||||||
 | 
					 * @license  LGPL-3.0
 | 
				
			||||||
 | 
					 * @copyright  Copyright (c) 2016 Volodymyr Shymanskyy
 | 
				
			||||||
 | 
					 * @date     Nov 2016
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TinyGsmClientSIM808_h
 | 
				
			||||||
 | 
					#define TinyGsmClientSIM808_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TinyGsmClientSIM800.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TinyGsmSim808: public TinyGsmSim800
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TinyGsmSim808(Stream& stream)
 | 
				
			||||||
 | 
					    : TinyGsmSim800(stream)
 | 
				
			||||||
 | 
					  {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * GPS location functions
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // enable GPS
 | 
				
			||||||
 | 
					  bool enableGPS() {
 | 
				
			||||||
 | 
					    uint16_t state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sendAT(GF("+CGNSPWR=1"));
 | 
				
			||||||
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool disableGPS() {
 | 
				
			||||||
 | 
					    uint16_t state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sendAT(GF("+CGNSPWR=0"));
 | 
				
			||||||
 | 
					    if (waitResponse() != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // get the RAW GPS output
 | 
				
			||||||
 | 
					  // works only with ans SIM808 V2
 | 
				
			||||||
 | 
					  String getGPSraw() {
 | 
				
			||||||
 | 
					    sendAT(GF("+CGNSINF"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
 | 
				
			||||||
 | 
					      return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    String res = stream.readStringUntil('\n');
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					    res.trim();
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // get GPS informations
 | 
				
			||||||
 | 
					  // works only with ans SIM808 V2
 | 
				
			||||||
 | 
					  bool getGPS(float *lat, float *lon, float *speed=0, int *alt=0, int *vsat=0, int *usat=0) {
 | 
				
			||||||
 | 
					    //String buffer = "";
 | 
				
			||||||
 | 
					    char chr_buffer[12];
 | 
				
			||||||
 | 
					    bool fix = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sendAT(GF("+CGNSINF"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    stream.readStringUntil(','); // mode
 | 
				
			||||||
 | 
					    if ( stream.readStringUntil(',').toInt() == 1 ) fix = true;
 | 
				
			||||||
 | 
					    stream.readStringUntil(','); //utctime
 | 
				
			||||||
 | 
					    *lat =  stream.readStringUntil(',').toFloat(); //lat
 | 
				
			||||||
 | 
					    *lon =  stream.readStringUntil(',').toFloat(); //lon
 | 
				
			||||||
 | 
					    if (alt != NULL) *alt =  stream.readStringUntil(',').toFloat(); //lon
 | 
				
			||||||
 | 
					    if (speed != NULL) *speed = stream.readStringUntil(',').toFloat(); //speed
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    stream.readStringUntil(',');
 | 
				
			||||||
 | 
					    if (vsat != NULL) *vsat = stream.readStringUntil(',').toInt(); //viewed satelites
 | 
				
			||||||
 | 
					    if (usat != NULL) *usat = stream.readStringUntil(',').toInt(); //used satelites
 | 
				
			||||||
 | 
					    stream.readStringUntil('\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fix;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // get GPS time
 | 
				
			||||||
 | 
					  // works only with SIM808 V2
 | 
				
			||||||
 | 
					  bool getGPSTime(int *year, int *month, int *day, int *hour, int *minute, int *second) {
 | 
				
			||||||
 | 
					    bool fix = false;
 | 
				
			||||||
 | 
					    char chr_buffer[12];
 | 
				
			||||||
 | 
					    sendAT(GF("+CGNSINF"));
 | 
				
			||||||
 | 
					    if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < 3; i++) {
 | 
				
			||||||
 | 
					      String buffer = stream.readStringUntil(',');
 | 
				
			||||||
 | 
					      buffer.toCharArray(chr_buffer, sizeof(chr_buffer));
 | 
				
			||||||
 | 
					      switch (i) {
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					          //mode
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 1:
 | 
				
			||||||
 | 
					          //fixstatus
 | 
				
			||||||
 | 
					          if ( buffer.toInt() == 1 ) {
 | 
				
			||||||
 | 
					            fix = buffer.toInt();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					          *year = buffer.substring(0,4).toInt();
 | 
				
			||||||
 | 
					          *month = buffer.substring(4,6).toInt();
 | 
				
			||||||
 | 
					          *day = buffer.substring(6,8).toInt();
 | 
				
			||||||
 | 
					          *hour = buffer.substring(8,10).toInt();
 | 
				
			||||||
 | 
					          *minute = buffer.substring(10,12).toInt();
 | 
				
			||||||
 | 
					          *second = buffer.substring(12,14).toInt();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					          // if nothing else matches, do the default
 | 
				
			||||||
 | 
					          // default is optional
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    String res = stream.readStringUntil('\n');
 | 
				
			||||||
 | 
					    waitResponse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (fix) {
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -26,6 +26,9 @@
 | 
				
			|||||||
  #define TINY_GSM_YIELD() { delay(0); }
 | 
					  #define TINY_GSM_YIELD() { delay(0); }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TINY_GSM_ATTR_NOT_AVAILABLE __attribute__((error("Not available on this modem type")))
 | 
				
			||||||
 | 
					#define TINY_GSM_ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__AVR__)
 | 
					#if defined(__AVR__)
 | 
				
			||||||
  #define TINY_GSM_PROGMEM PROGMEM
 | 
					  #define TINY_GSM_PROGMEM PROGMEM
 | 
				
			||||||
  typedef const __FlashStringHelper* GsmConstStr;
 | 
					  typedef const __FlashStringHelper* GsmConstStr;
 | 
				
			||||||
@@ -69,4 +72,26 @@ const T& TinyGsmMax(const T& a, const T& b)
 | 
				
			|||||||
    return (b < a) ? a : b;
 | 
					    return (b < a) ? a : b;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class T>
 | 
				
			||||||
 | 
					uint32_t TinyGsmAutoBaud(T& SerialAT)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static uint32_t rates[] = { 115200, 57600, 38400, 19200, 9600, 74400, 74880, 230400, 460800, 2400, 4800, 14400, 28800 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (unsigned i = 0; i < sizeof(rates)/sizeof(rates[0]); i++) {
 | 
				
			||||||
 | 
					    uint32_t rate = rates[i];
 | 
				
			||||||
 | 
					    DBG("Trying baud rate", rate, "...");
 | 
				
			||||||
 | 
					    SerialAT.begin(rate);
 | 
				
			||||||
 | 
					    delay(10);
 | 
				
			||||||
 | 
					    for (int i=0; i<3; i++) {
 | 
				
			||||||
 | 
					      SerialAT.print("AT\r\n");
 | 
				
			||||||
 | 
					      String input = SerialAT.readString();
 | 
				
			||||||
 | 
					      if (input.indexOf("OK") >= 0) {
 | 
				
			||||||
 | 
					        DBG("Modem responded at rate", rate);
 | 
				
			||||||
 | 
					        return rate;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										172
									
								
								examples/AllFunctions/AllFunctions.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								examples/AllFunctions/AllFunctions.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
				
			|||||||
 | 
					/**************************************************************
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * TinyGSM Getting Started guide:
 | 
				
			||||||
 | 
					 *   http://tiny.cc/tiny-gsm-readme
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * NOTE:
 | 
				
			||||||
 | 
					 * Some of the functions may be unavailable for your modem.
 | 
				
			||||||
 | 
					 * Just comment them out.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 **************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Select your modem:
 | 
				
			||||||
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_M590
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set serial for debug console (to the Serial Monitor, speed 115200)
 | 
				
			||||||
 | 
					#define SerialMon Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set serial for AT commands (to the module)
 | 
				
			||||||
 | 
					// Use Hardware Serial on Mega, Leonardo, Micro
 | 
				
			||||||
 | 
					#define SerialAT Serial1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// or Software Serial on Uno, Nano
 | 
				
			||||||
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					#define TINY_GSM_DEBUG SerialMon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set phone numbers, if you want to test SMS and Calls
 | 
				
			||||||
 | 
					//#define SMS_TARGET  "+380xxxxxxxxx"
 | 
				
			||||||
 | 
					//#define CALL_TARGET "+380xxxxxxxxx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Your GPRS credentials
 | 
				
			||||||
 | 
					// Leave empty, if missing user or pass
 | 
				
			||||||
 | 
					const char apn[]  = "YourAPN";
 | 
				
			||||||
 | 
					const char user[] = "";
 | 
				
			||||||
 | 
					const char pass[] = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					  #include <StreamDebugger.h>
 | 
				
			||||||
 | 
					  StreamDebugger debugger(SerialAT, SerialMon);
 | 
				
			||||||
 | 
					  TinyGsm modem(debugger);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsm modem(SerialAT);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					  // Set console baud rate
 | 
				
			||||||
 | 
					  SerialMon.begin(115200);
 | 
				
			||||||
 | 
					  delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set GSM module baud rate
 | 
				
			||||||
 | 
					  TinyGsmAutoBaud(SerialAT);
 | 
				
			||||||
 | 
					  delay(3000);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Restart takes quite some time
 | 
				
			||||||
 | 
					  // To skip it, call init() instead of restart()
 | 
				
			||||||
 | 
					  DBG("Initializing modem...");
 | 
				
			||||||
 | 
					  if (!modem.restart()) {
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  DBG("Modem:", modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DBG("Waiting for network...");
 | 
				
			||||||
 | 
					  if (!modem.waitForNetwork()) {
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DBG("Connecting to", apn);
 | 
				
			||||||
 | 
					  if (!modem.gprsConnect(apn, user, pass)) {
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String ccid = modem.getSimCCID();
 | 
				
			||||||
 | 
					  DBG("CCID:", ccid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String imei = modem.getIMEI();
 | 
				
			||||||
 | 
					  DBG("IMEI:", imei);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String cop = modem.getOperator();
 | 
				
			||||||
 | 
					  DBG("Operator:", cop);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  IPAddress local = modem.localIP();
 | 
				
			||||||
 | 
					  DBG("Local IP:", local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int csq = modem.getSignalQuality();
 | 
				
			||||||
 | 
					  DBG("Signal quality:", csq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This is NOT supported on M590
 | 
				
			||||||
 | 
					  int battLevel = modem.getBattPercent();
 | 
				
			||||||
 | 
					  DBG("Battery lavel:", battLevel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This is only supported on SIMxxx series
 | 
				
			||||||
 | 
					  float battVoltage = modem.getBattVoltage() / 1000.0F;
 | 
				
			||||||
 | 
					  DBG("Battery voltage:", battVoltage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This is only supported on SIMxxx series
 | 
				
			||||||
 | 
					  String gsmLoc = modem.getGsmLocation();
 | 
				
			||||||
 | 
					  DBG("GSM location:", gsmLoc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String ussd_balance = modem.sendUSSD("*111#");
 | 
				
			||||||
 | 
					  DBG("Balance (USSD):", ussd_balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String ussd_phone_num = modem.sendUSSD("*161#");
 | 
				
			||||||
 | 
					  DBG("Phone number (USSD):", ussd_phone_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TINY_GSM_MODEM_SIM808)
 | 
				
			||||||
 | 
					  modem.enableGPS();
 | 
				
			||||||
 | 
					  String gps_raw = modem.getGPSraw();
 | 
				
			||||||
 | 
					  modem.disableGPS();
 | 
				
			||||||
 | 
					  DBG("GPS raw data:", gps_raw);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(SMS_TARGET)
 | 
				
			||||||
 | 
					  res = modem.sendSMS(SMS_TARGET, String("Hello from ") + imei);
 | 
				
			||||||
 | 
					  DBG("SMS:", res ? "OK" : "fail");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This is only supported on SIMxxx series
 | 
				
			||||||
 | 
					  res = modem.sendSMS_UTF16(SMS_TARGET, u"Привіііт!", 9);
 | 
				
			||||||
 | 
					  DBG("UTF16 SMS:", res ? "OK" : "fail");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CALL_TARGET)
 | 
				
			||||||
 | 
					  DBG("Calling:", CALL_TARGET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This is NOT supported on M590
 | 
				
			||||||
 | 
					  res = modem.callNumber(CALL_TARGET);
 | 
				
			||||||
 | 
					  DBG("Call:", res ? "OK" : "fail");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (res) {
 | 
				
			||||||
 | 
					    delay(5000L);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    res = modem.callHangup();
 | 
				
			||||||
 | 
					    DBG("Hang up:", res ? "OK" : "fail");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  modem.gprsDisconnect();
 | 
				
			||||||
 | 
					  DBG("GPRS disconnected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Try to power-off (modem may decide to restart automatically)
 | 
				
			||||||
 | 
					  // To turn off modem completely, please use Reset/Enable pins
 | 
				
			||||||
 | 
					  modem.poweroff();
 | 
				
			||||||
 | 
					  DBG("Poweroff.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Do nothing forevermore
 | 
				
			||||||
 | 
					  while (true) {
 | 
				
			||||||
 | 
					    modem.maintain();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,6 +30,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -74,6 +75,10 @@ void setup()
 | 
				
			|||||||
  Serial.println("Initializing modem...");
 | 
					  Serial.println("Initializing modem...");
 | 
				
			||||||
  modem.restart();
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Unlock your SIM card with a PIN
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
  //modem.simUnlock("1234");
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/**************************************************************
 | 
					/**************************************************************
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * For this example, you need to install CRC32 library:
 | 
					 * For this example, you need to install CRC32 library:
 | 
				
			||||||
 *   https://github.com/vshymanskyy/CRC32.git
 | 
					 *   https://github.com/bakercp/CRC32
 | 
				
			||||||
 *   or from http://librarymanager/all#CRC32+checksum
 | 
					 *   or from http://librarymanager/all#CRC32+checksum
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * TinyGSM Getting Started guide:
 | 
					 * TinyGSM Getting Started guide:
 | 
				
			||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -24,8 +25,8 @@
 | 
				
			|||||||
// Increase RX buffer
 | 
					// Increase RX buffer
 | 
				
			||||||
#define TINY_GSM_RX_BUFFER 1030
 | 
					#define TINY_GSM_RX_BUFFER 1030
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmClient.h>
 | 
					//#define DUMP_AT_COMMANDS
 | 
				
			||||||
#include <CRC32.h>
 | 
					//#define TINY_GSM_DEBUG Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Your GPRS credentials
 | 
					// Your GPRS credentials
 | 
				
			||||||
// Leave empty, if missing user or pass
 | 
					// Leave empty, if missing user or pass
 | 
				
			||||||
@@ -40,12 +41,23 @@ const char pass[] = "";
 | 
				
			|||||||
//#include <SoftwareSerial.h>
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TinyGsm modem(SerialAT);
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					#include <CRC32.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					  #include <StreamDebugger.h>
 | 
				
			||||||
 | 
					  StreamDebugger debugger(SerialAT, Serial);
 | 
				
			||||||
 | 
					  TinyGsm modem(debugger);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsm modem(SerialAT);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
TinyGsmClient client(modem);
 | 
					TinyGsmClient client(modem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char server[] = "cdn.rawgit.com";
 | 
					const char server[] = "cdn.rawgit.com";
 | 
				
			||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_1k.bin";
 | 
					const int  port     = 80;
 | 
				
			||||||
uint32_t knownCRC32 = 0x6f50d767;
 | 
					
 | 
				
			||||||
 | 
					const char resource[]  = "/vshymanskyy/tinygsm/master/extras/test_1k.bin";
 | 
				
			||||||
 | 
					uint32_t knownCRC32    = 0x6f50d767;
 | 
				
			||||||
uint32_t knownFileSize = 1024;   // In case server does not send it
 | 
					uint32_t knownFileSize = 1024;   // In case server does not send it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup() {
 | 
					void setup() {
 | 
				
			||||||
@@ -62,6 +74,10 @@ void setup() {
 | 
				
			|||||||
  Serial.println("Initializing modem...");
 | 
					  Serial.println("Initializing modem...");
 | 
				
			||||||
  modem.restart();
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Unlock your SIM card with a PIN
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
  //modem.simUnlock("1234");
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -99,7 +115,7 @@ void loop() {
 | 
				
			|||||||
  Serial.print(server);
 | 
					  Serial.print(server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // if you get a connection, report back via serial:
 | 
					  // if you get a connection, report back via serial:
 | 
				
			||||||
  if (!client.connect(server, 80)) {
 | 
					  if (!client.connect(server, port)) {
 | 
				
			||||||
    Serial.println(" fail");
 | 
					    Serial.println(" fail");
 | 
				
			||||||
    delay(10000);
 | 
					    delay(10000);
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										152
									
								
								examples/HttpClient/HttpClient.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								examples/HttpClient/HttpClient.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
				
			|||||||
 | 
					/**************************************************************
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This sketch connects to a website and downloads a page.
 | 
				
			||||||
 | 
					 * It can be used to perform HTTP/RESTful API calls.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For this example, you need to install ArduinoHttpClient library:
 | 
				
			||||||
 | 
					 *   https://github.com/arduino-libraries/ArduinoHttpClient
 | 
				
			||||||
 | 
					 *   or from http://librarymanager/all#ArduinoHttpClient
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * TinyGSM Getting Started guide:
 | 
				
			||||||
 | 
					 *   http://tiny.cc/tiny-gsm-readme
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 **************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Select your modem:
 | 
				
			||||||
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_M590
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_ESP8266
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Increase RX buffer
 | 
				
			||||||
 | 
					#define TINY_GSM_RX_BUFFER 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Use Hardware Serial on Mega, Leonardo, Micro
 | 
				
			||||||
 | 
					#define SerialAT Serial1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// or Software Serial on Uno, Nano
 | 
				
			||||||
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					//#define TINY_GSM_DEBUG Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Your GPRS credentials
 | 
				
			||||||
 | 
					// Leave empty, if missing user or pass
 | 
				
			||||||
 | 
					const char apn[]  = "YourAPN";
 | 
				
			||||||
 | 
					const char user[] = "";
 | 
				
			||||||
 | 
					const char pass[] = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Name of the server we want to connect to
 | 
				
			||||||
 | 
					const char server[] = "cdn.rawgit.com";
 | 
				
			||||||
 | 
					const int  port     = 443;
 | 
				
			||||||
 | 
					// Path to download (this is the bit after the hostname in the URL)
 | 
				
			||||||
 | 
					const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					#include <ArduinoHttpClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					  #include <StreamDebugger.h>
 | 
				
			||||||
 | 
					  StreamDebugger debugger(SerialAT, Serial);
 | 
				
			||||||
 | 
					  TinyGsm modem(debugger);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsm modem(SerialAT);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TinyGsmClient client(modem);
 | 
				
			||||||
 | 
					HttpClient http(client, server, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					  // Set console baud rate
 | 
				
			||||||
 | 
					  Serial.begin(115200);
 | 
				
			||||||
 | 
					  delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set GSM module baud rate
 | 
				
			||||||
 | 
					  SerialAT.begin(115200);
 | 
				
			||||||
 | 
					  delay(3000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Restart takes quite some time
 | 
				
			||||||
 | 
					  // To skip it, call init() instead of restart()
 | 
				
			||||||
 | 
					  Serial.println("Initializing modem...");
 | 
				
			||||||
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					  Serial.print(F("Waiting for network..."));
 | 
				
			||||||
 | 
					  if (!modem.waitForNetwork()) {
 | 
				
			||||||
 | 
					    Serial.println(" fail");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Serial.println(" OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.print(F("Connecting to "));
 | 
				
			||||||
 | 
					  Serial.print(apn);
 | 
				
			||||||
 | 
					  if (!modem.gprsConnect(apn, user, pass)) {
 | 
				
			||||||
 | 
					    Serial.println(" fail");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Serial.println(" OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.print(F("Performing HTTP GET request... "));
 | 
				
			||||||
 | 
					  int err = http.get(resource);
 | 
				
			||||||
 | 
					  if (err != 0) {
 | 
				
			||||||
 | 
					    Serial.println("failed to connect");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int status = http.responseStatusCode();
 | 
				
			||||||
 | 
					  Serial.println(status);
 | 
				
			||||||
 | 
					  if (!status) {
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (http.headerAvailable()) {
 | 
				
			||||||
 | 
					    String headerName = http.readHeaderName();
 | 
				
			||||||
 | 
					    String headerValue = http.readHeaderValue();
 | 
				
			||||||
 | 
					    //Serial.println(headerName + " : " + headerValue);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int length = http.contentLength();
 | 
				
			||||||
 | 
					  if (length >= 0) {
 | 
				
			||||||
 | 
					    Serial.println(String("Content length is: ") + length);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (http.isResponseChunked()) {
 | 
				
			||||||
 | 
					    Serial.println("This response is chunked");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String body = http.responseBody();
 | 
				
			||||||
 | 
					  Serial.println("Response:");
 | 
				
			||||||
 | 
					  Serial.println(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.println(String("Body length is: ") + body.length());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  http.stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  modem.gprsDisconnect();
 | 
				
			||||||
 | 
					  Serial.println("GPRS disconnected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Do nothing forevermore
 | 
				
			||||||
 | 
					  while (true) {
 | 
				
			||||||
 | 
					    delay(1000);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										155
									
								
								examples/HttpsClient/HttpsClient.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								examples/HttpsClient/HttpsClient.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					/**************************************************************
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This sketch connects to a website and downloads a page.
 | 
				
			||||||
 | 
					 * It can be used to perform HTTP/RESTful API calls.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For this example, you need to install ArduinoHttpClient library:
 | 
				
			||||||
 | 
					 *   https://github.com/arduino-libraries/ArduinoHttpClient
 | 
				
			||||||
 | 
					 *   or from http://librarymanager/all#ArduinoHttpClient
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * TinyGSM Getting Started guide:
 | 
				
			||||||
 | 
					 *   http://tiny.cc/tiny-gsm-readme
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 **************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Select your modem
 | 
				
			||||||
 | 
					// SSL/TLS is currently supported only with SIM8xx series
 | 
				
			||||||
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					#define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Increase RX buffer
 | 
				
			||||||
 | 
					#define TINY_GSM_RX_BUFFER 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Use Hardware Serial on Mega, Leonardo, Micro
 | 
				
			||||||
 | 
					#define SerialAT Serial1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// or Software Serial on Uno, Nano
 | 
				
			||||||
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					//#define TINY_GSM_DEBUG Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Your GPRS credentials
 | 
				
			||||||
 | 
					// Leave empty, if missing user or pass
 | 
				
			||||||
 | 
					const char apn[]  = "YourAPN";
 | 
				
			||||||
 | 
					const char user[] = "";
 | 
				
			||||||
 | 
					const char pass[] = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Name of the server we want to connect to
 | 
				
			||||||
 | 
					const char server[] = "cdn.rawgit.com";
 | 
				
			||||||
 | 
					const int  port     = 443;
 | 
				
			||||||
 | 
					// Path to download (this is the bit after the hostname in the URL)
 | 
				
			||||||
 | 
					const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					#include <ArduinoHttpClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DUMP_AT_COMMANDS
 | 
				
			||||||
 | 
					  #include <StreamDebugger.h>
 | 
				
			||||||
 | 
					  StreamDebugger debugger(SerialAT, Serial);
 | 
				
			||||||
 | 
					  TinyGsm modem(debugger);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  TinyGsm modem(SerialAT);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TinyGsmClientSecure client(modem);
 | 
				
			||||||
 | 
					HttpClient http(client, server, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					  // Set console baud rate
 | 
				
			||||||
 | 
					  Serial.begin(115200);
 | 
				
			||||||
 | 
					  delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set GSM module baud rate
 | 
				
			||||||
 | 
					  SerialAT.begin(115200);
 | 
				
			||||||
 | 
					  delay(3000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Restart takes quite some time
 | 
				
			||||||
 | 
					  // To skip it, call init() instead of restart()
 | 
				
			||||||
 | 
					  Serial.println("Initializing modem...");
 | 
				
			||||||
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					  if (!modem.hasSSL()) {
 | 
				
			||||||
 | 
					    Serial.println("SSL is not supported by this modem");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.print(F("Waiting for network..."));
 | 
				
			||||||
 | 
					  if (!modem.waitForNetwork()) {
 | 
				
			||||||
 | 
					    Serial.println(" fail");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Serial.println(" OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.print(F("Connecting to "));
 | 
				
			||||||
 | 
					  Serial.print(apn);
 | 
				
			||||||
 | 
					  if (!modem.gprsConnect(apn, user, pass)) {
 | 
				
			||||||
 | 
					    Serial.println(" fail");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Serial.println(" OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.print(F("Performing HTTP GET request... "));
 | 
				
			||||||
 | 
					  http.connectionKeepAlive(); // Currently, this is needed for HTTPS
 | 
				
			||||||
 | 
					  int err = http.get(resource);
 | 
				
			||||||
 | 
					  if (err != 0) {
 | 
				
			||||||
 | 
					    Serial.println("failed to connect");
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int status = http.responseStatusCode();
 | 
				
			||||||
 | 
					  Serial.println(status);
 | 
				
			||||||
 | 
					  if (!status) {
 | 
				
			||||||
 | 
					    delay(10000);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (http.headerAvailable()) {
 | 
				
			||||||
 | 
					    String headerName = http.readHeaderName();
 | 
				
			||||||
 | 
					    String headerValue = http.readHeaderValue();
 | 
				
			||||||
 | 
					    //Serial.println(headerName + " : " + headerValue);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int length = http.contentLength();
 | 
				
			||||||
 | 
					  if (length >= 0) {
 | 
				
			||||||
 | 
					    Serial.println(String("Content length is: ") + length);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (http.isResponseChunked()) {
 | 
				
			||||||
 | 
					    Serial.println("This response is chunked");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String body = http.responseBody();
 | 
				
			||||||
 | 
					  Serial.println("Response:");
 | 
				
			||||||
 | 
					  Serial.println(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Serial.println(String("Body length is: ") + body.length());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  http.stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  modem.gprsDisconnect();
 | 
				
			||||||
 | 
					  Serial.println("GPRS disconnected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Do nothing forevermore
 | 
				
			||||||
 | 
					  while (true) {
 | 
				
			||||||
 | 
					    delay(1000);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,6 +27,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -81,6 +82,10 @@ void setup() {
 | 
				
			|||||||
  Serial.println("Initializing modem...");
 | 
					  Serial.println("Initializing modem...");
 | 
				
			||||||
  modem.restart();
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Unlock your SIM card with a PIN
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
  //modem.simUnlock("1234");
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,12 +10,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
// #define TINY_GSM_MODEM_M590
 | 
					// #define TINY_GSM_MODEM_M590
 | 
				
			||||||
// #define TINY_GSM_MODEM_ESP8266
 | 
					// #define TINY_GSM_MODEM_ESP8266
 | 
				
			||||||
// #define TINY_GSM_MODEM_XBEE 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmClient.h>
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +38,7 @@ TinyGsmClient client(modem);
 | 
				
			|||||||
const char server[] = "cdn.rawgit.com";
 | 
					const char server[] = "cdn.rawgit.com";
 | 
				
			||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
 | 
					const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int port = 80;
 | 
					const int port = 80;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup() {
 | 
					void setup() {
 | 
				
			||||||
  // Set console baud rate
 | 
					  // Set console baud rate
 | 
				
			||||||
@@ -54,6 +54,10 @@ void setup() {
 | 
				
			|||||||
  Serial.println(F("Initializing modem..."));
 | 
					  Serial.println(F("Initializing modem..."));
 | 
				
			||||||
  modem.restart();
 | 
					  modem.restart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String modemInfo = modem.getModemInfo();
 | 
				
			||||||
 | 
					  Serial.print("Modem: ");
 | 
				
			||||||
 | 
					  Serial.println(modemInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Unlock your SIM card with a PIN
 | 
					  // Unlock your SIM card with a PIN
 | 
				
			||||||
  //modem.simUnlock("1234");
 | 
					  //modem.simUnlock("1234");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
#######################################
 | 
					#######################################
 | 
				
			||||||
TinyGsm	KEYWORD1
 | 
					TinyGsm	KEYWORD1
 | 
				
			||||||
TinyGsmClient	KEYWORD1
 | 
					TinyGsmClient	KEYWORD1
 | 
				
			||||||
 | 
					TinyGsmClientSecure	KEYWORD1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SerialAT	KEYWORD1
 | 
					SerialAT	KEYWORD1
 | 
				
			||||||
SerialMon	KEYWORD1
 | 
					SerialMon	KEYWORD1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "TinyGSM",
 | 
					  "name": "TinyGSM",
 | 
				
			||||||
  "version": "0.1.8",
 | 
					  "version": "0.3.1",
 | 
				
			||||||
  "description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports GSM modules with AT command interface: SIM800, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900, SIM900A, SIM900D, SIM908, SIM968",
 | 
					  "description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports GSM modules with AT command interface: SIM800, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900, SIM900A, SIM900D, SIM908, SIM968",
 | 
				
			||||||
  "keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968",
 | 
					  "keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968",
 | 
				
			||||||
  "authors":
 | 
					  "authors":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
name=TinyGSM
 | 
					name=TinyGSM
 | 
				
			||||||
version=0.1.8
 | 
					version=0.3.1
 | 
				
			||||||
author=Volodymyr Shymanskyy
 | 
					author=Volodymyr Shymanskyy
 | 
				
			||||||
maintainer=Volodymyr Shymanskyy
 | 
					maintainer=Volodymyr Shymanskyy
 | 
				
			||||||
sentence=A small Arduino library for GPRS modules, that just works.
 | 
					sentence=A small Arduino library for GPRS modules, that just works.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -30,7 +31,9 @@
 | 
				
			|||||||
//#include <SoftwareSerial.h>
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TinyGsm modem(SerialAT);
 | 
					#define TINY_GSM_DEBUG SerialMon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Module baud rate
 | 
					// Module baud rate
 | 
				
			||||||
uint32_t rate = 0; // Set to 0 for Auto-Detect
 | 
					uint32_t rate = 0; // Set to 0 for Auto-Detect
 | 
				
			||||||
@@ -44,21 +47,7 @@ void setup() {
 | 
				
			|||||||
void loop() {
 | 
					void loop() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!rate) {
 | 
					  if (!rate) {
 | 
				
			||||||
      static uint32_t rates[] = { 115200, 9600, 57600, 19200, 38400, 74400, 74880, 230400, 460800, 2400, 4800, 14400, 28800 };
 | 
					    rate = TinyGsmAutoBaud(SerialAT);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      SerialMon.println("Autodetecting baud rate");
 | 
					 | 
				
			||||||
      for (unsigned i = 0; i < sizeof(rates)/sizeof(rates[0]); i++) {
 | 
					 | 
				
			||||||
        SerialMon.print(String("Trying baud rate ") + rates[i] + "... ");
 | 
					 | 
				
			||||||
        SerialAT.begin(rates[i]);
 | 
					 | 
				
			||||||
        delay(10);
 | 
					 | 
				
			||||||
        if (modem.autoBaud(1000)) {
 | 
					 | 
				
			||||||
          rate = rates[i];
 | 
					 | 
				
			||||||
          SerialMon.println(F("OK"));
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          SerialMon.println(F("fail"));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!rate) {
 | 
					  if (!rate) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -18,11 +19,10 @@
 | 
				
			|||||||
// #define TINY_GSM_MODEM_ESP8266
 | 
					// #define TINY_GSM_MODEM_ESP8266
 | 
				
			||||||
// #define TINY_GSM_MODEM_XBEE
 | 
					// #define TINY_GSM_MODEM_XBEE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Increase buffer fo see less commands
 | 
					// Increase the buffer
 | 
				
			||||||
#define TINY_GSM_RX_BUFFER 256
 | 
					#define TINY_GSM_RX_BUFFER 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmClient.h>
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
#include <StreamDebugger.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Your GPRS credentials
 | 
					// Your GPRS credentials
 | 
				
			||||||
// Leave empty, if missing user or pass
 | 
					// Leave empty, if missing user or pass
 | 
				
			||||||
@@ -42,12 +42,13 @@ const char pass[] = "";
 | 
				
			|||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <StreamDebugger.h>
 | 
				
			||||||
StreamDebugger debugger(SerialAT, SerialMon);
 | 
					StreamDebugger debugger(SerialAT, SerialMon);
 | 
				
			||||||
TinyGsm modem(debugger);
 | 
					TinyGsm modem(debugger);
 | 
				
			||||||
TinyGsmClient client(modem);
 | 
					TinyGsmClient client(modem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char server[] = "cdn.rawgit.com";
 | 
					const char server[] = "cdn.rawgit.com";
 | 
				
			||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_simple.txt";
 | 
					const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup() {
 | 
					void setup() {
 | 
				
			||||||
  // Set console baud rate
 | 
					  // Set console baud rate
 | 
				
			||||||
@@ -144,9 +145,9 @@ void loop() {
 | 
				
			|||||||
  SerialMon.println("************************");
 | 
					  SerialMon.println("************************");
 | 
				
			||||||
  SerialMon.print  (" Received: ");
 | 
					  SerialMon.print  (" Received: ");
 | 
				
			||||||
  SerialMon.print(bytesReceived);
 | 
					  SerialMon.print(bytesReceived);
 | 
				
			||||||
  SerialMon.println("bytes");
 | 
					  SerialMon.println(" bytes");
 | 
				
			||||||
  SerialMon.print  (" Test:     ");
 | 
					  SerialMon.print  (" Test:     ");
 | 
				
			||||||
  SerialMon.println((bytesReceived == 1000) ? "PASSED" : "FAIL");
 | 
					  SerialMon.println((bytesReceived == 121) ? "PASSED" : "FAILED");
 | 
				
			||||||
  SerialMon.println("************************");
 | 
					  SerialMon.println("************************");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Do nothing forevermore
 | 
					  // Do nothing forevermore
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Select your modem:
 | 
					// Select your modem:
 | 
				
			||||||
#define TINY_GSM_MODEM_SIM800
 | 
					#define TINY_GSM_MODEM_SIM800
 | 
				
			||||||
 | 
					// #define TINY_GSM_MODEM_SIM808
 | 
				
			||||||
// #define TINY_GSM_MODEM_SIM900
 | 
					// #define TINY_GSM_MODEM_SIM900
 | 
				
			||||||
// #define TINY_GSM_MODEM_A6
 | 
					// #define TINY_GSM_MODEM_A6
 | 
				
			||||||
// #define TINY_GSM_MODEM_A7
 | 
					// #define TINY_GSM_MODEM_A7
 | 
				
			||||||
@@ -19,7 +20,6 @@
 | 
				
			|||||||
// #define TINY_GSM_MODEM_XBEE
 | 
					// #define TINY_GSM_MODEM_XBEE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <TinyGsmClient.h>
 | 
					#include <TinyGsmClient.h>
 | 
				
			||||||
#include <StreamDebugger.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set serial for debug console (to the Serial Monitor, speed 115200)
 | 
					// Set serial for debug console (to the Serial Monitor, speed 115200)
 | 
				
			||||||
#define SerialMon Serial
 | 
					#define SerialMon Serial
 | 
				
			||||||
@@ -32,6 +32,7 @@
 | 
				
			|||||||
//#include <SoftwareSerial.h>
 | 
					//#include <SoftwareSerial.h>
 | 
				
			||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
					//SoftwareSerial SerialAT(2, 3); // RX, TX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <StreamDebugger.h>
 | 
				
			||||||
StreamDebugger debugger(SerialAT, SerialMon);
 | 
					StreamDebugger debugger(SerialAT, SerialMon);
 | 
				
			||||||
TinyGsm modem(debugger);
 | 
					TinyGsm modem(debugger);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user