diff --git a/src/TinyGsmClientA6.h b/src/TinyGsmClientA6.h index dda5f7c..c249352 100644 --- a/src/TinyGsmClientA6.h +++ b/src/TinyGsmClientA6.h @@ -81,14 +81,16 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { + virtual void stop(uint32_t maxWaitMs) { TINY_GSM_YIELD(); at->sendAT(GF("+CIPCLOSE="), mux); sock_connected = false; - at->waitResponse(); + at->waitResponse(maxWaitMs); rx.clear(); } + virtual void stop() { stop(1000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_NO_MODEM_FIFO() diff --git a/src/TinyGsmClientBG96.h b/src/TinyGsmClientBG96.h index 930e2a4..daa479a 100644 --- a/src/TinyGsmClientBG96.h +++ b/src/TinyGsmClientBG96.h @@ -82,25 +82,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+QICLOSE="), mux); sock_connected = false; at->waitResponse(); } + virtual void stop() { stop(15000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() diff --git a/src/TinyGsmClientESP8266.h b/src/TinyGsmClientESP8266.h index 66b7296..04764e8 100644 --- a/src/TinyGsmClientESP8266.h +++ b/src/TinyGsmClientESP8266.h @@ -78,14 +78,16 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { + virtual void stop(uint32_t maxWaitMs) { TINY_GSM_YIELD(); at->sendAT(GF("+CIPCLOSE="), mux); sock_connected = false; - at->waitResponse(5000L); + at->waitResponse(maxWaitMs); rx.clear(); } + virtual void stop() { stop(5000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_NO_MODEM_FIFO() diff --git a/src/TinyGsmClientM590.h b/src/TinyGsmClientM590.h index 8fb1c7e..6e26d79 100644 --- a/src/TinyGsmClientM590.h +++ b/src/TinyGsmClientM590.h @@ -79,14 +79,16 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { + virtual void stop(uint32_t maxWaitMs) { TINY_GSM_YIELD(); at->sendAT(GF("+TCPCLOSE="), mux); sock_connected = false; - at->waitResponse(); + at->waitResponse(maxWaitMs); rx.clear(); } + virtual void stop() { stop(1000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_NO_MODEM_FIFO() diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index ed549ac..39497cd 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -81,25 +81,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+QICLOSE="), mux); sock_connected = false; - at->waitResponse(60000L, GF("CLOSED"), GF("CLOSE OK"), GF("ERROR")); + at->waitResponse((maxWaitMs - (millis() - startMillis)), GF("CLOSED"), GF("CLOSE OK"), GF("ERROR")); } + virtual void stop() { stop(75000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_NO_BUFFER_CHECK() diff --git a/src/TinyGsmClientMC60.h b/src/TinyGsmClientMC60.h index 0b7d7ea..f78b40a 100644 --- a/src/TinyGsmClientMC60.h +++ b/src/TinyGsmClientMC60.h @@ -85,25 +85,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+QICLOSE="), mux); sock_connected = false; - at->waitResponse(60000L, GF("CLOSED"), GF("CLOSE OK"), GF("ERROR")); + at->waitResponse((maxWaitMs - (millis() - startMillis)), GF("CLOSED"), GF("CLOSE OK"), GF("ERROR")); } + virtual void stop() { stop(75000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_NO_BUFFER_CHECK() diff --git a/src/TinyGsmClientSIM7000.h b/src/TinyGsmClientSIM7000.h index 09dc1eb..d68e4ab 100644 --- a/src/TinyGsmClientSIM7000.h +++ b/src/TinyGsmClientSIM7000.h @@ -86,25 +86,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+CIPCLOSE="), mux); sock_connected = false; at->waitResponse(); } + virtual void stop() { stop(15000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index 9bb1c63..fbcd1a1 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -87,25 +87,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+CIPCLOSE="), mux, GF(",1")); // Quick close sock_connected = false; at->waitResponse(); } + virtual void stop() { stop(15000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() diff --git a/src/TinyGsmClientSaraR4.h b/src/TinyGsmClientSaraR4.h index 1b0e76a..81e0b63 100644 --- a/src/TinyGsmClientSaraR4.h +++ b/src/TinyGsmClientSaraR4.h @@ -91,23 +91,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_connected && sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } - at->modemDisconnect(mux); + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() + at->sendAT(GF("+USOCL="), mux); + at->waitResponse((maxWaitMs - (millis() - startMillis))); // NOTE: can take up to 120s to get a response + sock_connected = false; } + virtual void stop() { stop(135000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() @@ -569,21 +561,6 @@ protected: return (1 == rsp); } - bool modemDisconnect(uint8_t mux) { - TINY_GSM_YIELD(); - if (!modemGetConnected(mux)) { - sockets[mux]->sock_connected = false; - return true; - } - bool success; - sendAT(GF("+USOCL="), mux); - success = 1 == waitResponse(120000L); // can take up to 120s to get a response - if (success) { - sockets[mux]->sock_connected = false; - } - return success; - } - int16_t modemSend(const void* buff, size_t len, uint8_t mux) { sendAT(GF("+USOWR="), mux, ',', len); if (waitResponse(GF("@")) != 1) { diff --git a/src/TinyGsmClientSequansMonarch.h b/src/TinyGsmClientSequansMonarch.h index 60ed443..26d255d 100644 --- a/src/TinyGsmClientSequansMonarch.h +++ b/src/TinyGsmClientSequansMonarch.h @@ -93,25 +93,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() at->sendAT(GF("+SQNSH="), mux); sock_connected = false; at->waitResponse(); } + virtual void stop() { stop(15000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() diff --git a/src/TinyGsmClientUBLOX.h b/src/TinyGsmClientUBLOX.h index 01e4bb5..99b222c 100644 --- a/src/TinyGsmClientUBLOX.h +++ b/src/TinyGsmClientUBLOX.h @@ -91,23 +91,15 @@ public: TINY_GSM_CLIENT_CONNECT_OVERLOADS() - virtual void stop() { - TINY_GSM_YIELD(); - // Read and dump anything remaining in the modem's internal buffer. - // The socket will appear open in response to connected() even after it - // closes until all data is read from the buffer. - // Doing it this way allows the external mcu to find and get all of the data - // that it wants from the socket even if it was closed externally. - rx.clear(); - at->maintain(); - while (sock_connected && sock_available > 0) { - at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); - rx.clear(); - at->maintain(); - } - at->modemDisconnect(mux); + virtual void stop(uint32_t maxWaitMs) { + TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() + at->sendAT(GF("+USOCL="), mux); + at->waitResponse(); // should return within 1s + sock_connected = false; } + virtual void stop() { stop(15000L); } + TINY_GSM_CLIENT_WRITE() TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK() @@ -580,21 +572,6 @@ protected: return (1 == rsp); } - bool modemDisconnect(uint8_t mux) { - TINY_GSM_YIELD(); - if (!modemGetConnected(mux)) { - sockets[mux]->sock_connected = false; - return true; - } - bool success; - sendAT(GF("+USOCL="), mux); - success = 1 == waitResponse(); // should return within 1s - if (success) { - sockets[mux]->sock_connected = false; - } - return success; - } - int16_t modemSend(const void* buff, size_t len, uint8_t mux) { sendAT(GF("+USOWR="), mux, ',', len); if (waitResponse(GF("@")) != 1) { diff --git a/src/TinyGsmClientXBee.h b/src/TinyGsmClientXBee.h index 11251b1..0e2b0f4 100644 --- a/src/TinyGsmClientXBee.h +++ b/src/TinyGsmClientXBee.h @@ -116,21 +116,21 @@ public: return connect(ip, port, 75); } - virtual void stop() { + virtual void stop(uint32_t maxWaitMs) { at->streamClear(); // Empty anything in the buffer at->commandMode(); // For WiFi models, there's no direct way to close the socket. This is a // hack to shut the socket by setting the timeout to zero. if (at->beeType == XBEE_S6B_WIFI) { at->sendAT(GF("TM0")); // Set socket timeout (using Digi default of 10 seconds) - at->waitResponse(5000); // This response can be slow + at->waitResponse(maxWaitMs); // This response can be slow at->writeChanges(); } // For cellular models, per documentation: If you change the TM (socket // timeout) value while in Transparent Mode, the current connection is // immediately closed. at->sendAT(GF("TM64")); // Set socket timeout (using Digi default of 10 seconds) - at->waitResponse(5000); // This response can be slow + at->waitResponse(maxWaitMs); // This response can be slow at->writeChanges(); at->exitCommand(); at->streamClear(); // Empty anything remaining in the buffer @@ -142,6 +142,8 @@ public: // much more nicely with libraries like PubSubClient. } + virtual void stop() { stop(5000L); } + virtual size_t write(const uint8_t *buf, size_t size) { TINY_GSM_YIELD(); return at->modemSend(buf, size, mux); diff --git a/src/TinyGsmCommon.h b/src/TinyGsmCommon.h index 8edc8c4..a6b20f2 100644 --- a/src/TinyGsmCommon.h +++ b/src/TinyGsmCommon.h @@ -275,7 +275,7 @@ String TinyGsmDecodeHex16bit(String &instr) { } -// Returns the number of characters avaialable in the TinyGSM fifo +// Returns the number of characters available in the TinyGSM fifo // Assumes the modem chip has no internal fifo #define TINY_GSM_CLIENT_AVAILABLE_NO_MODEM_FIFO() \ virtual int available() { \ @@ -395,6 +395,24 @@ String TinyGsmDecodeHex16bit(String &instr) { } +// Read and dump anything remaining in the modem's internal buffer. +// Using this in the client stop() function. +// The socket will appear open in response to connected() even after it +// closes until all data is read from the buffer. +// Doing it this way allows the external mcu to find and get all of the data +// that it wants from the socket even if it was closed externally. +#define TINY_GSM_CLIENT_DUMP_MODEM_BUFFER() \ + TINY_GSM_YIELD(); \ + rx.clear(); \ + at->maintain(); \ + unsigned long startMillis = millis(); \ + while (sock_available > 0 && (millis() - startMillis < maxWaitMs)) { \ + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); \ + rx.clear(); \ + at->maintain(); \ + } + + // The peek, flush, and connected functions #define TINY_GSM_CLIENT_PEEK_FLUSH_CONNECTED() \ virtual int peek() { return -1; } /* TODO */ \