diff --git a/.gitignore b/.gitignore index 2b40655e..fb559b64 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ extras/At Command Manuals - Unsupported/* filters/* platformio_extra_envs.ini *.tar.gz +pioScripts/generate_compile_commands.py diff --git a/src/TinyGsmClientA6.h b/src/TinyGsmClientA6.h index d6959faa..008e127f 100644 --- a/src/TinyGsmClientA6.h +++ b/src/TinyGsmClientA6.h @@ -451,115 +451,37 @@ class TinyGsmA6 : public TinyGsmModem, * 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(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("+CIPRCV:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore(','); - int16_t len_orig = len; - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - if (len > sockets[mux]->rx.free()) { - DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); - } else { - DBG("### Got: ", len, "->", sockets[mux]->rx.free()); - } - while (len--) { moveCharFromStreamToFifo(mux); } - // TODO(?) Deal with missing characters - if (len_orig > sockets[mux]->available()) { - DBG("### Fewer characters received than expected: ", - sockets[mux]->available(), " vs ", len_orig); - } - } - data = ""; - } else if (data.endsWith(GF("+TCPCLOSED:"))) { - int8_t mux = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### Closed: ", mux); + bool handleURCs(String& data) { + if (data.endsWith(GF("+CIPRCV:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore(','); + int16_t len_orig = len; + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + // reset the len to read to the amount free + len = sockets[mux]->rx.free(); + } + while (len--) { moveCharFromStreamToFifo(mux); } + // TODO(?) Deal with missing characters + if (len_orig != sockets[mux]->available()) { + DBG("### Different number of characters received than expected: ", + sockets[mux]->available(), " vs ", len_orig); } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + DBG("### Got Data: ", len_orig, "on", mux); + return true; + } else if (data.endsWith(GF("+TCPCLOSED:"))) { + int8_t mux = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientBG96.h b/src/TinyGsmClientBG96.h index b5c45361..4b3b3347 100644 --- a/src/TinyGsmClientBG96.h +++ b/src/TinyGsmClientBG96.h @@ -603,110 +603,30 @@ class TinyGsmBG96 : public TinyGsmModem, * 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(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 "+QIURC:"))) { - streamSkipUntil('\"'); - String urc = stream.readStringUntil('\"'); - streamSkipUntil(','); - if (urc == "recv") { - int8_t mux = streamGetIntBefore('\n'); - DBG("### URC RECV:", mux); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - } - } else if (urc == "closed") { - int8_t mux = streamGetIntBefore('\n'); - DBG("### URC CLOSE:", mux); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - } else { - streamSkipUntil('\n'); - } - data = ""; + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+QIURC:"))) { + streamSkipUntil('\"'); + String urc = stream.readStringUntil('\"'); + streamSkipUntil(','); + if (urc == "recv") { + int8_t mux = streamGetIntBefore('\n'); + DBG("### URC RECV:", mux); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; } + } else if (urc == "closed") { + int8_t mux = streamGetIntBefore('\n'); + DBG("### URC CLOSE:", mux); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + } else { + streamSkipUntil('\n'); } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientESP8266.h b/src/TinyGsmClientESP8266.h index e0ee3412..ff998f8b 100644 --- a/src/TinyGsmClientESP8266.h +++ b/src/TinyGsmClientESP8266.h @@ -24,16 +24,20 @@ static uint8_t TINY_GSM_TCP_KEEP_ALIVE = 120; // status of ESP8266 station interface +// 0: ESP8266 station is not initialized. +// 1: ESP8266 station is initialized, but not started a Wi-Fi connection yet. // 2 : ESP8266 station connected to an AP and has obtained IP // 3 : ESP8266 station created a TCP or UDP transmission // 4 : the TCP or UDP transmission of ESP8266 station disconnected // 5 : ESP8266 station did NOT connect to an AP enum RegStatus { - REG_OK_IP = 2, - REG_OK_TCP = 3, - REG_OK_NO_TCP = 4, - REG_DENIED = 5, - REG_UNKNOWN = 6, + REG_UNINITIALIZED = 0, + REG_UNREGISTERED = 1, + REG_OK_IP = 2, + REG_OK_TCP = 3, + REG_OK_NO_TCP = 4, + REG_DENIED = 5, + REG_UNKNOWN = 6, }; class TinyGsmESP8266 : public TinyGsmModem, @@ -221,9 +225,14 @@ class TinyGsmESP8266 : public TinyGsmModem, RegStatus getRegistrationStatus() { sendAT(GF("+CIPSTATUS")); if (waitResponse(3000, GF("STATUS:")) != 1) return REG_UNKNOWN; - int8_t status = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), - GF("5")); - waitResponse(); // Returns an OK after the status + // after "STATUS:" it should return the status number (0,1,2,3,4,5), + // followed by an OK + // Since there are more possible status number codes than the arguments for + // waitResponse, we'll capture the response in a string and then parse it. + String res; + if (waitResponse(3000L, res) != 1) { return REG_UNKNOWN; } + res.trim(); + int8_t status = res.toInt(); return (RegStatus)status; } @@ -342,11 +351,12 @@ class TinyGsmESP8266 : public TinyGsmModem, bool modemGetConnected(uint8_t mux) { sendAT(GF("+CIPSTATUS")); if (waitResponse(3000, GF("STATUS:")) != 1) { return false; } - int8_t status = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), - GF("5")); - if (status != 3) { - // if the status is anything but 3, there are no connections open - waitResponse(); // Returns an OK after the status + // after "STATUS:" it should return the status number (0,1,2,3,4,5), + // followed by an OK + // Hopefully we'll catch the "3" here, but fall back to the OK or Error + int8_t status = waitResponse(GF("3"), GFP(GSM_OK), GFP(GSM_ERROR)); + // if the status is anything but 3, there are no connections open + if (status != 1) { for (int muxNo = 0; muxNo < TINY_GSM_MUX_COUNT; muxNo++) { if (sockets[muxNo]) { sockets[muxNo]->sock_connected = false; } } @@ -380,96 +390,40 @@ class TinyGsmESP8266 : public TinyGsmModem, * 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), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, 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(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)) { - 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("+IPD,"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore(':'); - int16_t len_orig = len; - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - if (len > sockets[mux]->rx.free()) { - DBG("### Buffer overflow: ", len, "received vs", - sockets[mux]->rx.free(), "available"); - } else { - // DBG("### Got Data: ", len, "on", mux); - } - while (len--) { moveCharFromStreamToFifo(mux); } - // TODO(SRGDamia1): deal with buffer overflow/missed characters - if (len_orig > sockets[mux]->available()) { - DBG("### Fewer characters received than expected: ", - sockets[mux]->available(), " vs ", len_orig); - } - } - data = ""; - } else if (data.endsWith(GF("CLOSED"))) { - int8_t muxStart = - TinyGsmMax(0, data.lastIndexOf(GSM_NL, data.length() - 8)); - int8_t coma = data.indexOf(',', muxStart); - int8_t mux = data.substring(muxStart, coma).toInt(); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### Closed: ", mux); + bool handleURCs(String& data) { + if (data.endsWith(GF("+IPD,"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore(':'); + int16_t len_orig = len; + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + // reset the len to read to the amount free + len = sockets[mux]->rx.free(); } + while (len--) { moveCharFromStreamToFifo(mux); } + // TODO(SRGDamia1): deal with buffer overflow/missed characters + if (len_orig != sockets[mux]->available()) { + DBG("### Different number of characters received than expected: ", + sockets[mux]->available(), " vs ", len_orig); + } + } + data = ""; + DBG("### Got Data: ", len_orig, "on", mux); + return true; + } else if (data.endsWith(GF("CLOSED"))) { + int8_t muxStart = TinyGsmMax(0, + data.lastIndexOf(GSM_NL, data.length() - 8)); + int8_t coma = data.indexOf(',', muxStart); + int8_t mux = data.substring(muxStart, coma).toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + DBG("### Closed: ", mux); + return true; } - // 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), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, 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), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, GsmConstStr r5 = NULL) { - return waitResponse(1000, r1, r2, r3, r4, r5); + return false; } public: diff --git a/src/TinyGsmClientM590.h b/src/TinyGsmClientM590.h index f89500d2..46041bdc 100644 --- a/src/TinyGsmClientM590.h +++ b/src/TinyGsmClientM590.h @@ -343,116 +343,38 @@ class TinyGsmM590 : public TinyGsmModem, * 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(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("+TCPRECV:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore(','); - int16_t len_orig = len; - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - if (len > sockets[mux]->rx.free()) { - DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); - } else { - DBG("### Got: ", len, "->", sockets[mux]->rx.free()); - } - while (len--) { moveCharFromStreamToFifo(mux); } - // TODO(?): Handle lost characters - if (len_orig > sockets[mux]->available()) { - DBG("### Fewer characters received than expected: ", - sockets[mux]->available(), " vs ", len_orig); - } - } - data = ""; - } else if (data.endsWith(GF("+TCPCLOSE:"))) { - int8_t mux = streamGetIntBefore(','); - streamSkipUntil('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### Closed: ", mux); + bool handleURCs(String& data) { + if (data.endsWith(GF("+TCPRECV:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore(','); + int16_t len_orig = len; + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + // reset the len to read to the amount free + len = sockets[mux]->rx.free(); + } + while (len--) { moveCharFromStreamToFifo(mux); } + // TODO(?): Handle lost characters + if (len_orig != sockets[mux]->available()) { + DBG("### Different number of characters received than expected: ", + sockets[mux]->available(), " vs ", len_orig); } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + DBG("### Got Data: ", len_orig, "on", mux); + return true; + } else if (data.endsWith(GF("+TCPCLOSE:"))) { + int8_t mux = streamGetIntBefore(','); + streamSkipUntil('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index 0a902e95..e66c7316 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -508,114 +508,36 @@ class TinyGsmM95 : public TinyGsmModem, * 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(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 "+QIRDI:"))) { - streamSkipUntil(','); // Skip the context - streamSkipUntil(','); // Skip the role - int8_t mux = streamGetIntBefore('\n'); - // DBG("### Got Data:", mux); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - // We have no way of knowing how much data actually came in, so - // we set the value to 1500, the maximum possible size. - sockets[mux]->sock_available = 1500; - } - 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("+QNITZ:"))) { - streamSkipUntil('\n'); // URC for time sync - data = ""; - DBG("### Network time updated."); - } + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+QIRDI:"))) { + streamSkipUntil(','); // Skip the context + streamSkipUntil(','); // Skip the role + int8_t mux = streamGetIntBefore('\n'); + // DBG("### Got Data:", mux); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + // We have no way of knowing how much data actually came in, so + // we set the value to 1500, the maximum possible size. + sockets[mux]->sock_available = 1500; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + return true; + } 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); + return true; + } else if (data.endsWith(GF("+QNITZ:"))) { + streamSkipUntil('\n'); // URC for time sync + data = ""; + DBG("### Network time updated."); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientMC60.h b/src/TinyGsmClientMC60.h index f43e9b03..83353b5d 100644 --- a/src/TinyGsmClientMC60.h +++ b/src/TinyGsmClientMC60.h @@ -481,127 +481,43 @@ class TinyGsmMC60 : public TinyGsmModem, * 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, GsmConstStr r6 = 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(); - String r6s(r6); r6s.trim(); - DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s, ",", r6s);*/ - 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(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 (r6 && data.endsWith(r6)) { - index = 6; - goto finish; - } else if (data.endsWith( - GF(GSM_NL "+QIRDI:"))) { // TODO(?): QIRD? or QIRDI? - // +QIRDI: ,,,,,< tlen> - streamSkipUntil(','); // Skip the context - streamSkipUntil(','); // Skip the role - // read the connection id - int8_t mux = streamGetIntBefore(','); - // read the number of packets in the buffer - int8_t num_packets = streamGetIntBefore(','); - // read the length of the current packet - streamSkipUntil( - ','); // Skip the length of the current package in the buffer - int16_t len_total = - streamGetIntBefore('\n'); // Total length of all packages - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux] && - num_packets >= 0 && len_total >= 0) { - sockets[mux]->sock_available = len_total; - } - data = ""; - // DBG("### Got Data:", len_total, "on", mux); - } 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("+QNITZ:"))) { - streamSkipUntil('\n'); // URC for time sync - DBG("### Network time updated."); - data = ""; - } + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+QIRDI:"))) { // TODO(?): QIRD? or QIRDI? + // +QIRDI: ,,,,,< tlen> + streamSkipUntil(','); // Skip the context + streamSkipUntil(','); // Skip the role + // read the connection id + int8_t mux = streamGetIntBefore(','); + // read the number of packets in the buffer + int8_t num_packets = streamGetIntBefore(','); + // read the length of the current packet + streamSkipUntil( + ','); // Skip the length of the current package in the buffer + int16_t len_total = + streamGetIntBefore('\n'); // Total length of all packages + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux] && + num_packets >= 0 && len_total >= 0) { + sockets[mux]->sock_available = len_total; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } + data = ""; + // DBG("### Got Data:", len_total, "on", mux); + return true; + } 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); + return true; + } else if (data.endsWith(GF("+QNITZ:"))) { + streamSkipUntil('\n'); // URC for time sync + DBG("### Network time updated."); 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, GsmConstStr r6 = NULL) { - String data; - return waitResponse(timeout_ms, data, r1, r2, r3, r4, r5, r6); - } - - 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, GsmConstStr r6 = NULL) { - return waitResponse(1000, r1, r2, r3, r4, r5, r6); + return false; } public: diff --git a/src/TinyGsmClientSIM5360.h b/src/TinyGsmClientSIM5360.h index 8463a34e..9d32bdc6 100644 --- a/src/TinyGsmClientSIM5360.h +++ b/src/TinyGsmClientSIM5360.h @@ -602,125 +602,49 @@ class TinyGsmSim5360 : public TinyGsmModem, * 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(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 "+CIPRXGET:"))) { - int8_t mode = streamGetIntBefore(','); - if (mode == 1) { - 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 { - data += mode; - } - } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - // DBG("### Got Data:", len, "on", mux); - } else if (data.endsWith(GF("+IPCLOSE:"))) { - int8_t mux = streamGetIntBefore(','); - streamSkipUntil('\n'); // Skip the reason code - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### Closed: ", mux); - } else if (data.endsWith(GF("+CIPEVENT:"))) { - // Need to close all open sockets and release the network library. - // User will then need to reconnect. - DBG("### Network error!"); - if (!isGprsConnected()) { gprsDisconnect(); } - data = ""; + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) { + int8_t mode = streamGetIntBefore(','); + if (mode == 1) { + 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); + return true; + } else { + data += mode; + return false; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } + } + data = ""; + // DBG("### Got Data:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+IPCLOSE:"))) { + int8_t mux = streamGetIntBefore(','); + streamSkipUntil('\n'); // Skip the reason code + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); + return true; + } else if (data.endsWith(GF("+CIPEVENT:"))) { + // Need to close all open sockets and release the network library. + // User will then need to reconnect. + DBG("### Network error!"); + if (!isGprsConnected()) { gprsDisconnect(); } data = ""; + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientSIM7000.h b/src/TinyGsmClientSIM7000.h index e7088457..a723a1c1 100644 --- a/src/TinyGsmClientSIM7000.h +++ b/src/TinyGsmClientSIM7000.h @@ -390,141 +390,68 @@ class TinyGsmSim7000 : public TinyGsmSim70xx, * 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(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 "+CIPRXGET:"))) { - int8_t mode = streamGetIntBefore(','); - if (mode == 1) { - 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 { - data += mode; - } - } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - // DBG("### Got Data:", len, "on", mux); - } 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(); + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) { + int8_t mode = streamGetIntBefore(','); + if (mode == 1) { + 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); + return true; + } else { + data += mode; + return false; + } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + // DBG("### Got Data:", len, "on", mux); + return true; + } 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); + return true; + } else if (data.endsWith(GF("*PSNWID:"))) { + streamSkipUntil('\n'); // Refresh network name by network + data = ""; + DBG("### Network name updated."); + return true; + } else if (data.endsWith(GF("*PSUTTZ:"))) { + streamSkipUntil('\n'); // Refresh time and time zone by network + data = ""; + DBG("### Network time and time zone updated."); + return true; + } else if (data.endsWith(GF("+CTZV:"))) { + streamSkipUntil('\n'); // Refresh network time zone by network + data = ""; + DBG("### Network time zone updated."); + return true; + } else if (data.endsWith(GF("DST: "))) { + streamSkipUntil('\n'); // Refresh Network Daylight Saving Time by network + data = ""; + DBG("### Daylight savings time state updated."); + return true; + } else if (data.endsWith(GF(GSM_NL "SMS Ready" GSM_NL))) { + data = ""; + DBG("### Unexpected module reset!"); + init(); + return true; } - // 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); + return false; } protected: diff --git a/src/TinyGsmClientSIM7000SSL.h b/src/TinyGsmClientSIM7000SSL.h index 2f88e893..f9499a37 100644 --- a/src/TinyGsmClientSIM7000SSL.h +++ b/src/TinyGsmClientSIM7000SSL.h @@ -588,138 +588,64 @@ class TinyGsmSim7000SSL * 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(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("+CARECV:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - DBG("### Got Data:", len, "on", mux); - } else if (data.endsWith(GF("+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("+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("*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(); - data = ""; + bool handleURCs(String& data) { + if (data.endsWith(GF("+CARECV:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } + } + data = ""; + DBG("### Got Data:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+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); + return true; + } else if (data.endsWith(GF("+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); } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + return true; + } else if (data.endsWith(GF("*PSNWID:"))) { + streamSkipUntil('\n'); // Refresh network name by network + data = ""; + DBG("### Network name updated."); + return true; + } else if (data.endsWith(GF("*PSUTTZ:"))) { + streamSkipUntil('\n'); // Refresh time and time zone by network + data = ""; + DBG("### Network time and time zone updated."); + return true; + } else if (data.endsWith(GF("+CTZV:"))) { + streamSkipUntil('\n'); // Refresh network time zone by network + data = ""; + DBG("### Network time zone updated."); + return true; + } else if (data.endsWith(GF("DST: "))) { + streamSkipUntil('\n'); // Refresh Network Daylight Saving Time by network + data = ""; + DBG("### Daylight savings time state updated."); + return true; + } else if (data.endsWith(GF(GSM_NL "SMS Ready" GSM_NL))) { + data = ""; + DBG("### Unexpected module reset!"); + init(); + data = ""; + return true; } - // 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); + return false; } protected: diff --git a/src/TinyGsmClientSIM7080.h b/src/TinyGsmClientSIM7080.h index f5584a9e..a0638ada 100644 --- a/src/TinyGsmClientSIM7080.h +++ b/src/TinyGsmClientSIM7080.h @@ -587,138 +587,64 @@ class TinyGsmSim7080 : public TinyGsmSim70xx, * 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(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("+CARECV:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - DBG("### Got Data:", len, "on", mux); - } else if (data.endsWith(GF("+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("+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("*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(); - data = ""; + bool handleURCs(String& data) { + if (data.endsWith(GF("+CARECV:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } + } + data = ""; + DBG("### Got Data:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+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); + return true; + } else if (data.endsWith(GF("+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); } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + return true; + } else if (data.endsWith(GF("*PSNWID:"))) { + streamSkipUntil('\n'); // Refresh network name by network + data = ""; + DBG("### Network name updated."); + return true; + } else if (data.endsWith(GF("*PSUTTZ:"))) { + streamSkipUntil('\n'); // Refresh time and time zone by network + data = ""; + DBG("### Network time and time zone updated."); + return true; + } else if (data.endsWith(GF("+CTZV:"))) { + streamSkipUntil('\n'); // Refresh network time zone by network + data = ""; + DBG("### Network time zone updated."); + return true; + } else if (data.endsWith(GF("DST: "))) { + streamSkipUntil('\n'); // Refresh Network Daylight Saving Time by network + data = ""; + DBG("### Daylight savings time state updated."); + return true; + } else if (data.endsWith(GF(GSM_NL "SMS Ready" GSM_NL))) { + data = ""; + DBG("### Unexpected module reset!"); + init(); + data = ""; + return true; } - // 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); + return false; } protected: diff --git a/src/TinyGsmClientSIM70xx.h b/src/TinyGsmClientSIM70xx.h index b672b76c..31702faa 100644 --- a/src/TinyGsmClientSIM70xx.h +++ b/src/TinyGsmClientSIM70xx.h @@ -398,48 +398,8 @@ class TinyGsmSim70xx : public TinyGsmModem>, * Client related functions */ // should implement in sub-classes - - /* - * Utilities - */ - public: - // should implement in sub-classes - 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) { - return thisModem().waitResponse(timeout_ms, data, r1, r2, r3, r4, r5); - } - - 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 thisModem().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 thisModem().waitResponse(1000, r1, r2, r3, r4, r5); + bool handleURCs(String& data) { + return thisModem().handleURCs(data); } public: diff --git a/src/TinyGsmClientSIM7600.h b/src/TinyGsmClientSIM7600.h index 1b758719..50ee85ad 100644 --- a/src/TinyGsmClientSIM7600.h +++ b/src/TinyGsmClientSIM7600.h @@ -727,125 +727,49 @@ class TinyGsmSim7600 : public TinyGsmModem, * 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(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 "+CIPRXGET:"))) { - int8_t mode = streamGetIntBefore(','); - if (mode == 1) { - 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 { - data += mode; - } - } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - // DBG("### Got Data:", len, "on", mux); - } else if (data.endsWith(GF("+IPCLOSE:"))) { - int8_t mux = streamGetIntBefore(','); - streamSkipUntil('\n'); // Skip the reason code - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### Closed: ", mux); - } else if (data.endsWith(GF("+CIPEVENT:"))) { - // Need to close all open sockets and release the network library. - // User will then need to reconnect. - DBG("### Network error!"); - if (!isGprsConnected()) { gprsDisconnect(); } - data = ""; + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) { + int8_t mode = streamGetIntBefore(','); + if (mode == 1) { + 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); + return true; + } else { + data += mode; + return false; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } + } + data = ""; + // DBG("### Got Data:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+IPCLOSE:"))) { + int8_t mux = streamGetIntBefore(','); + streamSkipUntil('\n'); // Skip the reason code + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); + return true; + } else if (data.endsWith(GF("+CIPEVENT:"))) { + // Need to close all open sockets and release the network library. + // User will then need to reconnect. + DBG("### Network error!"); + if (!isGprsConnected()) { gprsDisconnect(); } data = ""; + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index 9147d14b..1e31e212 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -620,137 +620,63 @@ class TinyGsmSim800 : public TinyGsmModem, * 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(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 "+CIPRXGET:"))) { - int8_t mode = streamGetIntBefore(','); - if (mode == 1) { - 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 { - data += mode; - } - } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - // DBG("### Got Data:", len, "on", mux); - } 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."); + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) { + int8_t mode = streamGetIntBefore(','); + if (mode == 1) { + 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); + return true; + } else { + data += mode; + return false; + } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + // DBG("### Got Data:", len, "on", mux); + return true; + } 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); + return true; + } else if (data.endsWith(GF("*PSNWID:"))) { + streamSkipUntil('\n'); // Refresh network name by network + data = ""; + DBG("### Network name updated."); + return true; + } else if (data.endsWith(GF("*PSUTTZ:"))) { + streamSkipUntil('\n'); // Refresh time and time zone by network + data = ""; + DBG("### Network time and time zone updated."); + return true; + } else if (data.endsWith(GF("+CTZV:"))) { + streamSkipUntil('\n'); // Refresh network time zone by network + data = ""; + DBG("### Network time zone updated."); + return true; + } else if (data.endsWith(GF("DST:"))) { + streamSkipUntil('\n'); // Refresh Network Daylight Saving Time by network + data = ""; + DBG("### Daylight savings time state updated."); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientSaraR4.h b/src/TinyGsmClientSaraR4.h index fe23218a..bc333ed0 100644 --- a/src/TinyGsmClientSaraR4.h +++ b/src/TinyGsmClientSaraR4.h @@ -768,116 +768,38 @@ class TinyGsmSaraR4 : public TinyGsmModem, * 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(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("+UUSORD:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - // max size is 1024 - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - DBG("### URC Data Received:", len, "on", mux); - } else if (data.endsWith(GF("+UUSOCL:"))) { - int8_t mux = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### URC Sock Closed: ", mux); - } else if (data.endsWith(GF("+UUSOCO:"))) { - int8_t mux = streamGetIntBefore('\n'); - int8_t socket_error = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux] && - socket_error == 0) { - sockets[mux]->sock_connected = true; - } - data = ""; - DBG("### URC Sock Opened: ", mux); - } + bool handleURCs(String& data) { + if (data.endsWith(GF("+UUSORD:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + // max size is 1024 + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } + } + data = ""; + DBG("### URC Data Received:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+UUSOCL:"))) { + int8_t mux = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### URC Sock Closed: ", mux); + return true; + } else if (data.endsWith(GF("+UUSOCO:"))) { + int8_t mux = streamGetIntBefore('\n'); + int8_t socket_error = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux] && + socket_error == 0) { + sockets[mux]->sock_connected = true; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + DBG("### URC Sock Opened: ", mux); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientSequansMonarch.h b/src/TinyGsmClientSequansMonarch.h index 694733ab..944876e6 100644 --- a/src/TinyGsmClientSequansMonarch.h +++ b/src/TinyGsmClientSequansMonarch.h @@ -503,9 +503,10 @@ class TinyGsmSequansMonarch waitResponse(10000L, GF(GSM_NL "> ")); // Translate bytes into char to be able to send them as an hex string char char_command[2]; - for (size_t i=0; i(buff)[i]); + sprintf(&char_command[0], "%02X", + reinterpret_cast(buff)[i]); stream.write(char_command, sizeof(char_command)); } stream.flush(); @@ -610,108 +611,29 @@ class TinyGsmSequansMonarch * 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(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 "+SQNSRING:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && - sockets[mux % TINY_GSM_MUX_COUNT]) { - sockets[mux % TINY_GSM_MUX_COUNT]->got_data = true; - sockets[mux % TINY_GSM_MUX_COUNT]->sock_available = len; - } - data = ""; - DBG("### URC Data Received:", len, "on", mux); - } else if (data.endsWith(GF("SQNSH: "))) { - int8_t mux = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && - sockets[mux % TINY_GSM_MUX_COUNT]) { - sockets[mux % TINY_GSM_MUX_COUNT]->sock_connected = false; - } - data = ""; - DBG("### URC Sock Closed: ", mux); - } + bool handleURCs(String& data) { + if (data.endsWith(GF(GSM_NL "+SQNSRING:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && + sockets[mux % TINY_GSM_MUX_COUNT]) { + sockets[mux % TINY_GSM_MUX_COUNT]->got_data = true; + sockets[mux % TINY_GSM_MUX_COUNT]->sock_available = len; + } + data = ""; + DBG("### URC Data Received:", len, "on", mux); + return true; + } else if (data.endsWith(GF("SQNSH: "))) { + int8_t mux = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && + sockets[mux % TINY_GSM_MUX_COUNT]) { + sockets[mux % TINY_GSM_MUX_COUNT]->sock_connected = false; } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + DBG("### URC Sock Closed: ", mux); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientUBLOX.h b/src/TinyGsmClientUBLOX.h index 1250da4a..0fb09e52 100644 --- a/src/TinyGsmClientUBLOX.h +++ b/src/TinyGsmClientUBLOX.h @@ -733,107 +733,28 @@ class TinyGsmUBLOX : public TinyGsmModem, * 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(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("+UUSORD:"))) { - int8_t mux = streamGetIntBefore(','); - int16_t len = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; - // max size is 1024 - if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } - } - data = ""; - // DBG("### URC Data Received:", len, "on", mux); - } else if (data.endsWith(GF("+UUSOCL:"))) { - int8_t mux = streamGetIntBefore('\n'); - if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->sock_connected = false; - } - data = ""; - DBG("### URC Sock Closed: ", mux); - } + bool handleURCs(String& data) { + if (data.endsWith(GF("+UUSORD:"))) { + int8_t mux = streamGetIntBefore(','); + int16_t len = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + // max size is 1024 + if (len >= 0 && len <= 1024) { sockets[mux]->sock_available = len; } } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - if (data.length()) { DBG("### Unhandled:", data); } data = ""; + // DBG("### URC Data Received:", len, "on", mux); + return true; + } else if (data.endsWith(GF("+UUSOCL:"))) { + int8_t mux = streamGetIntBefore('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### URC Sock Closed: ", mux); + return true; } - // 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); + return false; } public: diff --git a/src/TinyGsmClientXBee.h b/src/TinyGsmClientXBee.h index 8a154477..7b68bbd0 100644 --- a/src/TinyGsmClientXBee.h +++ b/src/TinyGsmClientXBee.h @@ -828,7 +828,8 @@ class TinyGsmXBee : public TinyGsmModem, changesMade = true; } } else { - changesMade |= changeSettingIfNeeded(GF("EE"), 0x0); // Set No security + changesMade |= changeSettingIfNeeded(GF("EE"), + 0x0); // Set No security } if (changesMade) { retVal &= writeChanges(); } @@ -878,7 +879,8 @@ class TinyGsmXBee : public TinyGsmModem, changesMade = true; } } - changesMade |= changeSettingIfNeeded(GF("AN"), String(apn)); // Set the APN + changesMade |= changeSettingIfNeeded(GF("AN"), + String(apn)); // Set the APN changesMade |= changeSettingIfNeeded(GF("AM"), 0x0, 5000L); // Airplane mode off @@ -1029,9 +1031,9 @@ class TinyGsmXBee : public TinyGsmModem, 0, }; res.toCharArray(buf, 5); - int8_t intRes = (int8_t)strtol( - buf, 0, - 16); // degrees Celsius displayed in 8-bit two's complement format. + int8_t intRes = (int8_t)strtol(buf, 0, + 16); // degrees Celsius displayed in + // 8-bit two's complement format. XBEE_COMMAND_END_DECORATOR return static_cast(intRes); } @@ -1072,9 +1074,9 @@ class TinyGsmXBee : public TinyGsmModem, uint32_t timeout_ms = ((uint32_t)timeout_s) * 1000; bool gotIP = false; XBEE_COMMAND_START_DECORATOR(5, IPAddress(0, 0, 0, 0)) - // XBee's require a numeric IP address for connection, but do provide the - // functionality to look up the IP address from a fully qualified domain - // name + // XBee's require a numeric IP address for connection, but do provide + // the functionality to look up the IP address from a fully qualified + // domain name // NOTE: the lookup can take a while while ((millis() - startMillis) < timeout_ms) { sendAT(GF("LA"), host); @@ -1104,8 +1106,8 @@ class TinyGsmXBee : public TinyGsmModem, bool retVal = false; XBEE_COMMAND_START_DECORATOR(5, false) - // If this is a new host name, replace the saved host and wipe out the saved - // host IP + // If this is a new host name, replace the saved host and wipe out the + // saved host IP if (this->savedHost != String(host)) { this->savedHost = String(host); savedHostIP = IPAddress(0, 0, 0, 0); @@ -1175,7 +1177,8 @@ class TinyGsmXBee : public TinyGsmModem, if (changesMade) { success &= writeChanges(); } } - // confirm the XBee type if needed so we know if we can know if connected + // confirm the XBee type if needed so we know if we can know if + // connected if (beeType == XBEE_UNKNOWN) { getSeries(); } // we'll accept either unknown or connected if (beeType != XBEE_S6B_WIFI) { @@ -1205,9 +1208,10 @@ class TinyGsmXBee : public TinyGsmModem, sendAT(GF("TM")); String timeoutUsed = readResponseString(5000L); - // For cellular models, per documentation: If you write the TM (socket - // timeout) value while in Transparent Mode, the current connection is - // immediately closed - this works even if the TM values is unchanged + // For cellular models, per documentation: If you write the TM + // (socket timeout) value while in Transparent Mode, the current + // connection is immediately closed - this works even if the TM + // values is unchanged sendAT(GF("TM"), timeoutUsed); // Re-set socket timeout waitResponse(maxWaitMs); // This response can be slow } @@ -1229,7 +1233,8 @@ class TinyGsmXBee : public TinyGsmModem, modemGetConnected(0); } else if (len > 5) { // After sending several characters, also re-check - // NOTE: I'm intentionally not checking after every single character! + // NOTE: I'm intentionally not checking after every single + // character! modemGetConnected(0); } } @@ -1237,10 +1242,11 @@ class TinyGsmXBee : public TinyGsmModem, return len; } - // NOTE: The CI command returns the status of the TCP connection as open only - // after data has been sent on the socket. If it returns 0xFF the socket may - // really be open, but no data has yet been sent. We return this unknown - // value as true so there's a possibility it's wrong. + // NOTE: The CI command returns the status of the TCP connection as + // open only after data has been sent on the socket. If it returns 0xFF + // the socket may really be open, but no data has yet been sent. We + // return this unknown value as true so there's a possibility it's + // wrong. bool modemGetConnected(uint8_t) { // If the IP address is 0, it's not valid so we can't be connected if (savedIP == IPAddress(0, 0, 0, 0)) { return false; } @@ -1281,11 +1287,12 @@ class TinyGsmXBee : public TinyGsmModem, } // 0x28 = "Unknown." - // 0xFF = No known status - always returned prior to sending data + // 0xFF = No known status - always returned prior to sending + // data case 0x28: case 0xFF: { - // If we previously had an operating destination and we no longer - // do, the socket must have closed + // If we previously had an operating destination and we no + // longer do, the socket must have closed if (od == IPAddress(0, 0, 0, 0) && savedOperatingIP != IPAddress(0, 0, 0, 0)) { savedOperatingIP = od; @@ -1297,13 +1304,14 @@ class TinyGsmXBee : public TinyGsmModem, sockets[0]->stop(); return false; } else if (od != IPAddress(0, 0, 0, 0) && od == savedIP) { - // else if the operating destination exists and matches, we're - // good to go + // else if the operating destination exists and matches, + // we're good to go savedOperatingIP = od; return true; } else { - // If we never had an operating destination, then sock may be open - // but data never sent - this is the dreaded "we don't know" + // If we never had an operating destination, then sock may + // be open but data never sent - this is the dreaded "we + // don't know" savedOperatingIP = od; return true; } @@ -1347,8 +1355,8 @@ class TinyGsmXBee : public TinyGsmModem, // 0x02 = Invalid parameters (bad IP/host) // 0x12 = DNS query lookup failure - // 0x25 = Unknown server - DNS lookup failed (0x22 for UDP socket!) - // fall through + // 0x25 = Unknown server - DNS lookup failed (0x22 for UDP + // socket!) fall through case 0x02: case 0x12: case 0x25: { @@ -1378,80 +1386,9 @@ class TinyGsmXBee : public TinyGsmModem, TINY_GSM_YIELD(); } } - - // TODO(vshymanskyy): Optimize this! - // NOTE: This function is used while INSIDE command mode, so we're only - // waiting for requested responses. The XBee has no unsoliliced responses - // (URC's) when in command mode. - int8_t waitResponse(uint32_t timeout_ms, String& data, - GsmConstStr r1 = GFP(GSM_OK), - GsmConstStr r2 = GFP(GSM_ERROR), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, 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(16); // Should never be getting much here for the XBee - int8_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(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)) { - index = 3; - goto finish; - } else if (r4 && data.endsWith(r4)) { - index = 4; - goto finish; - } else if (r5 && data.endsWith(r5)) { - index = 5; - goto finish; - } - } - } while (millis() - startMillis < timeout_ms); - finish: - if (!index) { - data.trim(); - data.replace(GSM_NL GSM_NL, GSM_NL); - data.replace(GSM_NL, "\r\n "); - if (data.length()) { - DBG("### Unhandled:", data, "\r\n"); - } else { - DBG("### NO RESPONSE FROM MODEM!\r\n"); - } - } else { - data.trim(); - data.replace(GSM_NL GSM_NL, GSM_NL); - data.replace(GSM_NL, "\r\n "); - } - // 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), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, 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), GsmConstStr r3 = NULL, - GsmConstStr r4 = NULL, GsmConstStr r5 = NULL) { - return waitResponse(1000, r1, r2, r3, r4, r5); + // The XBee has no unsoliliced responses (URC's) when in command mode. + bool handleURCs(String& data) { + return true; } bool commandMode(uint8_t retries = 5) { @@ -1467,8 +1404,9 @@ class TinyGsmXBee : public TinyGsmModem, streamClear(); // Empty everything in the buffer before starting while (!success && triesMade < retries) { - // Cannot send anything for 1 "guard time" before entering command mode - // Default guard time is 1s, but the init fxn decreases it to 100 ms + // Cannot send anything for 1 "guard time" before entering command + // mode Default guard time is 1s, but the init fxn decreases it to + // 100 ms delay(guardTime + 10); streamWrite(GF("+++")); // enter command mode diff --git a/src/TinyGsmModem.tpp b/src/TinyGsmModem.tpp index e909cae1..d70b2e55 100644 --- a/src/TinyGsmModem.tpp +++ b/src/TinyGsmModem.tpp @@ -48,6 +48,48 @@ class TinyGsmModem { bool testAT(uint32_t timeout_ms = 10000L) { return thisModem().testATImpl(timeout_ms); } + // Listen for responses to commands and handle URCs + 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, GsmConstStr r6 = NULL, + GsmConstStr r7 = NULL) { + return thisModem().waitResponseImpl(timeout_ms, data, r1, r2, r3, r4, r5, + r6, r7); + } + + 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, GsmConstStr r6 = NULL, + GsmConstStr r7 = NULL) { + String data; + return waitResponse(timeout_ms, data, r1, r2, r3, r4, r5, r6, r7); + } + + 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, GsmConstStr r6 = NULL, + GsmConstStr r7 = NULL) { + return waitResponse(1000L, r1, r2, r3, r4, r5, r6, r7); + } // Asks for modem information via the V.25TER standard ATI command // NOTE: The actual value and style of the response is quite varied @@ -132,6 +174,72 @@ class TinyGsmModem { return false; } + + // TODO(vshymanskyy): Optimize this! + int8_t waitResponseImpl(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, GsmConstStr r6 = NULL, + GsmConstStr r7 = NULL) { + data.reserve(64); + uint8_t index = 0; + uint32_t startMillis = millis(); + do { + TINY_GSM_YIELD(); + while (thisModem().stream.available() > 0) { + TINY_GSM_YIELD(); + int8_t a = thisModem().stream.read(); + if (a <= 0) continue; // Skip 0x00 bytes, just in case + data += static_cast(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 (r6 && data.endsWith(r6)) { + index = 6; + goto finish; + } else if (r7 && data.endsWith(r7)) { + index = 7; + goto finish; + } else if (thisModem().handleURCs(data)) { + data = ""; + } + } + } while (millis() - startMillis < timeout_ms); + finish: + if (!index) { + data.trim(); + if (data.length()) { DBG("### Unhandled:", data); } + data = ""; + } + // data.replace(AT_NL, "/"); + // DBG('<', index, '>', data); + return index; + } + + String getModemInfoImpl() { thisModem().sendAT(GF("I")); String res; diff --git a/src/TinyGsmTCP.tpp b/src/TinyGsmTCP.tpp index 391d1fe8..23e7fac0 100644 --- a/src/TinyGsmTCP.tpp +++ b/src/TinyGsmTCP.tpp @@ -241,9 +241,9 @@ class TinyGsmTCP { return -1; } - int peek() override { - return (uint8_t)rx.peek(); - } + int peek() override { + return (uint8_t)rx.peek(); + } void flush() override { at->stream.flush(); @@ -345,7 +345,7 @@ class TinyGsmTCP { // Yields up to a time-out period and then reads a character from the stream // into the mux FIFO - // TODO(SRGDamia1): Do we need to wait two _timeout periods for no + // TODO(SRGDamia1): Do we really need to wait _two_ timeout periods for no // character return? Will wait once in the first "while // !stream.available()" and then will wait again in the stream.read() // function.