Merge upstream dev companion CLI updates

This commit is contained in:
mikecarper committed 2026-08-28 17:31:28 -07:00
commit 2143d3e04b
46 files changed
+1976 -163

No files matched your search

+47 -12
View File
@@ -15,6 +15,8 @@
#define TXT_ACK_DELAY 200
#endif
#define CLI_REPLY_DELAY_MILLIS 600
bool BaseChatMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) {
return sendFlood(pkt, delay_millis);
}
@@ -274,8 +276,8 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
ContactInfo& from = contacts[i];
if (type == PAYLOAD_TYPE_TXT_MSG && len > 5) {
uint32_t timestamp;
memcpy(&timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong)
uint32_t sender_timestamp;
memcpy(&sender_timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong)
uint8_t flags = data[4] >> 2; // message attempt number, and other flags
// len can be > original length, but 'text' will be padded with zeroes
@@ -283,7 +285,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
if (flags == TXT_TYPE_PLAIN) {
from.lastmod = getRTCClock()->getCurrentTime(); // update last heard time
onMessageRecv(from, packet, timestamp, (const char *) &data[5]); // let UI know
onMessageRecv(from, packet, sender_timestamp, (const char *) &data[5]); // let UI know
int text_len = strlen((char *)&data[5]);
uint8_t ack_hash[6]; // calc truncated hash of the message timestamp + text + sender pub_key, to prove to sender that we got it
@@ -301,20 +303,50 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
sendAckTo(from, ack_hash, 6);
}
} else if (flags == TXT_TYPE_CLI_DATA) {
onCommandDataRecv(from, packet, timestamp, (const char *) &data[5]); // let UI know
char *text = (char *)&data[5];
onCommandDataRecv(from, packet, sender_timestamp, text); // let UI know
// NOTE: no ack expected for CLI_DATA replies
if (packet->isRouteFlood()) {
// let this sender know path TO here, so they can use sendDirect() (NOTE: no ACK as extra)
mesh::Packet* path = createPathReturn(from.id, secret, packet->path, packet->path_len, 0, NULL, 0);
// Let this sender learn a direct path without adding an ACK.
mesh::Packet* path = createPathReturn(from.id, secret, packet->path,
packet->path_len, 0, NULL, 0);
if (path) sendFloodScoped(from, path);
}
} else if (flags == TXT_TYPE_CLI_COMMAND) {
uint8_t temp[166];
char *command = (char *)&data[5];
char *reply = (char *)&temp[5];
*reply = 0;
onCLICommandRecv(from, packet, sender_timestamp, command, reply); // let UI know
// NOTE: no ack expected for CLI_COMMAND replies
int text_len = strlen(reply);
if (text_len > 0) {
uint32_t timestamp = getRTCClock()->getCurrentTimeUnique();
if (timestamp == sender_timestamp) {
// WORKAROUND: the two timestamps need to be different, in the CLI view
timestamp++;
}
memcpy(temp, &timestamp, 4);
temp[4] = (TXT_TYPE_CLI_DATA << 2);
auto reply_pkt = createDatagram(PAYLOAD_TYPE_TXT_MSG, from.id, secret, temp, 5 + text_len);
if (reply_pkt) {
if (from.out_path_len == OUT_PATH_UNKNOWN) {
sendFloodScoped(from, reply_pkt, CLI_REPLY_DELAY_MILLIS);
} else {
sendDirect(reply_pkt, from.out_path, from.out_path_len, CLI_REPLY_DELAY_MILLIS);
}
}
}
} else if (flags == TXT_TYPE_SIGNED_PLAIN) {
if (timestamp > from.sync_since) { // make sure 'sync_since' is up-to-date
from.sync_since = timestamp;
if (sender_timestamp > from.sync_since) { // make sure 'sync_since' is up-to-date
from.sync_since = sender_timestamp;
}
from.lastmod = getRTCClock()->getCurrentTime(); // update last heard time
onSignedMessageRecv(from, packet, timestamp, &data[5], (const char *) &data[9]); // let UI know
onSignedMessageRecv(from, packet, sender_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);
@@ -535,15 +567,18 @@ int BaseChatMesh::sendMessage(const ContactInfo& recipient, uint32_t timestamp,
int BaseChatMesh::sendCommandData(const ContactInfo& recipient,
uint32_t timestamp, uint8_t attempt,
const char* text, uint32_t& est_timeout,
uint8_t txt_type, const char* text,
uint32_t& est_timeout,
uint32_t logical_request_id) {
est_timeout = 0;
int text_len = strlen(text);
if (text_len > MAX_TEXT_LEN) return MSG_SEND_FAILED;
const size_t max_text_len = logical_request_id == 0
? MAX_TEXT_LEN : MAX_CORRELATED_CLI_TEXT_LEN;
if ((size_t)text_len > max_text_len) return MSG_SEND_FAILED;
uint8_t temp[5 + MAX_TEXT_LEN + mesh::RemoteCliRequest::EXTENSION_SIZE];
memcpy(temp, &timestamp, 4); // mostly an extra blob to help make packet_hash unique
temp[4] = (attempt & 3) | (TXT_TYPE_CLI_DATA << 2);
temp[4] = (attempt & 3) | (txt_type << 2);
memcpy(&temp[5], text, text_len);
size_t payload_len = 5 + text_len;