mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-16 16:52:44 +00:00
joystick UI: channel-send heard-repeat feedback
After broadcasting a group message, wait 5s to see if any neighbor
repeated the flood and use the outcome to mark the on-device entry
and the BLE-app mirror.
- ContentionTracker gets extractDupeCount(hash): finds the tracked
entry, captures dupe_count, finalizes (folds into EMA, marks
inactive), returns the count or -1.
- BaseChatMesh::sendGroupMessage gains an optional out_hash param;
when set, the FNV-1a packet hash is also pre-registered with the
contention tracker so heard retransmits get counted (originated
floods weren't tracked before, only relays).
- Mesh::getContentionTracker() promoted to public so the UI can
query after the feedback window.
JoystickUITask grows a 4-slot pending-channel table with per-slot
k_timer (5s one-shot). startPendingChannel() broadcasts, adds the
local _ch_previews entry with path_len = OUT_PATH_SENT, and starts
the feedback timer. The timer ISR sets a feedback_due flag; the
loop's processPendingChannelFeedback() picks it up, calls
extractDupeCount(), and rewrites the preview's path_len to
OUT_PATH_SENT_HEARD (0xFD) or OUT_PATH_SENT_UNHEARD (0xFC) — which
formatHopCount renders as "sent+" / "sent?".
The deferred BLE-app mirror queues only on outcome with body prefix
"(>>✓) " (heard) or "(>>✗) " (not heard). queueLocalSentChannelMessage
gains a heard_repeat parameter for the selection.
Both channel send entry points (sendComposedMessage's channel branch
and sendChannelMessage) now route through startPendingChannel().
This commit is contained in:
@@ -826,7 +826,7 @@ void CompanionMesh::queueLocalSentContactMessage(const ContactInfo &contact,
|
||||
}
|
||||
|
||||
void CompanionMesh::queueLocalSentChannelMessage(uint8_t channel_idx,
|
||||
uint32_t timestamp, const char *text)
|
||||
uint32_t timestamp, const char *text, bool heard_repeat)
|
||||
{
|
||||
if (!text) return;
|
||||
uint8_t frame[MAX_FRAME_SIZE];
|
||||
@@ -846,12 +846,13 @@ void CompanionMesh::queueLocalSentChannelMessage(uint8_t channel_idx,
|
||||
put_le32(&frame[i], timestamp);
|
||||
i += 4;
|
||||
|
||||
/* Channel wire-text is "<sender_name>: <body>" — the same prefix that
|
||||
* BaseChatMesh::sendGroupMessage applied before transmitting over LoRa.
|
||||
* The phone app parses up to the first ':' as the sender, the rest as
|
||||
* the body, so we need to mirror that format here or the message
|
||||
* shows up empty with the sender slot empty too. */
|
||||
int n = snprintf((char *)&frame[i], sizeof(frame) - i, "%s: ", prefs.node_name);
|
||||
/* Channel wire-text is "<sender_name>: <body>" — the same prefix
|
||||
* BaseChatMesh::sendGroupMessage applied over LoRa. Prepend a
|
||||
* heard/unheard marker so the phone app can distinguish whether the
|
||||
* mesh propagated our flood. */
|
||||
const char *marker = heard_repeat ? "(>>\xe2\x9c\x93) " /* (>>✓) UTF-8 */
|
||||
: "(>>\xe2\x9c\x97) "; /* (>>✗) UTF-8 */
|
||||
int n = snprintf((char *)&frame[i], sizeof(frame) - i, "%s%s: ", marker, prefs.node_name);
|
||||
if (n < 0) n = 0;
|
||||
if ((size_t)n > sizeof(frame) - i) n = sizeof(frame) - i;
|
||||
i += n;
|
||||
@@ -862,7 +863,8 @@ void CompanionMesh::queueLocalSentChannelMessage(uint8_t channel_idx,
|
||||
memcpy(&frame[i], text, text_len);
|
||||
i += text_len;
|
||||
|
||||
LOG_DBG("queueLocalSentChannelMessage: frame_len=%d channel_idx=%d", i, channel_idx);
|
||||
LOG_DBG("queueLocalSentChannelMessage: frame_len=%d channel_idx=%d heard=%d",
|
||||
i, channel_idx, (int)heard_repeat);
|
||||
queueOfflineMessage(frame, i);
|
||||
sendPush(PUSH_CODE_MSG_WAITING);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user