Split SIM7000, add SIM7070, NTP
Signed-off-by: Sara Damiano <sdamiano@stroudcenter.org>
This commit is contained in:
646
src/TinyGsmClientSIM7000SSL.h
Normal file
646
src/TinyGsmClientSIM7000SSL.h
Normal file
@@ -0,0 +1,646 @@
|
||||
/**
|
||||
* @file TinyGsmClientSim7000SSL.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license LGPL-3.0
|
||||
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||
* @date Nov 2016
|
||||
*/
|
||||
|
||||
#ifndef SRC_TINYGSMCLIENTSIM7000SSL_H_
|
||||
#define SRC_TINYGSMCLIENTSIM7000SSL_H_
|
||||
|
||||
// #define TINY_GSM_DEBUG Serial
|
||||
// #define TINY_GSM_USE_HEX
|
||||
|
||||
#define TINY_GSM_MUX_COUNT 2
|
||||
#define TINY_GSM_BUFFER_READ_AND_CHECK_SIZE
|
||||
|
||||
#include "TinyGsmClientSIM70xx.h"
|
||||
#include "TinyGsmTCP.tpp"
|
||||
#include "TinyGsmSSL.tpp"
|
||||
|
||||
class TinyGsmSim7000SSL
|
||||
: public TinyGsmSim70xx<TinyGsmSim7000SSL>,
|
||||
public TinyGsmTCP<TinyGsmSim7000SSL, TINY_GSM_MUX_COUNT>,
|
||||
public TinyGsmSSL<TinyGsmSim7000SSL> {
|
||||
friend class TinyGsmSim70xx<TinyGsmSim7000SSL>;
|
||||
friend class TinyGsmTCP<TinyGsmSim7000SSL, TINY_GSM_MUX_COUNT>;
|
||||
friend class TinyGsmSSL<TinyGsmSim7000SSL>;
|
||||
|
||||
/*
|
||||
* Inner Client
|
||||
*/
|
||||
public:
|
||||
class GsmClientSim7000SSL : public GsmClient {
|
||||
friend class TinyGsmSim7000SSL;
|
||||
|
||||
public:
|
||||
GsmClientSim7000SSL() {}
|
||||
|
||||
explicit GsmClientSim7000SSL(TinyGsmSim7000SSL& modem, uint8_t mux = 0) {
|
||||
init(&modem, mux);
|
||||
}
|
||||
|
||||
bool init(TinyGsmSim7000SSL* modem, uint8_t mux = 0) {
|
||||
this->at = modem;
|
||||
sock_available = 0;
|
||||
prev_check = 0;
|
||||
sock_connected = false;
|
||||
got_data = false;
|
||||
|
||||
if (mux < TINY_GSM_MUX_COUNT) {
|
||||
this->mux = mux;
|
||||
} else {
|
||||
this->mux = (mux % TINY_GSM_MUX_COUNT);
|
||||
}
|
||||
at->sockets[this->mux] = this;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int connect(const char* host, uint16_t port, int timeout_s) {
|
||||
stop();
|
||||
TINY_GSM_YIELD();
|
||||
rx.clear();
|
||||
sock_connected = at->modemConnect(host, port, mux, false, timeout_s);
|
||||
return sock_connected;
|
||||
}
|
||||
TINY_GSM_CLIENT_CONNECT_OVERRIDES
|
||||
|
||||
void stop(uint32_t maxWaitMs) {
|
||||
dumpModemBuffer(maxWaitMs);
|
||||
at->sendAT(GF("+CACLOSE="), mux);
|
||||
sock_connected = false;
|
||||
at->waitResponse(3000);
|
||||
}
|
||||
void stop() override {
|
||||
stop(15000L);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extended API
|
||||
*/
|
||||
|
||||
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||
};
|
||||
|
||||
/*
|
||||
* Inner Secure Client
|
||||
*/
|
||||
|
||||
class GsmClientSecureSIM7000SSL : public GsmClientSim7000SSL {
|
||||
public:
|
||||
GsmClientSecureSIM7000SSL() {}
|
||||
|
||||
GsmClientSecureSIM7000SSL(TinyGsmSim7000SSL& modem, uint8_t mux = 0)
|
||||
: GsmClientSim7000SSL(modem, mux) {}
|
||||
|
||||
public:
|
||||
bool setCertificate(const String& certificateName) {
|
||||
return at->setCertificate(certificateName, mux);
|
||||
}
|
||||
|
||||
int connect(const char* host, uint16_t port, int timeout_s) {
|
||||
stop();
|
||||
TINY_GSM_YIELD();
|
||||
rx.clear();
|
||||
sock_connected = at->modemConnect(host, port, mux, true, timeout_s);
|
||||
return sock_connected;
|
||||
}
|
||||
TINY_GSM_CLIENT_CONNECT_OVERRIDES
|
||||
};
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public:
|
||||
explicit TinyGsmSim7000SSL(Stream& stream)
|
||||
: TinyGsmSim70xx<TinyGsmSim7000SSL>(stream),
|
||||
certificates() {
|
||||
memset(sockets, 0, sizeof(sockets));
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic functions
|
||||
*/
|
||||
protected:
|
||||
bool initImpl(const char* pin = NULL) {
|
||||
DBG(GF("### TinyGSM Version:"), TINYGSM_VERSION);
|
||||
DBG(GF("### TinyGSM Compiled Module: TinyGsmClientSIM7000SSL"));
|
||||
|
||||
if (!testAT()) { return false; }
|
||||
|
||||
sendAT(GF("E0")); // Echo Off
|
||||
if (waitResponse() != 1) { return false; }
|
||||
|
||||
#ifdef TINY_GSM_DEBUG
|
||||
sendAT(GF("+CMEE=2")); // turn on verbose error codes
|
||||
#else
|
||||
sendAT(GF("+CMEE=0")); // turn off error codes
|
||||
#endif
|
||||
waitResponse();
|
||||
|
||||
DBG(GF("### Modem:"), getModemName());
|
||||
|
||||
// Enable Local Time Stamp for getting network time
|
||||
sendAT(GF("+CLTS=1"));
|
||||
if (waitResponse(10000L) != 1) { return false; }
|
||||
|
||||
// Enable battery checks
|
||||
sendAT(GF("+CBATCHK=1"));
|
||||
if (waitResponse() != 1) { return false; }
|
||||
|
||||
SimStatus ret = getSimStatus();
|
||||
// if the sim isn't ready and a pin has been provided, try to unlock the sim
|
||||
if (ret != SIM_READY && pin != NULL && strlen(pin) > 0) {
|
||||
simUnlock(pin);
|
||||
return (getSimStatus() == SIM_READY);
|
||||
} else {
|
||||
// if the sim is ready, or it's locked but no pin has been provided,
|
||||
// return true
|
||||
return (ret == SIM_READY || ret == SIM_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Power functions
|
||||
*/
|
||||
protected:
|
||||
// Follows the SIM70xx template
|
||||
|
||||
/*
|
||||
* Generic network functions
|
||||
*/
|
||||
protected:
|
||||
String getLocalIPImpl() {
|
||||
sendAT(GF("+CNACT?"));
|
||||
if (waitResponse(GF(GSM_NL "+CNACT:")) != 1) { return ""; }
|
||||
streamSkipUntil('\"');
|
||||
String res = stream.readStringUntil('\"');
|
||||
waitResponse();
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Secure socket layer functions
|
||||
*/
|
||||
protected:
|
||||
bool setCertificate(const String& certificateName, const uint8_t mux = 0) {
|
||||
if (mux >= TINY_GSM_MUX_COUNT) return false;
|
||||
certificates[mux] = certificateName;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPRS functions
|
||||
*/
|
||||
protected:
|
||||
bool gprsConnectImpl(const char* apn, const char* user = NULL,
|
||||
const char* pwd = NULL) {
|
||||
gprsDisconnect();
|
||||
|
||||
// Bearer settings for applications based on IP
|
||||
// Set the connection type to GPRS
|
||||
sendAT(GF("+SAPBR=3,1,\"Contype\",\"GPRS\""));
|
||||
waitResponse();
|
||||
|
||||
// Set the APN
|
||||
sendAT(GF("+SAPBR=3,1,\"APN\",\""), apn, '"');
|
||||
waitResponse();
|
||||
|
||||
// Set the user name
|
||||
if (user && strlen(user) > 0) {
|
||||
sendAT(GF("+SAPBR=3,1,\"USER\",\""), user, '"');
|
||||
waitResponse();
|
||||
}
|
||||
// Set the password
|
||||
if (pwd && strlen(pwd) > 0) {
|
||||
sendAT(GF("+SAPBR=3,1,\"PWD\",\""), pwd, '"');
|
||||
waitResponse();
|
||||
}
|
||||
|
||||
// Define the PDP context
|
||||
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
|
||||
waitResponse();
|
||||
|
||||
// Attach to GPRS
|
||||
sendAT(GF("+CGATT=1"));
|
||||
if (waitResponse(60000L) != 1) { return false; }
|
||||
|
||||
// Activate the PDP context
|
||||
sendAT(GF("+CGACT=1,1"));
|
||||
waitResponse(60000L);
|
||||
|
||||
// Open the definied GPRS bearer context
|
||||
sendAT(GF("+SAPBR=1,1"));
|
||||
waitResponse(85000L);
|
||||
// Query the GPRS bearer context status
|
||||
sendAT(GF("+SAPBR=2,1"));
|
||||
if (waitResponse(30000L) != 1) { return false; }
|
||||
|
||||
// Bearer settings for applications based on IP
|
||||
// Set the user name and password
|
||||
// AT+CNCFG=<ip_type>[,<APN>[,<usename>,<password>[,<authentication>]]]
|
||||
//<ip_type> 0: Dual PDN Stack
|
||||
// 1: Internet Protocol Version 4
|
||||
// 2: Internet Protocol Version 6
|
||||
//<authentication> 0: NONE
|
||||
// 1: PAP
|
||||
// 2: CHAP
|
||||
// 3: PAP or CHAP
|
||||
if (pwd && strlen(pwd) > 0 && user && strlen(user) > 0) {
|
||||
sendAT(GF("+CNCFG=1,\""), apn, "\",\"", "\",\"", user, pwd, '"');
|
||||
waitResponse();
|
||||
} else if (user && strlen(user) > 0) {
|
||||
// Set the user name only
|
||||
sendAT(GF("+CNCFG=1,\""), apn, "\",\"", user, '"');
|
||||
waitResponse();
|
||||
} else {
|
||||
// Set the APN only
|
||||
sendAT(GF("+CNCFG=1,\""), apn, '"');
|
||||
waitResponse();
|
||||
}
|
||||
|
||||
// Activate application network connection
|
||||
// This is for most other supported applications outside of the
|
||||
// TCP application toolkit (ie, SSL)
|
||||
// AT+CNACT=<mode>,<action>
|
||||
// <mode> 0: Deactive
|
||||
// 1: Active
|
||||
// 2: Auto Active
|
||||
int res = 0;
|
||||
int ntries = 0;
|
||||
while (res != 1 && ntries < 5) {
|
||||
sendAT(GF("+CNACT=1,\""), apn, GF("\""));
|
||||
res = waitResponse(60000L, GF(GSM_NL "+APP PDP: ACTIVE"),
|
||||
GF(GSM_NL "+APP PDP: DEACTIVE"));
|
||||
waitResponse();
|
||||
ntries++;
|
||||
}
|
||||
|
||||
// return res == 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gprsDisconnectImpl() {
|
||||
// Shut down the general application TCP/IP connection
|
||||
// CNACT will close *all* open application connections
|
||||
sendAT(GF("+CNACT=0"));
|
||||
if (waitResponse(60000L) != 1) { return false; }
|
||||
|
||||
sendAT(GF("+CGATT=0")); // Deactivate the bearer context
|
||||
if (waitResponse(60000L) != 1) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* SIM card functions
|
||||
*/
|
||||
protected:
|
||||
// Follows the SIM70xx template
|
||||
|
||||
/*
|
||||
* Messaging functions
|
||||
*/
|
||||
protected:
|
||||
// Follows all messaging functions per template
|
||||
|
||||
/*
|
||||
* GPS/GNSS/GLONASS location functions
|
||||
*/
|
||||
protected:
|
||||
// Follows the SIM70xx template
|
||||
|
||||
/*
|
||||
* Time functions
|
||||
*/
|
||||
// Can follow CCLK as per template
|
||||
|
||||
/*
|
||||
* NTP server functions
|
||||
*/
|
||||
// Can sync with server using CNTP as per template
|
||||
|
||||
/*
|
||||
* Battery functions
|
||||
*/
|
||||
protected:
|
||||
// Follows all battery functions per template
|
||||
|
||||
/*
|
||||
* Client related functions
|
||||
*/
|
||||
protected:
|
||||
bool modemConnect(const char* host, uint16_t port, uint8_t mux,
|
||||
bool ssl = false, int timeout_s = 75) {
|
||||
uint32_t timeout_ms = ((uint32_t)timeout_s) * 1000;
|
||||
|
||||
// set the connection (mux) identifier to use
|
||||
sendAT(GF("+CACID="), mux);
|
||||
if (waitResponse(timeout_ms) != 1) return false;
|
||||
|
||||
|
||||
if (ssl) {
|
||||
// set the ssl version
|
||||
sendAT(GF("+CSSLCFG=\"sslversion\",0,3")); // TLS 1.2
|
||||
if (waitResponse(5000L) != 1) return false;
|
||||
|
||||
// set the PDP context to apply SSL to
|
||||
sendAT(GF("+CSSLCFG=\"ctxindex\",0"));
|
||||
if (waitResponse(5000L, GF("+CSSLCFG:")) != 1) return false;
|
||||
streamSkipUntil('\n'); // read out the certificate information
|
||||
waitResponse();
|
||||
|
||||
if (certificates[mux] != "") {
|
||||
// apply the correct certificate to the connection
|
||||
sendAT(GF("+CASSLCFG="), mux, ",CACERT,\"", certificates[mux].c_str(),
|
||||
"\"");
|
||||
if (waitResponse(5000L) != 1) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// enable or disable ssl
|
||||
sendAT(GF("+CASSLCFG="), mux, ',', GF("ssl,"), ssl);
|
||||
waitResponse();
|
||||
|
||||
// set the protocol
|
||||
// 0: TCP; 1: UDP
|
||||
sendAT(GF("+CASSLCFG="), mux, ',', GF("protocol,0"));
|
||||
waitResponse();
|
||||
|
||||
// set the SSL SNI (server name indication)
|
||||
sendAT(GF("+CSSLCFG=\"sni\","), mux, ',', GF("\""), host, GF("\""));
|
||||
waitResponse();
|
||||
|
||||
// actually open the connection
|
||||
// AT+CAOPEN=<cid>[,<conn_type>],<server>,<port>
|
||||
// <cid> TCP/UDP identifier
|
||||
// <conn_type> "TCP" or "UDP"
|
||||
sendAT(GF("+CAOPEN="), mux, GF(",\"TCP\",\""), host, GF("\","), port);
|
||||
if (waitResponse(timeout_ms, GF(GSM_NL "+CAOPEN:")) != 1) { return 0; }
|
||||
// returns OK/r/n/r/n+CAOPEN: <cid>,<result>
|
||||
// <result> 0: Success
|
||||
// 1: Socket error
|
||||
// 2: No memory
|
||||
// 3: Connection limit
|
||||
// 4: Parameter invalid
|
||||
// 6: Invalid IP address
|
||||
// 7: Not support the function
|
||||
// 12: Can’t bind the port
|
||||
// 13: Can’t listen the port
|
||||
// 20: Can’t resolv the host
|
||||
// 21: Network not active
|
||||
// 23: Remote refuse
|
||||
// 24: Certificate’s time expired
|
||||
// 25: Certificate’s common name does not match
|
||||
// 26: Certificate’s common name does not match and time expired
|
||||
// 27: Connect failed
|
||||
streamSkipUntil(','); // Skip mux
|
||||
|
||||
// make sure the connection really opened
|
||||
int8_t res = streamGetIntBefore('\n');
|
||||
waitResponse();
|
||||
|
||||
return 0 == res;
|
||||
}
|
||||
|
||||
int16_t modemSend(const void* buff, size_t len, uint8_t mux) {
|
||||
sendAT(GF("+CASEND="), mux, ',', (uint16_t)len);
|
||||
if (waitResponse(GF(">")) != 1) { return 0; }
|
||||
|
||||
stream.write(reinterpret_cast<const uint8_t*>(buff), len);
|
||||
stream.flush();
|
||||
|
||||
if (waitResponse(GF(GSM_NL "+CASEND:")) != 1) { return 0; }
|
||||
streamSkipUntil(','); // Skip mux
|
||||
if (streamGetIntBefore(',') != 0) { return 0; } // If result != success
|
||||
return streamGetIntBefore('\n');
|
||||
}
|
||||
|
||||
size_t modemRead(size_t size, uint8_t mux) {
|
||||
if (!sockets[mux]) return 0;
|
||||
|
||||
sendAT(GF("+CARECV="), mux, ',', (uint16_t)size);
|
||||
|
||||
if (waitResponse(GF("+CARECV:")) != 1) {
|
||||
sockets[mux]->sock_available = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream.read();
|
||||
if (stream.peek() == '0') {
|
||||
waitResponse();
|
||||
sockets[mux]->sock_available = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int16_t len_confirmed = streamGetIntBefore(',');
|
||||
if (len_confirmed <= 0) {
|
||||
sockets[mux]->sock_available = 0;
|
||||
waitResponse();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len_confirmed; i++) {
|
||||
uint32_t startMillis = millis();
|
||||
while (!stream.available() &&
|
||||
(millis() - startMillis < sockets[mux]->_timeout)) {
|
||||
TINY_GSM_YIELD();
|
||||
}
|
||||
char c = stream.read();
|
||||
sockets[mux]->rx.put(c);
|
||||
}
|
||||
// DBG("### READ:", len_requested, "from", mux);
|
||||
// sockets[mux]->sock_available = modemGetAvailable(mux);
|
||||
auto diff = int64_t(size) - int64_t(len_confirmed);
|
||||
if (diff < 0) diff = 0;
|
||||
sockets[mux]->sock_available = diff;
|
||||
waitResponse();
|
||||
return len_confirmed;
|
||||
}
|
||||
|
||||
size_t modemGetAvailable(uint8_t mux) {
|
||||
if (!sockets[mux]) return 0;
|
||||
|
||||
sendAT(GF("+CARECV?"));
|
||||
|
||||
int8_t readMux = -1;
|
||||
size_t result = 0;
|
||||
while (readMux != mux) {
|
||||
if (waitResponse(GF("+CARECV:")) != 1) {
|
||||
sockets[mux]->sock_connected = modemGetConnected(mux);
|
||||
return 0;
|
||||
};
|
||||
readMux = streamGetIntBefore(',');
|
||||
result = streamGetIntBefore('\n');
|
||||
}
|
||||
waitResponse();
|
||||
// DBG("### Available:", result, "on", mux);
|
||||
if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); }
|
||||
return result;
|
||||
}
|
||||
|
||||
bool modemGetConnected(uint8_t mux) {
|
||||
sendAT(GF("+CASTATE?"));
|
||||
int8_t readMux = -1;
|
||||
while (readMux != mux) {
|
||||
if (waitResponse(3000, GF("+CASTATE:"), GFP(GSM_OK)) != 1) { return 0; }
|
||||
readMux = streamGetIntBefore(',');
|
||||
}
|
||||
int8_t res = streamGetIntBefore('\n');
|
||||
waitResponse();
|
||||
return 1 == res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
public:
|
||||
// TODO(vshymanskyy): Optimize this!
|
||||
int8_t waitResponse(uint32_t timeout_ms, String& data,
|
||||
GsmConstStr r1 = GFP(GSM_OK),
|
||||
GsmConstStr r2 = GFP(GSM_ERROR),
|
||||
#if defined TINY_GSM_DEBUG
|
||||
GsmConstStr r3 = GFP(GSM_CME_ERROR),
|
||||
GsmConstStr r4 = GFP(GSM_CMS_ERROR),
|
||||
#else
|
||||
GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,
|
||||
#endif
|
||||
GsmConstStr r5 = NULL) {
|
||||
/*String r1s(r1); r1s.trim();
|
||||
String r2s(r2); r2s.trim();
|
||||
String r3s(r3); r3s.trim();
|
||||
String r4s(r4); r4s.trim();
|
||||
String r5s(r5); r5s.trim();
|
||||
DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
|
||||
data.reserve(64);
|
||||
uint8_t index = 0;
|
||||
uint32_t startMillis = millis();
|
||||
do {
|
||||
TINY_GSM_YIELD();
|
||||
while (stream.available() > 0) {
|
||||
TINY_GSM_YIELD();
|
||||
int8_t a = stream.read();
|
||||
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
||||
data += static_cast<char>(a);
|
||||
if (r1 && data.endsWith(r1)) {
|
||||
index = 1;
|
||||
goto finish;
|
||||
} else if (r2 && data.endsWith(r2)) {
|
||||
index = 2;
|
||||
goto finish;
|
||||
} else if (r3 && data.endsWith(r3)) {
|
||||
#if defined TINY_GSM_DEBUG
|
||||
if (r3 == GFP(GSM_CME_ERROR)) {
|
||||
streamSkipUntil('\n'); // Read out the error
|
||||
}
|
||||
#endif
|
||||
index = 3;
|
||||
goto finish;
|
||||
} else if (r4 && data.endsWith(r4)) {
|
||||
index = 4;
|
||||
goto finish;
|
||||
} else if (r5 && data.endsWith(r5)) {
|
||||
index = 5;
|
||||
goto finish;
|
||||
} else if (data.endsWith(GF(GSM_NL "+CARECV:"))) {
|
||||
int8_t mux = streamGetIntBefore(',');
|
||||
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
|
||||
sockets[mux]->got_data = true;
|
||||
}
|
||||
data = "";
|
||||
DBG("### Got Data:", mux);
|
||||
} else if (data.endsWith(GF(GSM_NL "+CADATAIND:"))) {
|
||||
int8_t mux = streamGetIntBefore('\n');
|
||||
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
|
||||
sockets[mux]->got_data = true;
|
||||
}
|
||||
data = "";
|
||||
DBG("### Got Data:", mux);
|
||||
} else if (data.endsWith(GF(GSM_NL "+CASTATE:"))) {
|
||||
int8_t mux = streamGetIntBefore(',');
|
||||
int8_t state = streamGetIntBefore('\n');
|
||||
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
|
||||
if (state != 1) {
|
||||
sockets[mux]->sock_connected = false;
|
||||
DBG("### Closed: ", mux);
|
||||
}
|
||||
}
|
||||
data = "";
|
||||
} else if (data.endsWith(GF("CLOSED" GSM_NL))) {
|
||||
int8_t nl = data.lastIndexOf(GSM_NL, data.length() - 8);
|
||||
int8_t coma = data.indexOf(',', nl + 2);
|
||||
int8_t mux = data.substring(nl + 2, coma).toInt();
|
||||
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
|
||||
sockets[mux]->sock_connected = false;
|
||||
}
|
||||
data = "";
|
||||
DBG("### Closed: ", mux);
|
||||
} else if (data.endsWith(GF("*PSNWID:"))) {
|
||||
streamSkipUntil('\n'); // Refresh network name by network
|
||||
data = "";
|
||||
DBG("### Network name updated.");
|
||||
} else if (data.endsWith(GF("*PSUTTZ:"))) {
|
||||
streamSkipUntil('\n'); // Refresh time and time zone by network
|
||||
data = "";
|
||||
DBG("### Network time and time zone updated.");
|
||||
} else if (data.endsWith(GF("+CTZV:"))) {
|
||||
streamSkipUntil('\n'); // Refresh network time zone by network
|
||||
data = "";
|
||||
DBG("### Network time zone updated.");
|
||||
} else if (data.endsWith(GF("DST: "))) {
|
||||
streamSkipUntil(
|
||||
'\n'); // Refresh Network Daylight Saving Time by network
|
||||
data = "";
|
||||
DBG("### Daylight savings time state updated.");
|
||||
} else if (data.endsWith(GF(GSM_NL "SMS Ready" GSM_NL))) {
|
||||
data = "";
|
||||
DBG("### Unexpected module reset!");
|
||||
init();
|
||||
}
|
||||
}
|
||||
} while (millis() - startMillis < timeout_ms);
|
||||
finish:
|
||||
if (!index) {
|
||||
data.trim();
|
||||
if (data.length()) { DBG("### Unhandled:", data); }
|
||||
data = "";
|
||||
}
|
||||
// data.replace(GSM_NL, "/");
|
||||
// DBG('<', index, '>', data);
|
||||
return index;
|
||||
}
|
||||
|
||||
int8_t waitResponse(uint32_t timeout_ms, GsmConstStr r1 = GFP(GSM_OK),
|
||||
GsmConstStr r2 = GFP(GSM_ERROR),
|
||||
#if defined TINY_GSM_DEBUG
|
||||
GsmConstStr r3 = GFP(GSM_CME_ERROR),
|
||||
GsmConstStr r4 = GFP(GSM_CMS_ERROR),
|
||||
#else
|
||||
GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,
|
||||
#endif
|
||||
GsmConstStr r5 = NULL) {
|
||||
String data;
|
||||
return waitResponse(timeout_ms, data, r1, r2, r3, r4, r5);
|
||||
}
|
||||
|
||||
int8_t waitResponse(GsmConstStr r1 = GFP(GSM_OK),
|
||||
GsmConstStr r2 = GFP(GSM_ERROR),
|
||||
#if defined TINY_GSM_DEBUG
|
||||
GsmConstStr r3 = GFP(GSM_CME_ERROR),
|
||||
GsmConstStr r4 = GFP(GSM_CMS_ERROR),
|
||||
#else
|
||||
GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,
|
||||
#endif
|
||||
GsmConstStr r5 = NULL) {
|
||||
return waitResponse(1000, r1, r2, r3, r4, r5);
|
||||
}
|
||||
|
||||
protected:
|
||||
GsmClientSim7000SSL* sockets[TINY_GSM_MUX_COUNT];
|
||||
String certificates[TINY_GSM_MUX_COUNT];
|
||||
};
|
||||
|
||||
#endif // SRC_TINYGSMCLIENTSIM7000SSL_H_
|
||||
Reference in New Issue
Block a user