SensorMesh: add the possibility to receive msgs from admin

This commit is contained in:
Florent
2025-08-27 21:19:12 +02:00
parent 0959e64d11
commit 136f733df5
2 changed files with 73 additions and 29 deletions

View File

@@ -613,6 +613,23 @@ void SensorMesh::getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) {
} }
} }
void SensorMesh::sendAckTo(const ContactInfo& dest, uint32_t ack_hash) {
if (dest.out_path_len < 0) {
mesh::Packet* ack = createAck(ack_hash);
if (ack) sendFlood(ack, TXT_ACK_DELAY);
} else {
uint32_t d = TXT_ACK_DELAY;
if (getExtraAckTransmitCount() > 0) {
mesh::Packet* a1 = createMultiAck(ack_hash, 1);
if (a1) sendDirect(a1, dest.out_path, dest.out_path_len, d);
d += 300;
}
mesh::Packet* a2 = createAck(ack_hash);
if (a2) sendDirect(a2, dest.out_path, dest.out_path_len, d);
}
}
void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) { void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) {
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];
if (i < 0 || i >= num_contacts) { if (i < 0 || i >= num_contacts) {
@@ -656,9 +673,23 @@ void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_i
memcpy(&sender_timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong) memcpy(&sender_timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong)
uint flags = (data[4] >> 2); // message attempt number, and other flags uint flags = (data[4] >> 2); // message attempt number, and other flags
if (!(flags == TXT_TYPE_CLI_DATA)) { if (sender_timestamp > from.last_timestamp) { // prevent replay attacks
MESH_DEBUG_PRINTLN("onPeerDataRecv: unsupported text type received: flags=%02x", (uint32_t)flags); if (flags == TXT_TYPE_PLAIN) {
} else if (sender_timestamp > from.last_timestamp) { // prevent replay attacks bool handled = handleIncomingMsg(from, sender_timestamp, &data[5], flags, len - 5);
if (handled) { // if msg was handled then send an ack
uint32_t ack_hash; // calc truncated hash of the message timestamp + text + sender pub_key, to prove to sender that we got it
mesh::Utils::sha256((uint8_t *) &ack_hash, 4, data, 5 + strlen((char *)&data[5]), from.id.pub_key, PUB_KEY_SIZE);
if (packet->isRouteFlood()) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
mesh::Packet* path = createPathReturn(from.id, secret, packet->path, packet->path_len,
PAYLOAD_TYPE_ACK, (uint8_t *) &ack_hash, 4);
if (path) sendFlood(path, TXT_ACK_DELAY);
} else {
sendAckTo(from, ack_hash);
}
}
} else if (flags == TXT_TYPE_CLI_DATA) {
from.last_timestamp = sender_timestamp; from.last_timestamp = sender_timestamp;
from.last_activity = getRTCClock()->getCurrentTime(); from.last_activity = getRTCClock()->getCurrentTime();
@@ -689,12 +720,24 @@ void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_i
} }
} }
} }
} else {
MESH_DEBUG_PRINTLN("onPeerDataRecv: unsupported text type received: flags=%02x", (uint32_t)flags);
}
} else { } else {
MESH_DEBUG_PRINTLN("onPeerDataRecv: possible replay attack detected"); MESH_DEBUG_PRINTLN("onPeerDataRecv: possible replay attack detected");
} }
} }
} }
bool SensorMesh::handleIncomingMsg(ContactInfo& from, uint32_t timestamp, uint8_t* data, uint flags, size_t len) {
MESH_DEBUG_PRINT("handleIncomingMsg: unhandled msg from ");
#ifdef MESH_DEBUG
mesh::Utils::printHex(Serial, from.id.pub_key, PUB_KEY_SIZE);
Serial.printf(": %s\n", data);
#endif
return false;
}
bool SensorMesh::onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) { bool SensorMesh::onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) {
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];
if (i < 0 || i >= num_contacts) { if (i < 0 || i >= num_contacts) {

View File

@@ -140,7 +140,8 @@ protected:
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override; void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override;
bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override; bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override; void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override;
virtual bool handleIncomingMsg(ContactInfo& from, uint32_t timestamp, uint8_t* data, uint flags, size_t len);
void sendAckTo(const ContactInfo& dest, uint32_t ack_hash);
private: private:
FILESYSTEM* _fs; FILESYSTEM* _fs;
unsigned long next_local_advert, next_flood_advert; unsigned long next_local_advert, next_flood_advert;