Skip to content

Commit 0121910

Browse files
committed
[hot-fix] memory leak on send method
1 parent 5ad11c9 commit 0121910

File tree

3 files changed

+212
-25
lines changed

3 files changed

+212
-25
lines changed

iot_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
#include "Arduino.h"
77

8-
int indexOf(uint8_t * buffer, size_t bufLen, char find, size_t start = (size_t)0);
8+
int indexOf(uint8_t *buffer, size_t bufLen, char find, size_t start = (size_t)0);
99

1010
#endif

iot_protocol.cpp

Lines changed: 197 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#include "iot_protocol.h"
22

3+
IoTApp::IoTApp()
4+
{
5+
// this->handleData = [this](void *, AsyncClient *client, void *data, size_t len)
6+
// {
7+
// this->onData(client, (uint8_t *)data, len);
8+
// };
9+
}
10+
311
void IoTApp::use(IoTMiddleware middleware)
412
{
513
this->middlewares.push_back(middleware);
@@ -28,9 +36,23 @@ void IoTApp::runMiddleware(IoTRequest *request, int index = 0)
2836
}
2937
}
3038

39+
// static void handleData(void* arg, AsyncClient* client, void *data, size_t len)
40+
// {
41+
// Serial.print("[CALLBACK] data received, ip: " + client->remoteIP().toString());
42+
// Serial.println( " [" + String((char*)data) + "]");
43+
44+
// // or loop through data , using data[i] and len:
45+
// // for ( int i = 0 ; i < len ; i++ ) {
46+
// // if ( uint8_t*)data[i] == 0 ) { } }
47+
48+
// // could send to server here, by doing:
49+
// // sendToServer( "Hello!");
50+
// }
51+
3152
void IoTApp::listen(Client *client)
3253
{
3354
this->clients.push_back(client);
55+
// client->onData((this->handleData), NULL);
3456
}
3557

3658
void IoTApp::onData(Client *client, uint8_t *buffer, size_t bufLen)
@@ -60,13 +82,6 @@ void IoTApp::onData(Client *client, uint8_t *buffer, size_t bufLen)
6082
uint8_t *bufferPart = buffer + indexStart;
6183
size_t bufferPartLength = ((indexN == -1 || isBody) ? (bufLen + 1) : indexN) - indexStart;
6284

63-
// uint8_t bufferPart[bufferPartLength];
64-
// for (size_t i = 0; i < bufferPartLength; i++)
65-
// {
66-
// bufferPart[i] = bufferPartStart[i];
67-
// }
68-
69-
// [ 0 \n 1 2 \n 3 4 5 \n 6 7 8 9]
7085
switch (foundN)
7186
{
7287
case 0:
@@ -148,11 +163,34 @@ void IoTApp::onData(Client *client, uint8_t *buffer, size_t bufLen)
148163
if (invalidRequest)
149164
return;
150165

166+
/* Response */
167+
auto rr = this->requestResponse.find(request.id);
168+
if (rr != this->requestResponse.end())
169+
{
170+
if (rr->second.onResponse != NULL)
171+
{
172+
(*(rr->second.onResponse))(&request);
173+
// (rr->second.onResponse)(&request);
174+
175+
/* free body and path ?! hehe */
176+
free(request.path);
177+
free(request.body);
178+
}
179+
this->requestResponse.erase(request.id);
180+
return;
181+
}
182+
if (request.method == EIoTMethod::RESPONSE)
183+
{
184+
return;
185+
}
186+
187+
/* Middleware */
151188
this->runMiddleware(&request);
152189
}
153190

154191
uint16_t IoTApp::generateRequestId()
155192
{
193+
vTaskDelay(1);
156194
uint16_t id = (uint16_t)(millis() % 10000);
157195
if (this->requestResponse.find(id) != this->requestResponse.end() || id == 0)
158196
{
@@ -190,40 +228,164 @@ IoTRequest *IoTApp::send(IoTRequest *request, IoTRequestResponse *requestRespons
190228
headers += header->first + ":" + header->second + "\n";
191229
}
192230

193-
size_t dataLength = 1 + 1 + 1 + 2 + 1 /* (version+\n+method+id+\n) */ + pathLength + 1 /* (\n) */ + headers.length();
231+
size_t dataLength = 7 + pathLength + headers.length(); /* 1 + 1 + 1 + 2 + 1 (version+\n+method+id+\n) + pathLength + 1 (\n) + headers.length() */
194232

195233
if (request->body != NULL)
196234
{
197-
dataLength += 1 + 1 /* (B+\n) */ + request->bodyLength;
235+
dataLength += 2 + request->bodyLength; /* 1 + 1 (B+\n) + request->bodyLength */
198236
}
199237

200-
uint8_t *data = (uint8_t *)(malloc(dataLength * sizeof(uint8_t)));
238+
// uint8_t *data = (uint8_t *)(malloc(dataLength * sizeof(uint8_t)));
239+
// uint8_t *data = new uint8_t[dataLength];
240+
241+
// char data[dataLength+1]; /* +1 (\0) */
242+
uint8_t data[dataLength + 1]; /* +1 (\0) */
243+
// uint8_t data[6 + pathLength + 2]; /* +2 (\n\0) */
201244
data[0] = request->version;
202245
data[1] = '\n';
203246
data[2] = static_cast<uint8_t>((char)request->method);
204247
data[3] = request->id >> 8; /* Id as Big Endian - (MSB first) */
205-
data[4] = request->id - (data[3] << 8); /* Id as Big Endian - (LSB last) */
248+
data[4] = request->id - (data[3] << 8); /* Id as Big Endian - (LSB last) */
206249
data[5] = '\n';
207-
memcpy((data + 6), request->path, pathLength);
208-
size_t nextIndex = 5 /* (last index) */ + pathLength + 1 /* next */;
209-
data[nextIndex] = '\n';
210-
nextIndex++;
211250

251+
size_t nextIndex = 5;
252+
253+
// memcpy((data + 6), request->path, pathLength);
254+
for (size_t i = 0; i < pathLength; i++)
255+
{
256+
data[++nextIndex] = *(request->path + i);
257+
}
258+
259+
// size_t nextIndex = 6 + pathLength; /* 5 (last index) + pathLength + 1 (next) */
260+
// data[nextIndex] = '\n';
261+
// nextIndex++;
262+
263+
data[++nextIndex] = '\n';
264+
212265
if (headers.length() > 0)
213266
{
214-
memcpy((data + nextIndex), headers.c_str(), headers.length());
215-
nextIndex += headers.length();
267+
// memcpy((data + nextIndex), headers.c_str(), headers.length());
268+
for (size_t i = 0; i < headers.length(); i++)
269+
{
270+
data[++nextIndex] = (headers.charAt(i));
271+
}
272+
// nextIndex += headers.length();
216273
}
274+
217275
if (request->body != NULL)
218276
{
219-
data[nextIndex] = 'B';
277+
data[++nextIndex] = 'B';
220278
data[++nextIndex] = '\n';
221-
memcpy((data + nextIndex + 1), request->body, request->bodyLength);
279+
// memcpy((data + nextIndex + 1), request->body, request->bodyLength);
280+
for (size_t i = 0; i < request->bodyLength; i++)
281+
{
282+
data[++nextIndex] = *(request->body + i);
283+
}
222284
}
285+
// data[nextIndex + request->bodyLength + 1] = '\0';
286+
287+
data[++nextIndex] = '\0';
288+
289+
if (requestResponse != NULL)
290+
{
291+
if (requestResponse->timeout == 0)
292+
{
293+
requestResponse->timeout = 1000;
294+
}
295+
requestResponse->timeout += millis();
296+
requestResponse->request = *request;
297+
298+
this->requestResponse.insert(std::make_pair(request->id, *requestResponse));
299+
}
300+
301+
// request->client->print("teste");
302+
// String _data = String((const char*)data);
303+
// request->client->print(_data);
304+
// const uint8_t* _data = data;
305+
306+
// const uint8_t* _data = data;
307+
// request->client->print(String(_data, dataLength));
308+
// request->client->print("lorem ipsum fuck the message how much logger is this better for our test and counter lorem ipsum fuck the message how much logger is this better for our test and counter lorem ipsum fuck the message how much logger is this better for our test and counter");
309+
310+
// request->client->add((const char*)data, dataLength);
311+
// request->client->send();
312+
313+
// request->client->write((const char*)data, dataLength);
314+
315+
// const char* teste = (const char *)(malloc(dataLength * sizeof(char)));
316+
317+
/* char c[3];
318+
319+
c[0] = 'h';
320+
c[1] = 'i';
321+
c[2] = '\0'; */
322+
323+
//---- ok com path
324+
// char c[6 + pathLength + 2];
325+
326+
// c[0] = request->version;
327+
// c[1] = '\n';
328+
// c[2] = static_cast<uint8_t>((char)request->method);
329+
// c[3] = request->id >> 8; /* Id as Big Endian - (MSB first) */
330+
// c[4] = request->id - (data[3] << 8); /* Id as Big Endian - (LSB last) */
331+
// c[5] = '\n';
332+
// size_t cursor = 6;
333+
// // char p[pathLength];
334+
// for (size_t i = 0; i < pathLength; i++)
335+
// {
336+
// c[cursor + i] = *(request->path+i);
337+
// }
338+
// // char p[] = "/who/r/i";
339+
// // for (size_t i = 0; i < 8; i++)
340+
// // {
341+
// // c[cursor + i] = p[i];
342+
// // }
343+
// // memcpy((c + 6), request->path, pathLength);
344+
// c[(6 + pathLength)] = '\n';
345+
// c[(7 + pathLength)] = '\0';
346+
347+
// const char *d = c;
348+
// request->client->write(d, dataLength);
349+
//----- ok com path
350+
// const uint8_t *d = data;
351+
352+
// std::copy(data, data+dataLength, teste);
353+
// memcpy((char*)teste, data, dataLength);
223354

224355
request->client->write(data, dataLength);
356+
// request->client->write(d, 6 + pathLength + 1);
357+
358+
// size_t space = request->client->space();
359+
// if (space > dataLength)
360+
// {
361+
// // request->client->write((const char *)data, dataLength, ASYNC_WRITE_FLAG_MORE);
362+
363+
// }
364+
365+
// free((char*)teste);
225366

226-
free(data);
367+
// request->client->free();
368+
369+
// write the data in chunks
370+
// int chunk_size = 16; // write data in 16-byte chunks
371+
// for (int i = 0; i < dataLength; i += chunk_size)
372+
// {
373+
// size_t remainToWrite = dataLength - i;
374+
// size_t amountToWrite = ( remainToWrite > chunk_size) ? chunk_size : remainToWrite;
375+
// int bytes_written = request->client->write(data + i, amountToWrite);
376+
// }
377+
378+
// _data = String();
379+
380+
// request->client->flush();
381+
// request->client->stop();
382+
383+
// request->client->;
384+
// request->client->close();
385+
386+
// free(data);
387+
388+
// delete[] data;
227389
if (shouldFreePath)
228390
{
229391
free(request->path);
@@ -256,4 +418,19 @@ void IoTApp::loop()
256418
this->onData(client, buffer, (indexBuffer - 1));
257419
}
258420
}
421+
422+
/* Timeout */
423+
unsigned long now = millis();
424+
for (auto rr = this->requestResponse.begin(); rr != this->requestResponse.end(); ++rr)
425+
{
426+
unsigned long timeout = rr->second.timeout;
427+
if (now >= timeout)
428+
{
429+
OnTimeout *onTimeout = rr->second.onTimeout;
430+
(*onTimeout)(&(rr->second.request));
431+
432+
this->requestResponse.erase(rr->second.request.id);
433+
continue;
434+
}
435+
}
259436
}

iot_protocol.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,31 @@ enum class EIoTRequestPart : char
4747
BODY = 'B',
4848
};
4949

50+
typedef std::function<void(IoTRequest *response)> OnResponse;
51+
typedef std::function<void(IoTRequest *request)> OnTimeout;
52+
5053
struct IoTRequestResponse
5154
{
52-
std::function<void(IoTRequest *response)> onResponse;
53-
std::function<void(IoTRequest *request)> onTimeout;
54-
int timeout;
55+
OnResponse *onResponse;
56+
OnTimeout *onTimeout;
57+
58+
unsigned long timeout;
59+
60+
IoTRequest request;
5561
};
5662

5763
class IoTApp
5864
{
5965
private:
66+
// std::vector<AsyncClient *> clients;
6067
std::vector<Client *> clients;
6168
void onData(Client *client, uint8_t *buffer, size_t bufLen);
62-
std::map<uint16_t, IoTRequestResponse *> requestResponse = std::map<uint16_t, IoTRequestResponse *>();
69+
// void handleData(void* arg, AsyncClient* client, void *data, size_t len);
70+
// AcDataHandler handleData;
71+
std::map<uint16_t, IoTRequestResponse> requestResponse = std::map<uint16_t, IoTRequestResponse>();
6372

6473
public:
74+
IoTApp();
6575
std::vector<IoTMiddleware> middlewares;
6676

6777
/* Common methods */

0 commit comments

Comments
 (0)