test: add lora frame and chunk reassembly logic suite
This commit is contained in:
75
lib/dd3_transport_logic/src/batch_reassembly_logic.cpp
Normal file
75
lib/dd3_transport_logic/src/batch_reassembly_logic.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "batch_reassembly_logic.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void batch_reassembly_reset(BatchReassemblyState &state) {
|
||||
state.active = false;
|
||||
state.batch_id = 0;
|
||||
state.next_index = 0;
|
||||
state.expected_chunks = 0;
|
||||
state.total_len = 0;
|
||||
state.received_len = 0;
|
||||
state.last_rx_ms = 0;
|
||||
state.timeout_ms = 0;
|
||||
}
|
||||
|
||||
BatchReassemblyStatus batch_reassembly_push(BatchReassemblyState &state, uint16_t batch_id, uint8_t chunk_index,
|
||||
uint8_t chunk_count, uint16_t total_len, const uint8_t *chunk_data,
|
||||
size_t chunk_len, uint32_t now_ms, uint32_t timeout_ms_for_new_batch,
|
||||
uint16_t max_total_len, uint8_t *buffer, size_t buffer_cap,
|
||||
uint16_t &out_complete_len) {
|
||||
out_complete_len = 0;
|
||||
if (!buffer || !chunk_data) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
if (chunk_len > 0 && total_len == 0) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
|
||||
bool expired = state.timeout_ms > 0 && (now_ms - state.last_rx_ms > state.timeout_ms);
|
||||
if (!state.active || batch_id != state.batch_id || expired) {
|
||||
if (chunk_index != 0) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
if (total_len == 0 || total_len > max_total_len || chunk_count == 0) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
state.active = true;
|
||||
state.batch_id = batch_id;
|
||||
state.expected_chunks = chunk_count;
|
||||
state.total_len = total_len;
|
||||
state.received_len = 0;
|
||||
state.next_index = 0;
|
||||
state.last_rx_ms = now_ms;
|
||||
state.timeout_ms = timeout_ms_for_new_batch;
|
||||
}
|
||||
|
||||
if (!state.active || chunk_index != state.next_index || chunk_count != state.expected_chunks) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
|
||||
if (state.received_len + chunk_len > state.total_len ||
|
||||
state.received_len + chunk_len > max_total_len ||
|
||||
state.received_len + chunk_len > buffer_cap) {
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::ErrorReset;
|
||||
}
|
||||
|
||||
memcpy(&buffer[state.received_len], chunk_data, chunk_len);
|
||||
state.received_len += static_cast<uint16_t>(chunk_len);
|
||||
state.next_index++;
|
||||
state.last_rx_ms = now_ms;
|
||||
|
||||
if (state.next_index == state.expected_chunks && state.received_len == state.total_len) {
|
||||
out_complete_len = state.received_len;
|
||||
batch_reassembly_reset(state);
|
||||
return BatchReassemblyStatus::Complete;
|
||||
}
|
||||
|
||||
return BatchReassemblyStatus::InProgress;
|
||||
}
|
||||
Reference in New Issue
Block a user