diff --git a/src/TinyGsmClientA6.h b/src/TinyGsmClientA6.h index da2b027..5efd20d 100644 --- a/src/TinyGsmClientA6.h +++ b/src/TinyGsmClientA6.h @@ -39,11 +39,27 @@ enum RegStatus { }; +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmA6 Class +//============================================================================// +//============================================================================// + + + class TinyGsmA6 { public: + +//============================================================================// +//============================================================================// +// The A6 Client Class +//============================================================================// +//============================================================================// + + class GsmClient : public Client { friend class TinyGsmA6; @@ -167,9 +183,28 @@ private: RxFifo rx; }; +//============================================================================// +//============================================================================// +// The A6 Does not have a secure client! +//============================================================================// +//============================================================================// + + + +//============================================================================// +//============================================================================// +// The A6 Modem Functions +//============================================================================// +//============================================================================// + + public: +#ifdef GSM_DEFAULT_STREAM + TinyGsmA6(Stream& stream = GSM_DEFAULT_STREAM) +#else TinyGsmA6(Stream& stream) +#endif : stream(stream) { memset(sockets, 0, sizeof(sockets)); @@ -241,6 +276,8 @@ public: return res; } + bool hasSSL() { return false; } + /* * Power functions */ @@ -313,17 +350,6 @@ public: return SIM_ERROR; } - RegStatus getRegistrationStatus() { - sendAT(GF("+CREG?")); - if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { - return REG_UNKNOWN; - } - streamSkipUntil(','); // Skip format (0) - int status = stream.readStringUntil('\n').toInt(); - waitResponse(); - return (RegStatus)status; - } - String getOperator() { sendAT(GF("+COPS=3,0")); // Set format waitResponse(); @@ -342,6 +368,17 @@ public: * Generic network functions */ + RegStatus getRegistrationStatus() { + sendAT(GF("+CREG?")); + if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { + return REG_UNKNOWN; + } + streamSkipUntil(','); // Skip format (0) + int status = stream.readStringUntil('\n').toInt(); + waitResponse(); + return (RegStatus)status; + } + int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { @@ -367,6 +404,26 @@ public: return false; } + String getLocalIP() { + sendAT(GF("+CIFSR")); + String res; + if (waitResponse(10000L, res) != 1) { + return ""; + } + res.replace(GSM_NL "OK" GSM_NL, ""); + res.replace(GSM_NL, ""); + res.trim(); + return res; + } + + IPAddress localIP() { + return TinyGsmIpFromString(getLocalIP()); + } + + /* + * WiFi functions + */ + /* * GPRS functions */ @@ -423,22 +480,6 @@ public: return (res == 1); } - String getLocalIP() { - sendAT(GF("+CIFSR")); - String res; - if (waitResponse(10000L, res) != 1) { - return ""; - } - res.replace(GSM_NL "OK" GSM_NL, ""); - res.replace(GSM_NL, ""); - res.trim(); - return res; - } - - IPAddress localIP() { - return TinyGsmIpFromString(getLocalIP()); - } - /* * Messaging functions */ diff --git a/src/TinyGsmClientESP8266.h b/src/TinyGsmClientESP8266.h index 8dec021..805a6d6 100644 --- a/src/TinyGsmClientESP8266.h +++ b/src/TinyGsmClientESP8266.h @@ -9,7 +9,7 @@ #ifndef TinyGsmClientESP8266_h #define TinyGsmClientESP8266_h -//#define TINY_GSM_DEBUG Serial +// #define TINY_GSM_DEBUG Serial #if !defined(TINY_GSM_RX_BUFFER) #define TINY_GSM_RX_BUFFER 512 @@ -24,18 +24,36 @@ static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL; static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL; static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120; +// status of ESP8266 station interface +// 2 : ESP8266 station connected to an AP and has obtained IP +// 3 : ESP8266 station created a TCP or UDP transmission +// 4 : the TCP or UDP transmission of ESP8266 station disconnected +// 5 : ESP8266 station did NOT connect to an AP enum RegStatus { - REG_UNREGISTERED = 0, - REG_SEARCHING = 2, - REG_DENIED = 3, - REG_OK_HOME = 1, - REG_OK_ROAMING = 5, - REG_UNKNOWN = 4, + REG_OK_IP = 2, + REG_OK_TCP = 3, + REG_UNREGISTERED = 4, + REG_DENIED = 5, + REG_UNKNOWN = 6, }; + +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmESP8266 Class +//============================================================================// +//============================================================================// + + class TinyGsmESP8266 { + //============================================================================// + //============================================================================// + // The ESP8266 Client Class + //============================================================================// + //============================================================================// + public: class GsmClient : public Client @@ -158,6 +176,13 @@ private: RxFifo rx; }; +//============================================================================// +//============================================================================// +// The Secure ESP8266 Client Class +//============================================================================// +//============================================================================// + + class GsmClientSecure : public GsmClient { public: @@ -176,9 +201,20 @@ public: } }; + +//============================================================================// +//============================================================================// +// The ESP8266 Modem Functions +//============================================================================// +//============================================================================// + public: +#ifdef GSM_DEFAULT_STREAM + TinyGsmESP8266(Stream& stream = GSM_DEFAULT_STREAM) +#else TinyGsmESP8266(Stream& stream) +#endif : stream(stream) { memset(sockets, 0, sizeof(sockets)); @@ -239,29 +275,7 @@ public: return res; } - bool hasSSL() { - return true; - } - - RegStatus getRegistrationStatus() { - sendAT(GF("+CIPSTATUS")); - int res1 = waitResponse(3000, GF("STATUS:")); - int res2 = 0; - if (res1 == 1) { - res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5")); - } - // status of ESP8266 station interface - // 2 : ESP8266 station connected to an AP and has obtained IP - // 3 : ESP8266 station created a TCP or UDP transmission - // 4 : the TCP or UDP transmission of ESP8266 station disconnected - // 5 : ESP8266 station did NOT connect to an AP - waitResponse(); // Returns an OK after the status - if (res2 == 2) return REG_OK_HOME; - if (res2 == 3) return REG_OK_HOME; - if (res2 == 4) return REG_UNREGISTERED; - if (res2 == 5) return REG_DENIED; - else return REG_UNKNOWN; - } + bool hasSSL() { return true; } /* * Power functions @@ -282,11 +296,30 @@ public: return init(); } + bool poweroff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED; + + + /* + * SIM card functions + */ + /* * Generic network functions */ + RegStatus getRegistrationStatus() { + sendAT(GF("+CIPSTATUS")); + if (waitResponse(3000, GF("STATUS:")) != 1) return REG_UNKNOWN; + int status = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5")); + waitResponse(); // Returns an OK after the status + return (RegStatus)status; + } + int getSignalQuality() { sendAT(GF("+CWJAP_CUR?")); int res1 = waitResponse(GF("No AP"), GF("+CWJAP_CUR:")); @@ -304,7 +337,7 @@ public: bool isNetworkConnected() { RegStatus s = getRegistrationStatus(); - return (s == REG_OK_HOME || s == REG_OK_ROAMING); + return (s == REG_OK_IP || s == REG_OK_TCP); } bool waitForNetwork(unsigned long timeout = 60000L) { @@ -323,6 +356,21 @@ public: return false; } + String getLocalIP() { + sendAT(GF("+CIPSTA_CUR??")); + int res1 = waitResponse(GF("ERROR"), GF("+CWJAP_CUR:")); + if (res1 != 2) { + return ""; + } + String res2 = stream.readStringUntil('"'); + waitResponse(); + return res2; + } + + IPAddress localIP() { + return TinyGsmIpFromString(getLocalIP()); + } + /* * WiFi functions */ @@ -353,20 +401,27 @@ public: return retVal; } - String getLocalIP() { - sendAT(GF("+CIPSTA_CUR??")); - int res1 = waitResponse(GF("ERROR"), GF("+CWJAP_CUR:")); - if (res1 != 2) { - return ""; - } - String res2 = stream.readStringUntil('"'); - waitResponse(); - return res2; - } + /* + * GPRS functions + */ - IPAddress localIP() { - return TinyGsmIpFromString(getLocalIP()); - } + /* + * Messaging functions + */ + + /* + * Location functions + */ + + String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE; + + /* + * Battery functions + */ + + uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE; + + int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE; protected: @@ -400,7 +455,7 @@ protected: bool modemGetConnected(uint8_t mux) { RegStatus s = getRegistrationStatus(); - return (s == REG_OK_HOME || s == REG_OK_ROAMING); + return (s == REG_OK_IP || s == REG_OK_TCP); } public: @@ -436,7 +491,7 @@ public: streamWrite("AT", cmd..., GSM_NL); stream.flush(); TINY_GSM_YIELD(); - //DBG("### AT:", cmd...); + // DBG("### AT:", cmd...); } // TODO: Optimize this! diff --git a/src/TinyGsmClientM590.h b/src/TinyGsmClientM590.h index e0d9431..7bc276c 100644 --- a/src/TinyGsmClientM590.h +++ b/src/TinyGsmClientM590.h @@ -9,7 +9,7 @@ #ifndef TinyGsmClientM590_h #define TinyGsmClientM590_h -//#define TINY_GSM_DEBUG Serial +// #define TINY_GSM_DEBUG Serial #if !defined(TINY_GSM_RX_BUFFER) #define TINY_GSM_RX_BUFFER 256 @@ -39,9 +39,21 @@ enum RegStatus { }; +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmM590 Class +//============================================================================// +//============================================================================// + class TinyGsmM590 { +//============================================================================// +//============================================================================// +// The M590 Client Class +//============================================================================// +//============================================================================// + public: class GsmClient : public Client @@ -158,15 +170,33 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmM590* at; + TinyGsmM590* at; uint8_t mux; bool sock_connected; RxFifo rx; }; +//============================================================================// +//============================================================================// +// The M590 Has no Secure client! +//============================================================================// +//============================================================================// + + + +//============================================================================// +//============================================================================// +// The M590 Modem Functions +//============================================================================// +//============================================================================// + public: +#ifdef GSM_DEFAULT_STREAM + TinyGsmM590(Stream& stream = GSM_DEFAULT_STREAM) +#else TinyGsmM590(Stream& stream) +#endif : stream(stream) { memset(sockets, 0, sizeof(sockets)); @@ -243,6 +273,8 @@ public: return res; } + bool hasSSL() { return false; } + /* * Power functions */ @@ -322,17 +354,6 @@ public: return SIM_ERROR; } - RegStatus getRegistrationStatus() { - sendAT(GF("+CREG?")); - if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { - return REG_UNKNOWN; - } - streamSkipUntil(','); // Skip format (0) - int status = stream.readStringUntil('\n').toInt(); - waitResponse(); - return (RegStatus)status; - } - String getOperator() { sendAT(GF("+COPS?")); if (waitResponse(GF(GSM_NL "+COPS:")) != 1) { @@ -348,6 +369,17 @@ public: * Generic network functions */ + RegStatus getRegistrationStatus() { + sendAT(GF("+CREG?")); + if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { + return REG_UNKNOWN; + } + streamSkipUntil(','); // Skip format (0) + int status = stream.readStringUntil('\n').toInt(); + waitResponse(); + return (RegStatus)status; + } + int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { @@ -373,10 +405,30 @@ public: return false; } + 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() { + return TinyGsmIpFromString(getLocalIP()); + } + + /* + * WiFi 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 = "") { gprsDisconnect(); sendAT(GF("+XISP=0")); @@ -429,22 +481,6 @@ public: return res == 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() { - return TinyGsmIpFromString(getLocalIP()); - } - /* * Messaging functions */ @@ -596,7 +632,7 @@ public: streamWrite("AT", cmd..., GSM_NL); stream.flush(); TINY_GSM_YIELD(); - //DBG("### AT:", cmd...); + // DBG("### AT:", cmd...); } // TODO: Optimize this! diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index acdfcf8..056adc7 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -9,8 +9,8 @@ #ifndef TinyGsmClientSIM800_h #define TinyGsmClientSIM800_h -//#define TINY_GSM_DEBUG Serial -//#define TINY_GSM_USE_HEX +// #define TINY_GSM_DEBUG Serial +// #define TINY_GSM_USE_HEX #if !defined(TINY_GSM_RX_BUFFER) #define TINY_GSM_RX_BUFFER 64 @@ -40,9 +40,22 @@ enum RegStatus { }; +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmSim800 Class +//============================================================================// +//============================================================================// + class TinyGsmSim800 { +//============================================================================// +//============================================================================// +// The Sim800 Client Class +//============================================================================// +//============================================================================// + + public: class GsmClient : public Client @@ -180,6 +193,13 @@ private: RxFifo rx; }; +//============================================================================// +//============================================================================// +// The SIM800 Secure Client +//============================================================================// +//============================================================================// + + class GsmClientSecure : public GsmClient { public: @@ -198,9 +218,19 @@ public: } }; +//============================================================================// +//============================================================================// +// The SIM800 Modem Functions +//============================================================================// +//============================================================================// + public: +#ifdef GSM_DEFAULT_STREAM + TinyGsmSim800(Stream& stream = GSM_DEFAULT_STREAM) +#else TinyGsmSim800(Stream& stream) +#endif : stream(stream) { memset(sockets, 0, sizeof(sockets)); @@ -391,17 +421,6 @@ public: return SIM_ERROR; } - RegStatus getRegistrationStatus() { - sendAT(GF("+CREG?")); - if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { - return REG_UNKNOWN; - } - streamSkipUntil(','); // Skip format (0) - int status = stream.readStringUntil('\n').toInt(); - waitResponse(); - return (RegStatus)status; - } - String getOperator() { sendAT(GF("+COPS?")); if (waitResponse(GF(GSM_NL "+COPS:")) != 1) { @@ -417,6 +436,17 @@ public: * Generic network functions */ + RegStatus getRegistrationStatus() { + sendAT(GF("+CREG?")); + if (waitResponse(GF(GSM_NL "+CREG:")) != 1) { + return REG_UNKNOWN; + } + streamSkipUntil(','); // Skip format (0) + int status = stream.readStringUntil('\n').toInt(); + waitResponse(); + return (RegStatus)status; + } + int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { @@ -442,10 +472,30 @@ public: return false; } + String getLocalIP() { + sendAT(GF("+CIFSR;E0")); + String res; + if (waitResponse(10000L, res) != 1) { + return ""; + } + res.replace(GSM_NL "OK" GSM_NL, ""); + res.replace(GSM_NL, ""); + res.trim(); + return res; + } + + IPAddress localIP() { + return TinyGsmIpFromString(getLocalIP()); + } + + /* + * WiFi 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 = "") { gprsDisconnect(); // Set the Bearer for the IP @@ -561,22 +611,6 @@ public: return true; } - String getLocalIP() { - sendAT(GF("+CIFSR;E0")); - String res; - if (waitResponse(10000L, res) != 1) { - return ""; - } - res.replace(GSM_NL "OK" GSM_NL, ""); - res.replace(GSM_NL, ""); - res.trim(); - return res; - } - - IPAddress localIP() { - return TinyGsmIpFromString(getLocalIP()); - } - /* * Messaging functions */ @@ -668,6 +702,7 @@ public: /* * Battery functions */ + // Use: float vBatt = modem.getBattVoltage() / 1000.0; uint16_t getBattVoltage() { sendAT(GF("+CBC")); @@ -812,7 +847,7 @@ public: streamWrite("AT", cmd..., GSM_NL); stream.flush(); TINY_GSM_YIELD(); - //DBG("### AT:", cmd...); + // DBG("### AT:", cmd...); } // TODO: Optimize this! diff --git a/src/TinyGsmClientSIM808.h b/src/TinyGsmClientSIM808.h index 2b9c49a..b49ab85 100644 --- a/src/TinyGsmClientSIM808.h +++ b/src/TinyGsmClientSIM808.h @@ -11,6 +11,13 @@ #include + +//============================================================================// +//============================================================================// +// Declaration and Definitio of the TinyGsmSim808 Class +//============================================================================// +//============================================================================// + class TinyGsmSim808: public TinyGsmSim800 { diff --git a/src/TinyGsmClientU201.h b/src/TinyGsmClientU201.h index 64d6f2a..f5b2a35 100644 --- a/src/TinyGsmClientU201.h +++ b/src/TinyGsmClientU201.h @@ -9,7 +9,7 @@ #ifndef TinyGsmClientU201_h #define TinyGsmClientU201_h -//#define TINY_GSM_DEBUG Serial +// #define TINY_GSM_DEBUG Serial #if !defined(TINY_GSM_RX_BUFFER) #define TINY_GSM_RX_BUFFER 64 @@ -39,9 +39,22 @@ enum RegStatus { }; +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmU201 Class +//============================================================================// +//============================================================================// + class TinyGsmU201 { +//============================================================================// +//============================================================================// +// The U201 Client Class +//============================================================================// +//============================================================================// + + public: class GsmClient : public Client @@ -169,6 +182,13 @@ private: RxFifo rx; }; +//============================================================================// +//============================================================================// +// The Secure U201 Client Class +//============================================================================// +//============================================================================// + + class GsmClientSecure : public GsmClient { public: @@ -188,6 +208,13 @@ public: } }; + +//============================================================================// +//============================================================================// +// The U201 Modem Functions +//============================================================================// +//============================================================================// + public: #ifdef GSM_DEFAULT_STREAM @@ -258,6 +285,10 @@ public: return waitResponse() == 1; } + String getModemInfo() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool hasSSL() { return true; } + /* * Power functions */ @@ -276,6 +307,10 @@ public: bool poweroff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool sleepEnable(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED; + /* * SIM card functions */ @@ -326,17 +361,6 @@ public: return SIM_ERROR; } - RegStatus getRegistrationStatus() { - sendAT(GF("+CGREG?")); - if (waitResponse(GF(GSM_NL "+CGREG:")) != 1) { - return REG_UNKNOWN; - } - streamSkipUntil(','); // Skip format (0) - int status = stream.readStringUntil('\n').toInt(); - waitResponse(); - return (RegStatus)status; - } - String getOperator() { sendAT(GF("+COPS?")); if (waitResponse(GF(GSM_NL "+COPS:")) != 1) { @@ -352,6 +376,17 @@ public: * Generic network functions */ + RegStatus getRegistrationStatus() { + sendAT(GF("+CGREG?")); + if (waitResponse(GF(GSM_NL "+CGREG:")) != 1) { + return REG_UNKNOWN; + } + streamSkipUntil(','); // Skip format (0) + int status = stream.readStringUntil('\n').toInt(); + waitResponse(); + return (RegStatus)status; + } + int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { @@ -377,10 +412,28 @@ public: return false; } + String getLocalIP() { + sendAT(GF("+CIFSR;E0")); + String res; + if (waitResponse(10000L, res) != 1) { + return ""; + } + res.trim(); + return res; + } + + IPAddress localIP() { + return TinyGsmIpFromString(getLocalIP()); + } + + /* + * WiFi 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 = "") { gprsDisconnect(); sendAT(GF("+CGATT=1")); @@ -441,19 +494,6 @@ public: return true; } - String getLocalIP() { - sendAT(GF("+CIFSR;E0")); - String res; - if (waitResponse(10000L, res) != 1) { - return ""; - } - res.trim(); - return res; - } - - IPAddress localIP() { - return TinyGsmIpFromString(getLocalIP()); - } /* * Messaging functions */ @@ -483,6 +523,7 @@ public: /* * Battery functions */ + // Use: float vBatt = modem.getBattVoltage() / 1000.0; uint16_t getBattVoltage() { sendAT(GF("+CIND")); @@ -611,7 +652,7 @@ public: streamWrite("AT", cmd..., GSM_NL); stream.flush(); TINY_GSM_YIELD(); - //DBG("### AT:", cmd...); + // DBG("### AT:", cmd...); } // TODO: Optimize this! @@ -632,7 +673,7 @@ public: TINY_GSM_YIELD(); while (stream.available() > 0) { int a = stream.read(); - if (a < 0) continue; + if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { index = 1; diff --git a/src/TinyGsmClientXBee.h b/src/TinyGsmClientXBee.h index 60be866..c1c8ff9 100644 --- a/src/TinyGsmClientXBee.h +++ b/src/TinyGsmClientXBee.h @@ -11,9 +11,6 @@ // #define TINY_GSM_DEBUG Serial -#if !defined(TINY_GSM_RX_BUFFER) - #define TINY_GSM_RX_BUFFER 64 -#endif #define TINY_GSM_MUX_COUNT 1 // Multi-plexing isn't supported using command mode @@ -29,24 +26,36 @@ enum SimStatus { SIM_LOCKED = 2, }; -enum XBeeType { - XBEE_CELL = 0, - XBEE_WIFI = 1, -}; - enum RegStatus { REG_UNREGISTERED = 0, REG_SEARCHING = 2, REG_DENIED = 3, - REG_OK_HOME = 1, - REG_OK_ROAMING = 5, + REG_OK = 1, REG_UNKNOWN = 4, }; +enum XBeeType { + XBEE_CELL = 0, + XBEE_WIFI = 1, +}; + + +//============================================================================// +//============================================================================// +// Declaration of the TinyGsmXBee Class +//============================================================================// +//============================================================================// class TinyGsmXBee { +//============================================================================// +//============================================================================// +// The XBee Client Class +//============================================================================// +//============================================================================// + + public: class GsmClient : public Client @@ -116,7 +125,6 @@ public: virtual size_t write(const uint8_t *buf, size_t size) { TINY_GSM_YIELD(); - //at->maintain(); return at->modemSend(buf, size, mux); } @@ -162,6 +170,13 @@ private: bool sock_connected; }; +//============================================================================// +//============================================================================// +// The Secure XBee Client Class +//============================================================================// +//============================================================================// + + class GsmClientSecure : public GsmClient { public: @@ -197,6 +212,13 @@ public: } }; + +//============================================================================// +//============================================================================// +// The XBee Modem Functions +//============================================================================// +//============================================================================// + public: #ifdef GSM_DEFAULT_STREAM @@ -205,9 +227,7 @@ public: TinyGsmXBee(Stream& stream) #endif : stream(stream) - { - memset(sockets, 0, sizeof(sockets)); - } + {} /* * Basic functions @@ -290,6 +310,17 @@ public: return ret_val; } + String getModemInfo() { + String modemInf = ""; + if (!commandMode()) return modemInf; // Try up to 10 times for the init + + sendAT(GF("HS")); // Get the "Hardware Series" + modemInf += readResponse(); + + exitCommand(); + return modemInf; + } + bool hasSSL() { if (beeType == XBEE_WIFI) return false; else return true; @@ -349,6 +380,12 @@ public: exitCommand(); } + bool poweroff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool sleepEnable() TINY_GSM_ATTR_NOT_IMPLEMENTED; + /* * SIM card functions */ @@ -377,65 +414,83 @@ public: return SIM_READY; // unsupported } + String getOperator() { + if (!commandMode()) return ""; // Return immediately + sendAT(GF("MN")); + String res = readResponse(); + exitCommand(); + return res; + } + + /* + * Generic network functions + */ + RegStatus getRegistrationStatus() { if (!commandMode()) return REG_UNKNOWN; // Return immediately sendAT(GF("AI")); String res = readResponse(); - RegStatus stat; + char buf[3] = {0,}; // Set up buffer for response + res.toCharArray(buf, 3); + int intRes = strtol(buf, 0, 16); + RegStatus stat = REG_UNKNOWN; switch (beeType){ case XBEE_WIFI: { - if(res == GF("0")) // 0x00 Successfully joined an access point, established IP addresses and IP listening sockets - stat = REG_OK_HOME; - else if(res == GF("1")) // 0x01 Wi-Fi transceiver initialization in progress. + if(intRes == 0x00) // 0x00 Successfully joined an access point, established IP addresses and IP listening sockets + stat = REG_OK; + else if(intRes == 0x01) // 0x01 Wi-Fi transceiver initialization in progress. stat = REG_SEARCHING; - else if(res == GF("2")) // 0x02 Wi-Fi transceiver initialized, but not yet scanning for access point. + else if(intRes == 0x02) // 0x02 Wi-Fi transceiver initialized, but not yet scanning for access point. stat = REG_SEARCHING; - else if(res == GF("13")) { // 0x13 Disconnecting from access point. - sendAT(GF("NR")); // Do a network reset; the S6B tends to get stuck "disconnecting" + else if(intRes == 0x13) { // 0x13 Disconnecting from access point. + sendAT(GF("NR0")); // Do a network reset; the S6B tends to get stuck "disconnecting" + waitResponse(5000); writeChanges(); stat = REG_UNREGISTERED; } - else if(res == GF("23")) // 0x23 SSID not configured. + else if(intRes == 0x23) // 0x23 SSID not configured. stat = REG_UNREGISTERED; - else if(res == GF("24")) // 0x24 Encryption key invalid (either NULL or invalid length for WEP). + else if(intRes == 0x24) // 0x24 Encryption key invalid (either NULL or invalid length for WEP). stat = REG_DENIED; - else if(res == GF("27")) // 0x27 SSID was found, but join failed. + else if(intRes == 0x27) // 0x27 SSID was found, but join failed. stat = REG_DENIED; - else if(res == GF("40")) // 0x40 Waiting for WPA or WPA2 Authentication. + else if(intRes == 0x40) // 0x40 Waiting for WPA or WPA2 Authentication. stat = REG_SEARCHING; - else if(res == GF("41")) // 0x41 Device joined a network and is waiting for IP configuration to complete + else if(intRes == 0x41) // 0x41 Device joined a network and is waiting for IP configuration to complete stat = REG_SEARCHING; - else if(res == GF("42")) // 0x42 Device is joined, IP is configured, and listening sockets are being set up. + else if(intRes == 0x42) // 0x42 Device is joined, IP is configured, and listening sockets are being set up. stat = REG_SEARCHING; - else if(res == GF("FF")) // 0xFF Device is currently scanning for the configured SSID. + else if(intRes == 0xFF) // 0xFF Device is currently scanning for the configured SSID. stat = REG_SEARCHING; else stat = REG_UNKNOWN; break; } case XBEE_CELL: { - if(res == GF("0")) // 0x00 Connected to the Internet. - stat = REG_OK_HOME; - else if(res == GF("22")) // 0x22 Registering to cellular network. + if(intRes == 0x00) // 0x00 Connected to the Internet. + stat = REG_OK; + else if(intRes == 0x22) // 0x22 Registering to cellular network. stat = REG_SEARCHING; - else if(res == GF("23")) // 0x23 Connecting to the Internet. + else if(intRes == 0x23) // 0x23 Connecting to the Internet. stat = REG_SEARCHING; - else if(res == GF("24")) // 0x24 The cellular component is missing, corrupt, or otherwise in error. + else if(intRes == 0x24) // 0x24 The cellular component is missing, corrupt, or otherwise in error. stat = REG_UNKNOWN; - else if(res == GF("25")) // 0x25 Cellular network registration denied. + else if(intRes == 0x25) // 0x25 Cellular network registration denied. stat = REG_DENIED; - else if(res == GF("2A")) { // 0x2A Airplane mode. + else if(intRes == 0x2A) { // 0x2A Airplane mode. sendAT(GF("AM0")); // Turn off airplane mode + waitResponse(); writeChanges(); stat = REG_UNKNOWN; } - else if(res == GF("2F")) { // 0x2F Bypass mode active. + else if(intRes == 0x2F) { // 0x2F Bypass mode active. sendAT(GF("AP0")); // Set back to transparent mode + waitResponse(); writeChanges(); stat = REG_UNKNOWN; } - else if(res == GF("FF")) // 0xFF Device is currently scanning for the configured SSID. + else if(intRes == 0xFF) // 0xFF Device is currently scanning for the configured SSID. stat = REG_SEARCHING; else stat = REG_UNKNOWN; break; @@ -446,18 +501,6 @@ public: return stat; } - String getOperator() { - if (!commandMode()) return ""; // Return immediately - sendAT(GF("MN")); - String res = readResponse(); - exitCommand(); - return res; - } - - /* - * Generic network functions - */ - int getSignalQuality() { if (!commandMode()) return 0; // Return immediately if (beeType == XBEE_WIFI) sendAT(GF("LM")); // ask for the "link margin" - the dB above sensitivity @@ -473,19 +516,42 @@ public: bool isNetworkConnected() { RegStatus s = getRegistrationStatus(); - return (s == REG_OK_HOME || s == REG_OK_ROAMING); + return (s == REG_OK); } bool waitForNetwork(unsigned long timeout = 60000L) { + commandMode(); for (unsigned long start = millis(); millis() - start < timeout; ) { - if (isNetworkConnected()) { + sendAT(GF("AI")); + String res = readResponse(); + char buf[3] = {0,}; // Set up buffer for response + res.toCharArray(buf, 3); + int intRes = strtol(buf, 0, 16); + if (intRes == 0) { + exitCommand(); return true; } delay(250); } + exitCommand(); return false; } + String getLocalIP() { + if (!commandMode()) return ""; // Return immediately + sendAT(GF("MY")); + String IPaddr; IPaddr.reserve(16); + // wait for the response - this response can be very slow + IPaddr = readResponse(30000); + exitCommand(); + IPaddr.trim(); + return IPaddr; + } + + IPAddress localIP() { + return TinyGsmIpFromString(getLocalIP()); + } + /* * WiFi functions */ @@ -513,27 +579,18 @@ fail: } bool networkDisconnect() { - return false; // Doesn't support disconnecting - } - - String getLocalIP() { - if (!commandMode()) return ""; // Return immediately - sendAT(GF("MY")); - String IPaddr; IPaddr.reserve(16); - // wait for the response - this response can be very slow - IPaddr = readResponse(30000); + if (!commandMode()) return false; // return immediately + sendAT(GF("NR0")); // Do a network reset in order to disconnect + int res = (1 == waitResponse(5000)); + writeChanges(); exitCommand(); - return IPaddr; - } - - IPAddress localIP() { - return TinyGsmIpFromString(getLocalIP()); + return res; } /* * GPRS functions */ - bool gprsConnect(const char* apn, const char* user = "", const char* pw = "") { + bool gprsConnect(const char* apn, const char* user = "", const char* pwd = "") { if (!commandMode()) return false; // Return immediately sendAT(GF("AN"), apn); // Set the APN waitResponse(); @@ -542,19 +599,29 @@ fail: return true; } - bool gprsDisconnect() { // TODO - return false; + bool gprsDisconnect() { + if (!commandMode()) return false; // return immediately + sendAT(GF("AM1")); // Cheating and disconnecting by turning on airplane mode + int res = (1 == waitResponse(5000)); + writeChanges(); + sendAT(GF("AM0")); // Airplane mode off + waitResponse(5000); + writeChanges(); + exitCommand(); + return res; + } + + bool isGprsConnected() { + return isNetworkConnected(); } /* * Messaging functions */ - void sendUSSD() { - } + void sendUSSD() TINY_GSM_ATTR_NOT_AVAILABLE; - void sendSMS() { - } + void sendSMS() TINY_GSM_ATTR_NOT_IMPLEMENTED; bool sendSMS(const String& number, const String& text) { if (!commandMode()) return false; // Return immediately @@ -577,6 +644,21 @@ fail: return false; } + /* + * Location functions + */ + + String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE; + + /* + * Battery functions + */ + + uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE; + + int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE; + +protected: private: @@ -590,8 +672,9 @@ private: { sendAT(GF("LA"), host); while (stream.available() < 4) {}; // wait for any response - strIP = streamReadUntil('\r'); // read result - // DBG("<<< ", strIP); + strIP = stream.readStringUntil('\r'); // read result + strIP.trim(); + DBG("<<< ", strIP); if (!strIP.endsWith(GF("ERROR"))) gotIP = true; delay(100); // short wait before trying again } @@ -644,29 +727,9 @@ public: /* Utilities */ - template - void streamWrite(T last) { - stream.print(last); - } - - template - void streamWrite(T head, Args... tail) { - stream.print(head); - streamWrite(tail...); - } - - int streamRead() { return stream.read(); } - - String streamReadUntil(char c) { - TINY_GSM_YIELD(); - String return_string = stream.readStringUntil(c); - return_string.trim(); - return return_string; - } - void streamClear(void) { TINY_GSM_YIELD(); - while (stream.available()) { streamRead(); } + while (stream.available()) { stream.read(); } } bool commandMode(int retries = 2) { @@ -677,8 +740,8 @@ public: // Cannot send anything for 1 "guard time" before entering command mode // Default guard time is 1s, but the init fxn decreases it to 250 ms delay(guardTime); - streamWrite(GF("+++")); // enter command mode - // DBG("\r\n+++"); + stream.print(GF("+++")); // enter command mode + DBG("\r\n+++"); success = (1 == waitResponse(guardTime*2)); triesMade ++; } @@ -699,16 +762,18 @@ public: } String readResponse(uint32_t timeout = 1000) { + TINY_GSM_YIELD(); unsigned long startMillis = millis(); while (!stream.available() && millis() - startMillis < timeout) {}; - String res = streamReadUntil('\r'); // lines end with carriage returns - // DBG("<<< ", res); + String res = stream.readStringUntil('\r'); // lines end with carriage returns + res.trim(); + DBG("<<< ", res); return res; } template void sendAT(Args... cmd) { - streamWrite("AT", cmd..., GSM_NL); + stream.print("AT", cmd..., GSM_NL); stream.flush(); TINY_GSM_YIELD(); // DBG("### AT:", cmd...); @@ -731,7 +796,7 @@ public: do { TINY_GSM_YIELD(); while (stream.available() > 0) { - int a = streamRead(); + int a = stream.read(); if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { @@ -767,7 +832,7 @@ finish: data.replace(GSM_NL GSM_NL, GSM_NL); data.replace(GSM_NL, "\r\n "); if (data.length()) { - // DBG("<<< ", data); + DBG("<<< ", data); } } return index; @@ -787,7 +852,7 @@ finish: return waitResponse(1000, r1, r2, r3, r4, r5); } -private: +protected: int guardTime; XBeeType beeType; Stream& stream;