Skip to content
Open
Show file tree
Hide file tree
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
10 changes: 7 additions & 3 deletions examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,10 @@ uint8_t MyMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_tim
}

void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data, uint8_t len) {
if (len < 4) return;
if (len > MAX_FRAME_SIZE - 4) { // largest frame below writes 8-byte header + (len - 4) bytes
len = MAX_FRAME_SIZE - 4;
}
uint32_t tag;
memcpy(&tag, data, 4);

Expand All @@ -696,12 +700,12 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
pending_login = 0;

int i = 0;
if (memcmp(&data[4], "OK", 2) == 0) { // legacy Repeater login OK response
if (len >= 6 && memcmp(&data[4], "OK", 2) == 0) { // legacy Repeater login OK response
out_frame[i++] = PUSH_CODE_LOGIN_SUCCESS;
out_frame[i++] = 0; // legacy: is_admin = false
memcpy(&out_frame[i], contact.id.pub_key, 6);
i += 6; // pub_key_prefix
} else if (data[4] == RESP_SERVER_LOGIN_OK) { // new login response
} else if (len >= 8 && data[4] == RESP_SERVER_LOGIN_OK) { // new login response
uint16_t keep_alive_secs = ((uint16_t)data[5]) * 16;
if (keep_alive_secs > 0) {
startConnection(contact, keep_alive_secs);
Expand All @@ -713,7 +717,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
memcpy(&out_frame[i], &tag, 4);
i += 4; // NEW: include server timestamp
out_frame[i++] = data[7]; // NEW (v7): ACL permissions
out_frame[i++] = data[12]; // FIRMWARE_VER_LEVEL
out_frame[i++] = (len >= 13) ? data[12] : 0; // FIRMWARE_VER_LEVEL
} else {
out_frame[i++] = PUSH_CODE_LOGIN_FAIL;
out_frame[i++] = 0; // reserved
Expand Down
14 changes: 10 additions & 4 deletions src/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,23 @@ int Mesh::searchChannelsByHash(const uint8_t* hash, GroupChannel channels[], int

DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
if (pkt->isRouteDirect() && pkt->getPayloadType() == PAYLOAD_TYPE_TRACE) {
if (pkt->path_len < MAX_PATH_SIZE) {
if (pkt->path_len < MAX_PATH_SIZE && pkt->payload_len >= 9) {
uint8_t i = 0;
uint32_t trace_tag;
memcpy(&trace_tag, &pkt->payload[i], 4); i += 4;
uint32_t auth_code;
memcpy(&auth_code, &pkt->payload[i], 4); i += 4;
uint8_t flags = pkt->payload[i++];
uint8_t path_sz = flags & 0x03; // NEW v1.11+: lower 2 bits is path hash size
uint8_t hash_sz = (uint8_t)(1 << path_sz);

uint8_t len = pkt->payload_len - i;
// path_len*entry_size can exceed 255 (path_len up to 63, entry_size up to 8);
// a uint8_t offset would wrap and steer the isHashMatch() read to the wrong place.
uint16_t offset = (uint16_t)pkt->path_len << path_sz;
if (offset >= len) { // TRACE has reached end of given path
onTraceRecv(pkt, trace_tag, auth_code, flags, pkt->path, &pkt->payload[i], len);
} else if (self_id.isHashMatch(&pkt->payload[i + offset], 1 << path_sz) && allowPacketForward(pkt) && !_tables->wasSeen(pkt)) {
} else if (offset + hash_sz <= len && self_id.isHashMatch(&pkt->payload[i + offset], hash_sz) && allowPacketForward(pkt) && !_tables->wasSeen(pkt)) {
_tables->markSeen(pkt);
// append SNR (Not hash!)
pkt->path[pkt->path_len++] = (int8_t) (pkt->getSNR()*4);
Expand All @@ -67,7 +68,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
return ACTION_RELEASE;
}

if (pkt->isRouteDirect() && pkt->getPayloadType() == PAYLOAD_TYPE_CONTROL && (pkt->payload[0] & 0x80) != 0) {
if (pkt->isRouteDirect() && pkt->getPayloadType() == PAYLOAD_TYPE_CONTROL && pkt->payload_len > 0 && (pkt->payload[0] & 0x80) != 0) {
if (pkt->getPathHashCount() == 0) {
onControlDataRecv(pkt);
}
Expand Down Expand Up @@ -166,7 +167,12 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
}
uint8_t hash_size = (path_len >> 6) + 1;
uint8_t hash_count = path_len & 63;
uint8_t* path = &data[k]; k += hash_size*hash_count;
uint8_t path_byte_len = hash_size * hash_count;
if (k + path_byte_len + 1 > len) {
MESH_DEBUG_PRINTLN("%s PAYLOAD_TYPE_PATH, incomplete payload: len=%d", getLogDateTime(), len);
break; // reject bad encoding
}
uint8_t* path = &data[k]; k += path_byte_len;
uint8_t extra_type = data[k++] & 0x0F; // upper 4 bits reserved for future use
uint8_t* extra = &data[k];
uint8_t extra_len = len - k; // remainder of packet (may be padded with zeroes!)
Expand Down