diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 729dc17..e1e354e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -23,7 +23,7 @@ with your board before submitting any issues. Main processor board: Modem: -TinyGSM version: +TinyGSM version: Code: ### Scenario, steps to reproduce diff --git a/library.json b/library.json index c9fcf2a..8108dc8 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TinyGSM", - "version": "0.9.14", + "version": "0.9.15", "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 ed9d8ad..dcf23a2 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TinyGSM -version=0.9.14 +version=0.9.15 author=Volodymyr Shymanskyy maintainer=Volodymyr Shymanskyy sentence=A small Arduino library for GPRS modules, that just works. diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index 8877625..f83a056 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -64,7 +64,6 @@ public: this->mux = mux; sock_available = 0; sock_connected = false; - got_data = false; at->sockets[mux] = this; @@ -110,7 +109,6 @@ private: uint8_t mux; uint16_t sock_available; bool sock_connected; - bool got_data; RxFifo rx; }; @@ -369,17 +367,41 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return false; } - //Set Method to Handle Received TCP/IP Data - Retrieve Data by Command + // Set Method to Handle Received TCP/IP Data + // Mode = 1 - Output a notification when data is received + // “+QIRDI: ,,” sendAT(GF("+QINDI=1")); if (waitResponse() != 1) { return false; } - //Request an IP header for received data ("IPD(data length):") - sendAT(GF("+QIHEAD=1")); - if (waitResponse() != 1) { - return false; - } + // // Request an IP header for received data + // // "IPD(data length):" + // sendAT(GF("+QIHEAD=1")); + // if (waitResponse() != 1) { + // return false; + // } + // + // // Do NOT show the IP address of the sender when receiving data + // // The format to show the address is: RECV FROM: : + // sendAT(GF("+QISHOWRA=0")); + // if (waitResponse() != 1) { + // return false; + // } + // + // // Do NOT show the protocol type at the end of the header for received data + // // IPD(data length)(TCP/UDP): + // sendAT(GF("+QISHOWPT=0")); + // if (waitResponse() != 1) { + // return false; + // } + // + // // Do NOT show the destination address before receiving data + // // The format to show the address is: TO: + // sendAT(GF("+QISHOWLA=0")); + // if (waitResponse() != 1) { + // return false; + // } return true; } @@ -637,22 +659,34 @@ protected: // sid = index of connection = mux // len = maximum length of data to retrieve sendAT(GF("+QIRD=0,1,"), mux, ',', (uint16_t)size); - // sendAT(GF("+QIRD="), mux, ',', (uint16_t)size); - if (waitResponse(GF("+QIRD:")) != 1) { - return 0; - } - streamSkipUntil(':'); // skip IP address - streamSkipUntil(','); // skip port - streamSkipUntil(','); // skip connection type (TCP/UDP) - int len = stream.readStringUntil('\n').toInt(); // read length - for (int i=0; isock_available--; - // ^^ One less character available after moving from modem's FIFO to our FIFO + // If it replies only OK for the write command, it means there is no + // received data in the buffer of the connection. + int res = waitResponse(GF("+QIRD:"), GFP(GSM_OK), GFP(GSM_ERROR)); + if (res == 1) { + streamSkipUntil(':'); // skip IP address + streamSkipUntil(','); // skip port + streamSkipUntil(','); // skip connection type (TCP/UDP) + // read the real length of the retrieved data + uint16_t len = stream.readStringUntil('\n').toInt(); + // We have no way of knowing in advance how much data will be in the buffer + // so when data is received we always assume the buffer is completely full. + // Chances are, this is not true and there's really not that much there. + // In that case, make sure we make sure we re-set the amount of data available. + if (len < size) { + sockets[mux]->sock_available = len; + } + for (uint16_t i=0; isock_available--; + // ^^ One less character available after moving from modem's FIFO to our FIFO + } + waitResponse(); // ends with an OK + DBG("### READ:", len, "from", mux); + return len; + } else { + sockets[mux]->sock_available = 0; + return 0; } - waitResponse(); // ends with an OK - DBG("### READ:", len, "from", mux); - return len; } bool modemGetConnected(uint8_t mux) { @@ -725,7 +759,9 @@ TINY_GSM_MODEM_STREAM_UTILITIES() int mux = stream.readStringUntil('\n').toInt(); DBG("### Got Data:", mux); if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; + // 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))) { diff --git a/src/TinyGsmClientMC60.h b/src/TinyGsmClientMC60.h index 61d6a2e..9ec3ade 100644 --- a/src/TinyGsmClientMC60.h +++ b/src/TinyGsmClientMC60.h @@ -68,7 +68,6 @@ public: this->mux = mux; sock_available = 0; sock_connected = false; - got_data = false; at->sockets[mux] = this; @@ -114,7 +113,6 @@ private: uint8_t mux; uint16_t sock_available; bool sock_connected; - bool got_data; RxFifo rx; }; @@ -381,14 +379,10 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return false; } - //Set Method to Handle Received TCP/IP Data - Retrieve Data by Command - sendAT(GF("+QINDI=1")); - if (waitResponse() != 1) { - return false; - } - - //Request an IP header for received data ("IPD(data length):") - sendAT(GF("+QIHEAD=1")); + //Set Method to Handle Received TCP/IP Data + // Mode=2 - Output a notification statement: + // “+QIRDI: ,,,,,< tlen>” + sendAT(GF("+QINDI=2")); if (waitResponse() != 1) { return false; } @@ -638,22 +632,34 @@ protected: // sid = index of connection - mux // len = maximum length of data to send sendAT(GF("+QIRD=0,1,"), mux, ',', (uint16_t)size); - // sendAT(GF("+QIRD="), mux, ',', (uint16_t)size); - if (waitResponse(GF("+QIRD:")) != 1) { - return 0; - } - streamSkipUntil(':'); // skip IP address - streamSkipUntil(','); // skip port - streamSkipUntil(','); // skip connection type (TCP/UDP) - int len = stream.readStringUntil('\n').toInt(); // read length - for (int i=0; isock_available--; - // ^^ One less character available after moving from modem's FIFO to our FIFO + // If it replies only OK for the write command, it means there is no + // received data in the buffer of the connection. + int res = waitResponse(GF("+QIRD:"), GFP(GSM_OK), GFP(GSM_ERROR)); + if (res == 1) { + streamSkipUntil(':'); // skip IP address + streamSkipUntil(','); // skip port + streamSkipUntil(','); // skip connection type (TCP/UDP) + // read the real length of the retrieved data + uint16_t len = stream.readStringUntil('\n').toInt(); + // It's possible that the real length available is less than expected + // This is quite likely if the buffer is broken into packets - which may + // be different sizes. + // If so, make sure we make sure we re-set the amount of data available. + if (len < size) { + sockets[mux]->sock_available = len; + } + for (uint16_t i=0; isock_available--; + // ^^ One less character available after moving from modem's FIFO to our FIFO + } + waitResponse(); + DBG("### READ:", len, "from", mux); + return len; + } else { + sockets[mux]->sock_available = 0; + return 0; } - waitResponse(); - DBG("### READ:", len, "from", mux); - return len; } bool modemGetConnected(uint8_t mux) { @@ -725,14 +731,20 @@ TINY_GSM_MODEM_STREAM_UTILITIES() index = 6; goto finish; } else if (data.endsWith(GF(GSM_NL "+QIRD:"))) { // TODO: QIRD? or QIRDI? + // +QIRDI: ,,,,,< tlen> streamSkipUntil(','); // Skip the context streamSkipUntil(','); // Skip the role - int mux = stream.readStringUntil('\n').toInt(); - DBG("### Got Data:", mux); + // read the connection id + int mux = stream.readStringUntil(',').toInt(); + // read the number of packets in the buffer + int num_packets = stream.readStringUntil(',').toInt(); + // read the length of the current packet + int len_packet = stream.readStringUntil('\n').toInt(); if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) { - sockets[mux]->got_data = true; + sockets[mux]->sock_available = len_packet*num_packets; } 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/TinyGsmCommon.h b/src/TinyGsmCommon.h index 5df479a..3e476f8 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.9.14" +#define TINYGSM_VERSION "0.9.15" #if defined(SPARK) || defined(PARTICLE) #include "Particle.h"