From 9e4b2511b1f7a7f6971f6f4e76770b989f409817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Crippa=20B=C3=BArigo?= Date: Thu, 7 Mar 2024 07:06:13 -0300 Subject: [PATCH] TcpClient does not send incomplete packets. (#2721) Before this Pull Request, when the microprocessor runs out of memory while calling `TcpClient::send`, this method could send an incomplete packet. Since `TcpClient::send` does not return the number of bytes actually sent, there's no way to know which part of the message was sent and which part still needs to be sent. Therefore - assuming we keep the interface constant - we should not allow a message to be sent incompletely. More specifically, when one calls [TcpClient::send](https://github.com/SmingHub/Sming/blob/8939766cb38ef540d8296c3ae4bbc0998f88b91a/Sming/Components/Network/src/Network/TcpClient.cpp#L41), the `data` argument is written to a `MemoryDataStream` (by a call to [MemoryDataStream::write](https://github.com/SmingHub/Sming/blob/8939766cb38ef540d8296c3ae4bbc0998f88b91a/Sming/Core/Data/Stream/MemoryDataStream.cpp#L49C8-L49C31)). According to its [implementation](https://github.com/SmingHub/Sming/blob/8939766cb38ef540d8296c3ae4bbc0998f88b91a/Sming/Core/Data/Stream/MemoryDataStream.cpp#L57), when it is not possible to allocate enough additional memory to hold `data`, `MemoryDataStream` stores "as much as possible" in the space that could be allocated. For a `TcpClient`, this may not be a desirable behavior since this allows incomplete messages to be sent, while there's no way to know how much of the packet was actually sent. This change ensures there's enough memory to hold `data` before writing it to the `MemoryDataStream`. This makes sure only complete messages are sent. --- Sming/Components/Network/src/Network/TcpClient.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sming/Components/Network/src/Network/TcpClient.cpp b/Sming/Components/Network/src/Network/TcpClient.cpp index b0c1e7b45e..56b151352d 100644 --- a/Sming/Components/Network/src/Network/TcpClient.cpp +++ b/Sming/Components/Network/src/Network/TcpClient.cpp @@ -49,11 +49,13 @@ bool TcpClient::send(const char* data, uint16_t len, bool forceCloseAfterSent) memoryStream = new MemoryDataStream(); } - if(memoryStream->write(data, len) != len) { + if(!memoryStream->ensureCapacity(memoryStream->getSize() + len)) { debug_e("TcpClient::send ERROR: Unable to store %d bytes in buffer", len); return false; } + memoryStream->write(data, len); + return send(memoryStream, forceCloseAfterSent); }