diff --git a/library.json b/library.json index a74627c..8993ef5 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TinyGSM", - "version": "0.6.1", + "version": "0.6.2", "description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports many GSM, LTE, and WiFi modules with AT command interfaces.", "keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM7000, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968, M95, MC60, MC60E, BG96, ublox, Quectel, SIMCOM, AI Thinker, LTE, LTE-M", "authors": diff --git a/library.properties b/library.properties index 146f48b..b1423a1 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TinyGSM -version=0.6.1 +version=0.6.2 author=Volodymyr Shymanskyy maintainer=Volodymyr Shymanskyy sentence=A small Arduino library for GPRS modules, that just works. diff --git a/src/TinyGsmClientA6.h b/src/TinyGsmClientA6.h index 8fa02bb..6f892a5 100644 --- a/src/TinyGsmClientA6.h +++ b/src/TinyGsmClientA6.h @@ -58,6 +58,10 @@ public: this->mux = -1; sock_connected = false; + // at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems + return true; } @@ -71,6 +75,8 @@ public: if (sock_connected) { mux = newMux; at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems } return sock_connected; } @@ -112,7 +118,7 @@ public: virtual int available() { TINY_GSM_YIELD(); - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } return rx.size(); diff --git a/src/TinyGsmClientBG96.h b/src/TinyGsmClientBG96.h index d75ba25..02a8269 100644 --- a/src/TinyGsmClientBG96.h +++ b/src/TinyGsmClientBG96.h @@ -62,6 +62,8 @@ public: got_data = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -72,6 +74,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -97,7 +103,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -144,7 +150,7 @@ public: // TODO: Read directly into user buffer? at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -178,12 +184,12 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmBG96* at; - uint8_t mux; - uint16_t sock_available; - bool sock_connected; - bool got_data; - RxFifo rx; + TinyGsmBG96* at; + uint8_t mux; + uint16_t sock_available; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -632,6 +638,7 @@ protected: return 0; } // TODO: Wait for ACK? AT+QISEND=id,0 + maintain(); // look for a very quick response from the remote return len; } @@ -641,6 +648,7 @@ protected: return 0; } size_t len = stream.readStringUntil('\n').toInt(); + sockets[mux]->sock_available = len; for (size_t i=0; irx.put(c); } waitResponse(); - DBG("### READ:", mux, ",", len); + DBG("### READ:", len, "from", mux); + maintain(); // Listen for a close or other URC return len; } @@ -659,12 +668,13 @@ protected: streamSkipUntil(','); // Skip total received streamSkipUntil(','); // Skip have read result = stream.readStringUntil('\n').toInt(); - DBG("### STILL:", mux, "has", result); + DBG("### DATA AVAILABLE:", result, "on", mux); waitResponse(); } if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -683,6 +693,7 @@ protected: int res = stream.readStringUntil(',').toInt(); // socket state waitResponse(); + maintain(); // Listen for a close or other URC // 0 Initial, 1 Opening, 2 Connected, 3 Listening, 4 Closing return 2 == res; diff --git a/src/TinyGsmClientESP8266.h b/src/TinyGsmClientESP8266.h index f6c7419..a18dfbd 100644 --- a/src/TinyGsmClientESP8266.h +++ b/src/TinyGsmClientESP8266.h @@ -59,6 +59,8 @@ public: sock_connected = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -69,6 +71,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -109,7 +115,7 @@ public: virtual int available() { TINY_GSM_YIELD(); - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } return rx.size(); @@ -183,6 +189,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux, true); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } }; diff --git a/src/TinyGsmClientM590.h b/src/TinyGsmClientM590.h index 1f5ea00..7eeb917 100644 --- a/src/TinyGsmClientM590.h +++ b/src/TinyGsmClientM590.h @@ -59,6 +59,8 @@ public: sock_connected = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -69,6 +71,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -128,7 +134,7 @@ public: continue; } // TODO: Read directly into user buffer? - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } } @@ -161,10 +167,10 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmM590* at; - uint8_t mux; - bool sock_connected; - RxFifo rx; + TinyGsmM590* at; + uint8_t mux; + bool sock_connected; + RxFifo rx; }; diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index a3818ce..39022a9 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -62,6 +62,8 @@ public: got_data = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -72,6 +74,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -97,7 +103,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -144,7 +150,7 @@ public: // TODO: Read directly into user buffer? at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -178,12 +184,12 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmM95* at; - uint8_t mux; - uint16_t sock_available; - bool sock_connected; - bool got_data; - RxFifo rx; + TinyGsmM95* at; + uint8_t mux; + uint16_t sock_available; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -684,10 +690,11 @@ protected: } } waitResponse(5000L); + maintain(); // look for a very quick response from the remote // streamSkipUntil(','); // Skip mux // return stream.readStringUntil('\n').toInt(); - return 1; + return len; // TODO } size_t modemRead(size_t size, uint8_t mux) { @@ -696,6 +703,7 @@ protected: return 0; } size_t len = stream.readStringUntil('\n').toInt(); + sockets[mux]->sock_available = len; for (size_t i=0; irx.put(c); } waitResponse(); - DBG("### READ:", mux, ",", len); + DBG("### READ:", len, "from", mux); + maintain(); // Listen for a close or other URC return len; } @@ -714,12 +723,13 @@ protected: streamSkipUntil(','); // Skip total received streamSkipUntil(','); // Skip have read result = stream.readStringUntil('\n').toInt(); - DBG("### STILL:", mux, "has", result); + DBG("### DATA AVAILABLE:", result, "on", mux); waitResponse(); } if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -738,6 +748,7 @@ protected: int res = stream.readStringUntil(',').toInt(); // socket state waitResponse(); + maintain(); // Listen for a close or other URC // 0 Initial, 1 Opening, 2 Connected, 3 Listening, 4 Closing return 2 == res; diff --git a/src/TinyGsmClientMC60.h b/src/TinyGsmClientMC60.h index b3239b3..8b6e021 100644 --- a/src/TinyGsmClientMC60.h +++ b/src/TinyGsmClientMC60.h @@ -66,6 +66,8 @@ public: got_data = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -76,6 +78,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -101,7 +107,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -148,7 +154,7 @@ public: // TODO: Read directly into user buffer? at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -182,12 +188,12 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmMC60* at; - uint8_t mux; - uint16_t sock_available; - bool sock_connected; - bool got_data; - RxFifo rx; + TinyGsmMC60* at; + uint8_t mux; + uint16_t sock_available; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -715,7 +721,9 @@ protected: // streamSkipUntil(','); // Skip mux // return stream.readStringUntil('\n').toInt(); - return 1; + + maintain(); // look for a very quick response from the remote + return len; // TODO } size_t modemRead(size_t size, uint8_t mux) { @@ -724,6 +732,7 @@ protected: return 0; } size_t len = stream.readStringUntil('\n').toInt(); + sockets[mux]->sock_available = len; for (size_t i=0; irx.put(c); } waitResponse(); - DBG("### READ:", mux, ",", len); + DBG("### READ:", len, "from", mux); + maintain(); // Listen for a close or other URC return len; } @@ -742,12 +752,13 @@ protected: streamSkipUntil(','); // Skip total received streamSkipUntil(','); // Skip have read result = stream.readStringUntil('\n').toInt(); - DBG("### STILL:", mux, "has", result); + DBG("### DATA AVAILABLE:", result, "on", mux); waitResponse(); } if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -766,6 +777,7 @@ protected: int res = stream.readStringUntil(',').toInt(); // socket state waitResponse(); + maintain(); // Listen for a close or other URC // 0 Initial, 1 Opening, 2 Connected, 3 Listening, 4 Closing return 2 == res; diff --git a/src/TinyGsmClientSIM7000.h b/src/TinyGsmClientSIM7000.h index ef64d5d..90634aa 100644 --- a/src/TinyGsmClientSIM7000.h +++ b/src/TinyGsmClientSIM7000.h @@ -71,6 +71,8 @@ public: got_data = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -81,6 +83,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -106,7 +112,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -166,10 +172,10 @@ public: got_data = true; prev_check = millis(); } - at->maintain(); // TODO: Read directly into user buffer? + at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -204,12 +210,12 @@ public: private: TinyGsmSim7000* at; - uint8_t mux; - uint16_t sock_available; - uint32_t prev_check; - bool sock_connected; - bool got_data; - RxFifo rx; + uint8_t mux; + uint16_t sock_available; + uint32_t prev_check; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -228,6 +234,9 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux, true); + // sock_connected = at->modemConnect(host, port, &mux, true); + // at->sockets[mux] = this; + // TODO: When is the socket attached? return sock_connected; } }; @@ -421,6 +430,7 @@ public: RegStatus getRegistrationStatus() { sendAT(GF("+CGREG?")); + // TODO: Shouldn't this be CEREG for the EPS status of this 4G module? if (waitResponse(GF(GSM_NL "+CGREG:")) != 1) { return REG_UNKNOWN; } @@ -932,6 +942,7 @@ protected: return 0; } streamSkipUntil(','); // Skip mux + maintain(); // look for a very quick response from the remote return stream.readStringUntil('\n').toInt(); } @@ -947,12 +958,19 @@ protected: return 0; } #endif - streamSkipUntil(','); // Skip mode 2/3 + streamSkipUntil(','); // Skip Rx mode 2/normal or 3/HEX streamSkipUntil(','); // Skip mux - size_t len = stream.readStringUntil(',').toInt(); - sockets[mux]->sock_available = stream.readStringUntil('\n').toInt(); + size_t len_requested = stream.readStringUntil(',').toInt(); + // ^^ Requested number of data bytes (1-1460 bytes)to be read + size_t len_confirmed = stream.readStringUntil('\n').toInt(); + if (len_confirmed > len_requested) { + DBG(len_requested - len_confirmed, "fewer bytes confirmed than requested!"); + } + sockets[mux]->sock_available = len_confirmed; + // ^^ Confirmed number of data bytes to be read, which may be less than requested. + // 0 indicates that no data can be read. - for (size_t i=0; irx.put(c); } waitResponse(); - return len; + DBG("### READ:", len_confirmed, "from", mux); + maintain(); // Listen for a close or other URC + return len_confirmed; } size_t modemGetAvailable(uint8_t mux) { @@ -981,6 +1001,7 @@ protected: if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -988,6 +1009,7 @@ protected: sendAT(GF("+CIPSTATUS="), mux); int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\"")); waitResponse(); + maintain(); // Listen for a close or other URC return 1 == res; } @@ -1048,9 +1070,19 @@ public: sockets[mux]->got_data = true; } data = ""; + DBG("### Got Data:", mux); } else { data += mode; } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int mux = stream.readStringUntil(',').toInt(); + int len = stream.readStringUntil('\n').toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + sockets[mux]->sock_available = len; + } + data = ""; + DBG("### Got Data:", len, "on", mux); } else if (data.endsWith(GF("CLOSED" GSM_NL))) { int nl = data.lastIndexOf(GSM_NL, data.length()-8); int coma = data.indexOf(',', nl+2); diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index 1e19928..13b94b4 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -68,6 +68,8 @@ public: got_data = false; at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems return true; } @@ -78,6 +80,10 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux); + // sock_connected = at->modemConnect(host, port, &mux); + // at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems return sock_connected; } @@ -103,7 +109,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -161,10 +167,10 @@ public: got_data = true; prev_check = millis(); } - at->maintain(); // TODO: Read directly into user buffer? + at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -198,13 +204,13 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmSim800* at; - uint8_t mux; - uint16_t sock_available; - uint32_t prev_check; - bool sock_connected; - bool got_data; - RxFifo rx; + TinyGsmSim800* at; + uint8_t mux; + uint16_t sock_available; + uint32_t prev_check; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -223,6 +229,9 @@ public: TINY_GSM_YIELD(); rx.clear(); sock_connected = at->modemConnect(host, port, mux, true); + // sock_connected = at->modemConnect(host, port, &mux, true); + // at->sockets[mux] = this; + // TODO: When is the socket attached? return sock_connected; } }; @@ -578,6 +587,7 @@ public: bool gprsDisconnect() { // Shut the TCP/IP connection + // CIPSHUT will close *all* open connections sendAT(GF("+CIPSHUT")); if (waitResponse(60000L) != 1) return false; @@ -791,6 +801,7 @@ public: /* * Battery functions */ + // Use: float vBatt = modem.getBattVoltage() / 1000.0; uint16_t getBattVoltage() { sendAT(GF("+CBC")); @@ -853,6 +864,7 @@ protected: return 0; } streamSkipUntil(','); // Skip mux + maintain(); // look for a very quick response from the remote return stream.readStringUntil('\n').toInt(); } @@ -868,12 +880,19 @@ protected: return 0; } #endif - streamSkipUntil(','); // Skip mode 2/3 + streamSkipUntil(','); // Skip Rx mode 2/normal or 3/HEX streamSkipUntil(','); // Skip mux - size_t len = stream.readStringUntil(',').toInt(); - sockets[mux]->sock_available = stream.readStringUntil('\n').toInt(); + size_t len_requested = stream.readStringUntil(',').toInt(); + // ^^ Requested number of data bytes (1-1460 bytes)to be read + size_t len_confirmed = stream.readStringUntil('\n').toInt(); + if (len_confirmed > len_requested) { + DBG(len_requested - len_confirmed, "fewer bytes confirmed than requested!"); + } + sockets[mux]->sock_available = len_confirmed; + // ^^ Confirmed number of data bytes to be read, which may be less than requested. + // 0 indicates that no data can be read. - for (size_t i=0; irx.put(c); } waitResponse(); - return len; + DBG("### READ:", len_confirmed, "from", mux); + maintain(); // Listen for a close or other URC + return len_confirmed; } size_t modemGetAvailable(uint8_t mux) { @@ -902,6 +923,7 @@ protected: if (!result) { sockets[mux]->sock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -909,6 +931,7 @@ protected: sendAT(GF("+CIPSTATUS="), mux); int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\"")); waitResponse(); + maintain(); // Listen for a close or other URC return 1 == res; } @@ -969,9 +992,19 @@ public: sockets[mux]->got_data = true; } data = ""; + DBG("### Got Data:", mux); } else { data += mode; } + } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) { + int mux = stream.readStringUntil(',').toInt(); + int len = stream.readStringUntil('\n').toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { + sockets[mux]->got_data = true; + sockets[mux]->sock_available = len; + } + data = ""; + DBG("### Got Data:", len, "on", mux); } else if (data.endsWith(GF("CLOSED" GSM_NL))) { int nl = data.lastIndexOf(GSM_NL, data.length()-8); int coma = data.indexOf(',', nl+2); diff --git a/src/TinyGsmClientUBLOX.h b/src/TinyGsmClientUBLOX.h index d5e4912..9d938f0 100644 --- a/src/TinyGsmClientUBLOX.h +++ b/src/TinyGsmClientUBLOX.h @@ -61,6 +61,11 @@ public: prev_check = 0; sock_connected = false; got_data = false; + + // at->sockets[mux] = this; + // ^^ TODO: attach the socket here at init? Or later at connect? + // Currently done inconsistently between modems + return true; } @@ -81,8 +86,11 @@ public: } TINY_GSM_YIELD(); rx.clear(); + // sock_connected = at->modemConnect(host, port, mux); sock_connected = at->modemConnect(host, port, &mux); at->sockets[mux] = this; + // ^^ TODO: attach the socet after attempting connection or above at init? + // Currently done inconsistently between modems at->maintain(); return sock_connected; } @@ -109,7 +117,7 @@ public: rx.clear(); at->maintain(); while (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); rx.clear(); at->maintain(); } @@ -168,10 +176,10 @@ public: got_data = true; prev_check = millis(); } - at->maintain(); // TODO: Read directly into user buffer? + at->maintain(); if (sock_available > 0) { - sock_available -= at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); + at->modemRead(TinyGsmMin((uint16_t)rx.free(), sock_available), mux); } else { break; } @@ -205,13 +213,13 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmUBLOX* at; - uint8_t mux; - uint16_t sock_available; - uint32_t prev_check; - bool sock_connected; - bool got_data; - RxFifo rx; + TinyGsmUBLOX* at; + uint8_t mux; + uint16_t sock_available; + uint32_t prev_check; + bool sock_connected; + bool got_data; + RxFifo rx; }; @@ -229,8 +237,10 @@ public: stop(); TINY_GSM_YIELD(); rx.clear(); + // sock_connected = at->modemConnect(host, port, mux, true); sock_connected = at->modemConnect(host, port, &mux, true); at->sockets[mux] = this; + // TODO: When is the socket attached? at->maintain(); return sock_connected; } @@ -772,6 +782,7 @@ protected: bool modemDisconnect(uint8_t mux) { TINY_GSM_YIELD(); + if (!modemGetConnected(mux)) return true; if (isCatM) { // These modems allow a faster "asynchronous" close sendAT(GF("+USOCL="), mux, GF(",1")); int rsp = waitResponse(120000L); @@ -798,7 +809,7 @@ protected: streamSkipUntil(','); // Skip mux int sent = stream.readStringUntil('\n').toInt(); waitResponse(); - maintain(); // look for a very quick response + maintain(); // look for a very quick response from the remote return sent; } @@ -809,6 +820,7 @@ protected: } streamSkipUntil(','); // Skip mux size_t len = stream.readStringUntil(',').toInt(); + sockets[mux]->sock_available = len; streamSkipUntil('\"'); for (size_t i=0; isock_connected = modemGetConnected(mux); } + maintain(); // Listen for a close or other URC return result; } @@ -860,6 +876,7 @@ protected: // 9: the socket is in LAST_ACK status // 10: the socket is in TIME_WAIT status waitResponse(); + maintain(); // Listen for a close or other URC return (result != 0); } @@ -895,7 +912,7 @@ public: TINY_GSM_YIELD(); while (stream.available() > 0) { int a = stream.read(); - if (a < 0) continue; + if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { index = 1; @@ -914,19 +931,20 @@ public: goto finish; } else if (data.endsWith(GF(GSM_NL "+UUSORD:"))) { int mux = stream.readStringUntil(',').toInt(); - streamSkipUntil('\n'); + int len = stream.readStringUntil('\n').toInt(); if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { sockets[mux]->got_data = true; + sockets[mux]->sock_available = len; } data = ""; - DBG("### Got Data:", mux); + DBG("### Got Data:", len, "on", mux); } else if (data.endsWith(GF(GSM_NL "+UUSOCL:"))) { int mux = stream.readStringUntil('\n').toInt(); if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { sockets[mux]->sock_connected = false; } data = ""; - DBG("### Closed:", mux); + DBG("### Closed: ", mux); } } } while (millis() - startMillis < timeout); diff --git a/src/TinyGsmClientXBee.h b/src/TinyGsmClientXBee.h index 865139c..fc8d1ae 100644 --- a/src/TinyGsmClientXBee.h +++ b/src/TinyGsmClientXBee.h @@ -213,10 +213,10 @@ public: String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: - TinyGsmXBee* at; - uint8_t mux; - bool sock_connected; - // RxFifo rx; + TinyGsmXBee* at; + uint8_t mux; + bool sock_connected; + // RxFifo rx; }; @@ -992,8 +992,8 @@ finish: streamClear(); // Empty everything in the buffer before starting while (!success and 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 250 ms - delay(guardTime); + // Default guard time is 1s, but the init fxn decreases it to 100 ms + delay(guardTime + 50); streamWrite(GF("+++")); // enter command mode int res = waitResponse(guardTime*2); success = (1 == res); diff --git a/src/TinyGsmCommon.h b/src/TinyGsmCommon.h index a8c7be4..7d0db43 100644 --- a/src/TinyGsmCommon.h +++ b/src/TinyGsmCommon.h @@ -10,7 +10,7 @@ #define TinyGsmCommon_h // The current library version number -#define TINYGSM_VERSION "0.6.1" +#define TINYGSM_VERSION "0.6.2" #if defined(SPARK) || defined(PARTICLE) #include "Particle.h"