diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index d881c4a87..672fff4b2 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -239,6 +239,27 @@ int WiFiClient::peek() return _client->peek(); } +size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { + size_t count = 0; + + if(!_client) { + return 0; + } + + _startMillis = millis(); + while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) { + yield(); + } + + if(available() < (int) length) { + count = available(); + } else { + count = length; + } + + return _client->peekBytes((char *)buffer, count); +} + void WiFiClient::flush() { if (_client) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h index 3c4ebde2e..62436b512 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/libraries/ESP8266WiFi/src/WiFiClient.h @@ -56,6 +56,10 @@ public: virtual int read(); virtual int read(uint8_t *buf, size_t size); virtual int peek(); + virtual size_t peekBytes(uint8_t *buffer, size_t length); + size_t peekBytes(char *buffer, size_t length) { + return peekBytes((uint8_t *) buffer, length); + } virtual void flush(); virtual void stop(); virtual uint8_t connected(); diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index a35a25ad0..4299ddb8f 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -133,6 +133,17 @@ public: return _read_ptr[0]; } + size_t peekBytes(char *dst, size_t size) { + if(!_available) { + if(!_readAll()) + return -1; + } + + size_t will_copy = (_available < size) ? _available : size; + memcpy(dst, _read_ptr, will_copy); + return will_copy; + } + int available() { auto cb = _available; if (cb == 0) { @@ -278,6 +289,27 @@ int WiFiClientSecure::peek() { return _ssl->peek(); } +size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) { + size_t count = 0; + + if(!_ssl) { + return 0; + } + + _startMillis = millis(); + while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) { + yield(); + } + + if(available() < (int) length) { + count = available(); + } else { + count = length; + } + + return _ssl->peekBytes((char *)buffer, count); +} + int WiFiClientSecure::available() { if (!_ssl) return 0; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.h b/libraries/ESP8266WiFi/src/WiFiClientSecure.h index 07b111e1a..d1234a621 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.h @@ -46,6 +46,7 @@ public: int available() override; int read() override; int peek() override; + size_t peekBytes(uint8_t *buffer, size_t length) override; void stop() override; void setCertificate(const uint8_t* cert_data, size_t size); diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 2c26de832..65cbc2a24 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -179,6 +179,20 @@ class ClientContext { return reinterpret_cast(_rx_buf->payload)[_rx_buf_offset]; } + size_t peekBytes(char *dst, size_t size) { + if(!_rx_buf) return 0; + + size_t max_size = _rx_buf->tot_len - _rx_buf_offset; + size = (size < max_size) ? size : max_size; + + DEBUGV(":pd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset); + size_t buf_size = _rx_buf->len - _rx_buf_offset; + size_t copy_size = (size < buf_size) ? size : buf_size; + DEBUGV(":rpi %d, %d\r\n", buf_size, copy_size); + os_memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, copy_size); + return copy_size; + } + void flush() { if(!_rx_buf) { return;