Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 36 additions & 14 deletions RF24Network.cpp

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense in the sense that each platform allocates different sizes for data types. We've certainly seen divergences in ESP cores on this numerous times before. I suspect this sizeof(Header) + sizeof(Addr) math is done at compile time. Might be cleaner to have a constexpr to signify that this math is calculating the... whatchamacallit... FRAG_MSG_OFFSET?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if this works, we can def do that

Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@ template<class radio_t>
uint8_t ESBNetwork<radio_t>::enqueue(RF24NetworkHeader* header)
{
bool result = false;

// Prevent unsigned underflow in message_size calculation
if (frame_size < sizeof(RF24NetworkHeader)) {
return false;
}

uint16_t message_size = frame_size - sizeof(RF24NetworkHeader);

IF_RF24NETWORK_DEBUG(printf_P(PSTR("NET Enqueue @%x\n"), next_frame - frame_queue));
Expand All @@ -439,6 +445,11 @@ uint8_t ESBNetwork<radio_t>::enqueue(RF24NetworkHeader* header)

if (header->type == NETWORK_FIRST_FRAGMENT) {

// Necessary bounds check before copy
if (message_size > MAX_PAYLOAD_SIZE) {
return false;
}

memcpy((char*)(&frag_queue), &frame_buffer, sizeof(RF24NetworkHeader));
memcpy(frag_queue.message_buffer, frame_buffer + sizeof(RF24NetworkHeader), message_size);

Expand Down Expand Up @@ -487,11 +498,11 @@ uint8_t ESBNetwork<radio_t>::enqueue(RF24NetworkHeader* header)
return 0;
#endif
if ((uint16_t)(MAX_PAYLOAD_SIZE) - (next_frame - frame_queue) >= frag_queue.message_size) {
memcpy(next_frame, &frag_queue, 10);
memcpy(next_frame + 10, frag_queue.message_buffer, frag_queue.message_size);
next_frame += (10 + frag_queue.message_size);
memcpy(next_frame, &frag_queue, sizeof(RF24NetworkHeader) + sizeof(uint16_t));
memcpy(next_frame + sizeof(RF24NetworkHeader) + sizeof(uint16_t), frag_queue.message_buffer, frag_queue.message_size);
next_frame += (sizeof(RF24NetworkHeader) + sizeof(uint16_t) + frag_queue.message_size);
#if !defined(ARDUINO_ARCH_AVR)
if (uint8_t padding = (frag_queue.message_size + 10) % 4) {
if (uint8_t padding = (frag_queue.message_size + sizeof(RF24NetworkHeader) + sizeof(uint16_t)) % 4) {
next_frame += 4 - padding;
}
#endif
Expand All @@ -510,7 +521,12 @@ uint8_t ESBNetwork<radio_t>::enqueue(RF24NetworkHeader* header)
#if !defined(DISABLE_FRAGMENTATION)
if (header->type == EXTERNAL_DATA_TYPE)
{
memcpy((char*)(&frag_queue), &frame_buffer, 8);
// Necessary bounds check before copy
if (message_size > MAX_PAYLOAD_SIZE) {
return false;
}

memcpy((char*)(&frag_queue), &frame_buffer, sizeof(RF24NetworkHeader));
memcpy(frag_queue.message_buffer, frame_buffer + sizeof(RF24NetworkHeader), message_size);
frag_queue.message_size = message_size;
return 2;
Expand All @@ -521,26 +537,23 @@ uint8_t ESBNetwork<radio_t>::enqueue(RF24NetworkHeader* header)
}
#else // !defined(DISABLE_USER_PAYLOADS)
#if !defined(ARDUINO_ARCH_AVR)
uint8_t padding = (message_size + 10) % 4;
uint8_t padding = (message_size + sizeof(RF24NetworkHeader) + sizeof(uint16_t)) % 4;
padding = padding ? 4 - padding : 0;
if (padding +
#else
if (
#endif
message_size + 10 + (next_frame - frame_queue)
message_size + sizeof(RF24NetworkHeader) + sizeof(uint16_t) + (next_frame - frame_queue)
<= MAIN_BUFFER_SIZE)
{
memcpy(next_frame, &frame_buffer, 8);
memcpy(next_frame + 8, &message_size, 2);
memcpy(next_frame + 10, frame_buffer + 8, message_size);
memcpy(next_frame, &frame_buffer, sizeof(RF24NetworkHeader));
memcpy(next_frame + sizeof(RF24NetworkHeader), &message_size, sizeof(uint16_t));
memcpy(next_frame + sizeof(RF24NetworkHeader) + sizeof(uint16_t), frame_buffer + sizeof(RF24NetworkHeader), message_size);

//IF_RF24NETWORK_DEBUG_FRAGMENTATION( for(int i=0; i<message_size;i++){ Serial.print(next_frame[i],HEX); Serial.print(" : "); } Serial.println(""); );

next_frame += (message_size + 10);
next_frame += (message_size + sizeof(RF24NetworkHeader) + sizeof(uint16_t));
#if !defined(ARDUINO_ARCH_AVR)
next_frame += padding;
#endif
//IF_RF24NETWORK_DEBUG_FRAGMENTATION( Serial.print("Enq "); Serial.println(next_frame-frame_queue); );//printf_P(PSTR("enq %d\n"),next_frame-frame_queue); );

result = true;
}
Expand Down Expand Up @@ -1266,12 +1279,21 @@ void ESBNetwork<radio_t>::pipe_address(uint16_t node, uint8_t pipe, uint8_t* add

/******************************************************************/
#if defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP32
#include "esp_task_wdt.h"
#endif

template<class radio_t>
void ESBNetwork<radio_t>::RF24NetworkDelay(uint32_t delay)
{
uint32_t timer = millis();
while (millis() - timer < delay) {
}
#if defined ARDUINO_ARCH_ESP8266
ESP.wdtFeed();
#else
esp_task_wdt_reset();
#endif
}
#endif
/************************ Sleep Mode ******************************************/
Expand Down