diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 8a8e1528..c45b17e0 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -117,7 +117,7 @@ static uint32_t _atoi(const char* sp) { /*------------ Frame Protocol --------------*/ -#define FIRMWARE_VER_CODE 2 +#define FIRMWARE_VER_CODE 3 #ifndef FIRMWARE_BUILD_DATE #define FIRMWARE_BUILD_DATE "3 Mar 2025" @@ -165,8 +165,8 @@ static uint32_t _atoi(const char* sp) { #define RESP_CODE_END_OF_CONTACTS 4 // last reply to CMD_GET_CONTACTS #define RESP_CODE_SELF_INFO 5 // reply to CMD_APP_START #define RESP_CODE_SENT 6 // reply to CMD_SEND_TXT_MSG -#define RESP_CODE_CONTACT_MSG_RECV 7 // a reply to CMD_SYNC_NEXT_MESSAGE -#define RESP_CODE_CHANNEL_MSG_RECV 8 // a reply to CMD_SYNC_NEXT_MESSAGE +#define RESP_CODE_CONTACT_MSG_RECV 7 // a reply to CMD_SYNC_NEXT_MESSAGE (ver < 3) +#define RESP_CODE_CHANNEL_MSG_RECV 8 // a reply to CMD_SYNC_NEXT_MESSAGE (ver < 3) #define RESP_CODE_CURR_TIME 9 // a reply to CMD_GET_DEVICE_TIME #define RESP_CODE_NO_MORE_MESSAGES 10 // a reply to CMD_SYNC_NEXT_MESSAGE #define RESP_CODE_EXPORT_CONTACT 11 @@ -174,6 +174,8 @@ static uint32_t _atoi(const char* sp) { #define RESP_CODE_DEVICE_INFO 13 // a reply to CMD_DEVICE_QEURY #define RESP_CODE_PRIVATE_KEY 14 // a reply to CMD_EXPORT_PRIVATE_KEY #define RESP_CODE_DISABLED 15 +#define RESP_CODE_CONTACT_MSG_RECV_V3 16 // a reply to CMD_SYNC_NEXT_MESSAGE (ver >= 3) +#define RESP_CODE_CHANNEL_MSG_RECV_V3 17 // a reply to CMD_SYNC_NEXT_MESSAGE (ver >= 3) // these are _pushed_ to client app at any time #define PUSH_CODE_ADVERT 0x80 @@ -471,11 +473,18 @@ protected: return checkConnectionsAck(data); } - void queueMessage(const ContactInfo& from, uint8_t txt_type, uint8_t path_len, uint32_t sender_timestamp, const uint8_t* extra, int extra_len, const char *text) { + void queueMessage(const ContactInfo& from, uint8_t txt_type, mesh::Packet* pkt, uint32_t sender_timestamp, const uint8_t* extra, int extra_len, const char *text) { int i = 0; - out_frame[i++] = RESP_CODE_CONTACT_MSG_RECV; + if (app_target_ver >= 3) { + out_frame[i++] = RESP_CODE_CONTACT_MSG_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_CONTACT_MSG_RECV; + } memcpy(&out_frame[i], from.id.pub_key, 6); i += 6; // just 6-byte prefix - out_frame[i++] = path_len; + uint8_t path_len = out_frame[i++] = pkt->isRouteFlood() ? pkt->path_len : 0xFF; out_frame[i++] = txt_type; memcpy(&out_frame[i], &sender_timestamp, 4); i += 4; if (extra_len > 0) { @@ -500,27 +509,35 @@ protected: #endif } - void onMessageRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const char *text) override { + void onMessageRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) override { markConnectionActive(from); // in case this is from a server, and we have a connection - queueMessage(from, TXT_TYPE_PLAIN, path_len, sender_timestamp, NULL, 0, text); + queueMessage(from, TXT_TYPE_PLAIN, pkt, sender_timestamp, NULL, 0, text); } - void onCommandDataRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const char *text) override { + void onCommandDataRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) override { markConnectionActive(from); // in case this is from a server, and we have a connection - queueMessage(from, TXT_TYPE_CLI_DATA, path_len, sender_timestamp, NULL, 0, text); + queueMessage(from, TXT_TYPE_CLI_DATA, pkt, sender_timestamp, NULL, 0, text); } - void onSignedMessageRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) override { + void onSignedMessageRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) override { markConnectionActive(from); saveContacts(); // from.sync_since change needs to be persisted - queueMessage(from, TXT_TYPE_SIGNED_PLAIN, path_len, sender_timestamp, sender_prefix, 4, text); + queueMessage(from, TXT_TYPE_SIGNED_PLAIN, pkt, sender_timestamp, sender_prefix, 4, text); } - void onChannelMessageRecv(const mesh::GroupChannel& channel, int in_path_len, uint32_t timestamp, const char *text) override { + void onChannelMessageRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, const char *text) override { int i = 0; - out_frame[i++] = RESP_CODE_CHANNEL_MSG_RECV; + if (app_target_ver >= 3) { + out_frame[i++] = RESP_CODE_CHANNEL_MSG_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_MSG_RECV; + } + out_frame[i++] = 0; // FUTURE: channel_idx (will just be 'public' for now) - out_frame[i++] = in_path_len < 0 ? 0xFF : in_path_len; + uint8_t path_len = out_frame[i++] = pkt->isRouteFlood() ? pkt->path_len : 0xFF; out_frame[i++] = TXT_TYPE_PLAIN; memcpy(&out_frame[i], ×tamp, 4); i += 4; int tlen = strlen(text); // TODO: UTF-8 ?? @@ -538,7 +555,7 @@ protected: soundBuzzer(); } #ifdef DISPLAY_CLASS - ui_task.showMsgPreview(in_path_len < 0 ? 0xFF : in_path_len, "Public", text); + ui_task.showMsgPreview(path_len, "Public", text); #endif } diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 2051d4a0..b03c479f 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -254,8 +254,8 @@ protected: return false; } - void onMessageRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const char *text) override { - Serial.printf("(%s) MSG -> from %s\n", path_len == 0xFF ? "DIRECT" : "FLOOD", from.name); + void onMessageRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) override { + Serial.printf("(%s) MSG -> from %s\n", pkt->isRouteDirect() ? "DIRECT" : "FLOOD", from.name); Serial.printf(" %s\n", text); if (strcmp(text, "clock sync") == 0) { // special text command @@ -263,16 +263,16 @@ protected: } } - void onCommandDataRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const char *text) override { + void onCommandDataRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) override { } - void onSignedMessageRecv(const ContactInfo& from, uint8_t path_len, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) override { + void onSignedMessageRecv(const ContactInfo& from, mesh::Packet* pkt, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) override { } - void onChannelMessageRecv(const mesh::GroupChannel& channel, int in_path_len, uint32_t timestamp, const char *text) override { - if (in_path_len < 0) { + void onChannelMessageRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, const char *text) override { + if (pkt->isRouteDirect()) { Serial.printf("PUBLIC CHANNEL MSG -> (Direct!)\n"); } else { - Serial.printf("PUBLIC CHANNEL MSG -> (Flood) hops %d\n", in_path_len); + Serial.printf("PUBLIC CHANNEL MSG -> (Flood) hops %d\n", pkt->path_len); } Serial.printf(" %s\n", text); } diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index db937787..4ae0b1b1 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -105,7 +105,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender data[len] = 0; // need to make a C string again, with null terminator if (flags == TXT_TYPE_PLAIN) { - onMessageRecv(from, packet->isRouteFlood() ? packet->path_len : 0xFF, timestamp, (const char *) &data[5]); // let UI know + onMessageRecv(from, packet, timestamp, (const char *) &data[5]); // let UI know 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); @@ -126,7 +126,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender } } } else if (flags == TXT_TYPE_CLI_DATA) { - onCommandDataRecv(from, packet->isRouteFlood() ? packet->path_len : 0xFF, timestamp, (const char *) &data[5]); // let UI know + onCommandDataRecv(from, packet, timestamp, (const char *) &data[5]); // let UI know // NOTE: no ack expected for CLI_DATA replies if (packet->isRouteFlood()) { @@ -138,7 +138,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender if (timestamp > from.sync_since) { // make sure 'sync_since' is up-to-date from.sync_since = timestamp; } - onSignedMessageRecv(from, packet->isRouteFlood() ? packet->path_len : 0xFF, timestamp, &data[5], (const char *) &data[9]); // let UI know + onSignedMessageRecv(from, packet, timestamp, &data[5], (const char *) &data[9]); // let UI know uint32_t ack_hash; // calc truncated hash of the message timestamp + text + OUR pub_key, to prove to sender that we got it mesh::Utils::sha256((uint8_t *) &ack_hash, 4, data, 9 + strlen((char *)&data[9]), self_id.pub_key, PUB_KEY_SIZE); @@ -266,7 +266,7 @@ void BaseChatMesh::onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mes data[len] = 0; // need to make a C string again, with null terminator // notify UI of this new message - onChannelMessageRecv(channel, packet->isRouteFlood() ? packet->path_len : -1, timestamp, (const char *) &data[5]); // let UI know + onChannelMessageRecv(channel, packet, timestamp, (const char *) &data[5]); // let UI know } } diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index d2b38c7a..8d22cbea 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -100,13 +100,13 @@ protected: virtual void onDiscoveredContact(ContactInfo& contact, bool is_new) = 0; virtual bool processAck(const uint8_t *data) = 0; virtual void onContactPathUpdated(const ContactInfo& contact) = 0; - virtual void onMessageRecv(const ContactInfo& contact, uint8_t path_len, uint32_t sender_timestamp, const char *text) = 0; - virtual void onCommandDataRecv(const ContactInfo& contact, uint8_t path_len, uint32_t sender_timestamp, const char *text) = 0; - virtual void onSignedMessageRecv(const ContactInfo& contact, uint8_t path_len, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) = 0; + virtual void onMessageRecv(const ContactInfo& contact, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) = 0; + virtual void onCommandDataRecv(const ContactInfo& contact, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) = 0; + virtual void onSignedMessageRecv(const ContactInfo& contact, mesh::Packet* pkt, uint32_t sender_timestamp, const uint8_t *sender_prefix, const char *text) = 0; virtual uint32_t calcFloodTimeoutMillisFor(uint32_t pkt_airtime_millis) const = 0; virtual uint32_t calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t path_len) const = 0; virtual void onSendTimeout() = 0; - virtual void onChannelMessageRecv(const mesh::GroupChannel& channel, int in_path_len, uint32_t timestamp, const char *text) = 0; + virtual void onChannelMessageRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, const char *text) = 0; virtual void onContactResponse(const ContactInfo& contact, const uint8_t* data, uint8_t len) = 0; virtual void onContactTraceRecv(const ContactInfo& contact, uint32_t sender_timestamp, const uint8_t hash[], int8_t snr[], uint8_t path_len) = 0;