diff --git a/src/GSMClient.cpp b/src/GSMClient.cpp index ddaa19a..9da359c 100644 --- a/src/GSMClient.cpp +++ b/src/GSMClient.cpp @@ -51,7 +51,8 @@ GSMClient::GSMClient(int socket, bool synch) : _host(NULL), _port(0), _ssl(false), - _writeSync(true) + _writeSync(true), + _bytesWritten(0) { MODEM.addUrcHandler(this); } @@ -325,6 +326,73 @@ size_t GSMClient::write(const uint8_t* buf, size_t size) return written; } +size_t GSMClient::send(const void* buf, size_t size, uint32_t timeout) +{ + uint32_t start = millis(); + + if (_writeSync) { + while (ready() == 0); + } + else if (ready() == 0) { + return 0; + } + + if (_socket == -1) { + return 0; + } + String command; + + command += "AT+USOWR="; + command += _socket; + command += ","; + command += size; + + MODEM.send(command); + + String response; + if ((MODEM.waitForResponse(10000, &response) == 1) && + (response == "@")) { + //After the @ prompt reception, wait for a minimum of 50ms before sending data. + delay(50); + MODEM.write((uint8_t*)buf, size); + } + else { + return 0; + } + + _bytesWritten = 0; + + while (((millis() - start) < timeout) && (_bytesWritten < size)) { + MODEM.ready(); + } + + return _bytesWritten; +} + +size_t GSMClient::unacknoledgedBytes(uint32_t timeout) +{ + uint32_t start = millis(); + uint32_t unacknoledgedBytes = 0; + + do { + String response; + MODEM.send("AT+USOCTL=0,11"); + if (MODEM.waitForResponse(100, &response) == 1) { + if (response.startsWith("+USOCTL: ")) { + int i = response.lastIndexOf(','); + if (i > 0) { + unacknoledgedBytes = response.substring(i + 1).toInt(); + if (unacknoledgedBytes == 0) { + break; + } + } + } + } + } while ((millis() - start) < timeout); + + return unacknoledgedBytes; +} + void GSMClient::endWrite(bool /*sync*/) { _writeSync = true; @@ -437,6 +505,12 @@ void GSMClient::stop() void GSMClient::handleUrc(const String& urc) { + if (urc.startsWith("+USOWR: ")){ + int i = urc.indexOf(','); + if (i > 0){ + _bytesWritten = urc.substring(i + 1).toInt(); + } + } if (urc.startsWith("+UUSORD: ")) { int socket = urc.charAt(9) - '0'; diff --git a/src/GSMClient.h b/src/GSMClient.h index 1455d58..5930c9d 100644 --- a/src/GSMClient.h +++ b/src/GSMClient.h @@ -86,6 +86,27 @@ class GSMClient : public Client, public ModemUrcHandler { */ size_t write(const uint8_t*, size_t); + /** Write a buffer with size in request in binary mode + @param (uint8_t*) Buffer + @param (size_t) Buffer size + @param (uint32_t) Timeout + @return data bytes sent to lower level of protocol stack. + + @brief Write data bytes. + The returned value is not a notification of an acknowledgment + received from the remote host. + */ + size_t send(const void*, size_t, uint32_t); + + /** Waiting data acknowledgement + @param (uint32_t) Timeout + @return data bytes unacknoledged. + + @brief This function ensures that all data sent + are received from the remote host. +*/ + size_t unacknoledgedBytes(uint32_t timeout=5000); + /** Finish write request @param sync Sync mode */ @@ -145,6 +166,7 @@ class GSMClient : public Client, public ModemUrcHandler { bool _writeSync; String _response; + uint32_t _bytesWritten; }; #endif diff --git a/src/Modem.cpp b/src/Modem.cpp index 2e73cd1..1e14ad0 100644 --- a/src/Modem.cpp +++ b/src/Modem.cpp @@ -279,7 +279,17 @@ void ModemClass::poll() } case AT_RECEIVING_RESPONSE: { - if (c == '\n') { + if (c == '@'){ + _lastResponseOrUrcMillis = millis(); + _ready = 1; + if (_responseDataStorage != NULL){ + *_responseDataStorage = _buffer; + _responseDataStorage = NULL; + } + _atCommandState = AT_COMMAND_IDLE; + _buffer = ""; + return; + } else if (c == '\n') { _lastResponseOrUrcMillis = millis(); int responseResultIndex = _buffer.lastIndexOf("OK\r\n"); diff --git a/src/Modem.h b/src/Modem.h index 57e6152..7d47cc2 100644 --- a/src/Modem.h +++ b/src/Modem.h @@ -50,7 +50,6 @@ class ModemClass { size_t write(uint8_t c); size_t write(const uint8_t*, size_t); - void send(const char* command); void send(const String& command) { send(command.c_str()); } void sendf(const char *fmt, ...);