fix: Align channel data framing

ref: #1928
This commit is contained in:
Janez T 2026-03-18 20:14:22 +01:00
parent a21b83b127
commit f25d7a882a
5 changed files with 63 additions and 56 deletions

View file

@ -93,7 +93,8 @@
#define RESP_CODE_AUTOADD_CONFIG 25
#define RESP_ALLOWED_REPEAT_FREQ 26
#define RESP_CODE_CHANNEL_DATA_RECV 27
#define RESP_CODE_CHANNEL_DATA_RECV_V3 28
#define MAX_CHANNEL_DATA_LENGTH (MAX_FRAME_SIZE - 12)
#define SEND_TIMEOUT_BASE_MILLIS 500
#define FLOOD_SEND_TIMEOUT_FACTOR 16.0f
@ -208,7 +209,7 @@ void MyMesh::updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, co
bool MyMesh::Frame::isChannelMsg() const {
return buf[0] == RESP_CODE_CHANNEL_MSG_RECV || buf[0] == RESP_CODE_CHANNEL_MSG_RECV_V3 ||
buf[0] == RESP_CODE_CHANNEL_DATA_RECV || buf[0] == RESP_CODE_CHANNEL_DATA_RECV_V3;
buf[0] == RESP_CODE_CHANNEL_DATA_RECV;
}
void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
@ -570,28 +571,26 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
void MyMesh::onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint32_t timestamp, uint8_t data_type,
const uint8_t *data, size_t data_len) {
int i = 0;
if (app_target_ver >= 3) {
out_frame[i++] = RESP_CODE_CHANNEL_DATA_RECV_V3;
out_frame[i++] = (int8_t)(pkt->getSNR() * 4);
out_frame[i++] = 0; // reserved1
out_frame[i++] = 0; // reserved2
} else {
out_frame[i++] = RESP_CODE_CHANNEL_DATA_RECV;
if (data_len > MAX_CHANNEL_DATA_LENGTH) {
MESH_DEBUG_PRINTLN("onChannelDataRecv: dropping payload_len=%d exceeds frame limit=%d",
(uint32_t)data_len, (uint32_t)MAX_CHANNEL_DATA_LENGTH);
return;
}
int i = 0;
out_frame[i++] = RESP_CODE_CHANNEL_DATA_RECV;
out_frame[i++] = (int8_t)(pkt->getSNR() * 4);
out_frame[i++] = 0; // reserved1
out_frame[i++] = 0; // reserved2
uint8_t channel_idx = findChannelIdx(channel);
out_frame[i++] = channel_idx;
out_frame[i++] = pkt->isRouteFlood() ? pkt->path_len : 0xFF;
out_frame[i++] = data_type;
out_frame[i++] = (uint8_t)data_len;
memcpy(&out_frame[i], &timestamp, 4);
i += 4;
size_t available = MAX_FRAME_SIZE - i;
if (data_len > available) {
MESH_DEBUG_PRINTLN("onChannelDataRecv(): payload_len=%d exceeds frame space=%d, truncating", (uint32_t)data_len, (uint32_t)available);
data_len = available;
}
int copy_len = (int)data_len;
if (copy_len > 0) {
memcpy(&out_frame[i], data, copy_len);
@ -1108,8 +1107,8 @@ void MyMesh::handleCmdFrame(size_t len) {
writeErrFrame(ERR_CODE_NOT_FOUND); // bad channel_idx
} else if (data_type != DATA_TYPE_CUSTOM) {
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
} else if (payload_len > MAX_GROUP_DATA_LENGTH) {
MESH_DEBUG_PRINTLN("CMD_SEND_CHANNEL_DATA payload too long: %d > %d", payload_len, MAX_GROUP_DATA_LENGTH);
} else if (payload_len > MAX_CHANNEL_DATA_LENGTH) {
MESH_DEBUG_PRINTLN("CMD_SEND_CHANNEL_DATA payload too long: %d > %d", payload_len, MAX_CHANNEL_DATA_LENGTH);
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
} else if (sendGroupData(msg_timestamp, channel.channel, data_type, payload, payload_len)) {
writeOKFrame();