Repository navigation
Feat/tak dm receipts - #1283
Feat/tak dm receipts#1283
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the
Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
6f9c4de to
1f73153
Compare
Each radio's "Messaging in ATAK" section gains a "Direct messages" switch. With it on: - Companions this radio can message (a MeshCore companion whose key it holds, any Meshtastic node) get a chat endpoint on their marker, so ATAK offers to message them. Repeaters, room servers and sensors do not. - A message to a companion's contact goes out from this radio through the Chat send path as a direct message, prefixed [CALLSIGN], and shows in Chat. - A DM heard from a companion goes to the ATAK device that last wrote to it, or to every connected device when none has; it is held (with channel messages, 50 max, 24 h) while the device it is for is away. Retried copies are relayed once. Command replies from repeaters and room servers are not relayed. - A companion with no marker on the map gets a contact at 0, 0 for a day after the last message, under its marker's uid, so a later marker replaces it. - A message ATAK cannot deliver (DMs off for the radio, or not a node this radio can reach) gets a note in its conversation saying why. - DMs and chat endpoints are never sent to the remote TAK server. New IPC: tak:pushDirectMessage and tak:setDirectMessaging. TakInboundChat now carries a target (channel or direct) in place of channelKey. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHFPfW7vZXpRdR3tBBTX3r
A direct message sent from ATAK now tells the device that wrote it how it went, once mesh-client's automatic resends settle: - Acknowledged by the companion: a b-t-f-d delivery receipt naming the device's message id, so ATAK marks it delivered. - Still unacknowledged after the last resend (4 tries): a "Not confirmed" note in the conversation, quoting the message. For MeshCore it adds that a flood advert from each radio usually fixes a DM that keeps failing. - Never sent (no radio could take it): a "Not sent to the mesh" note. A note for a device that is away waits with the held messages; a receipt is dropped. Main waits up to 30 minutes for an outcome. The resend controller reports how each send's lineage ends (acked or gave up), keyed by the first send's store id through re-keys and resends, via subscribeAutoResendOutcomes. takDmStatus.ts watches DMs sent from TAK and reports their outcome over the new tak:dmStatus IPC, keyed by a dmRef main attaches to each inbound DM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHFPfW7vZXpRdR3tBBTX3r
1f73153 to
f7a0948
Compare
The radio TAK uses per protocol is recorded in an effect, so for a moment after a switch to another radio of the same protocol it can still name the old one, whose transport may still be open. findTakSendTargets now drops a direct target whose recorded radio is not the protocol's current identity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EHFPfW7vZXpRdR3tBBTX3r
Failed direct sends reach the originating client: valid for this PR on its own, and handled in the next PR of the stack, Colorado-Mesh#1283 (delivery receipts). There, main attaches a dmRef to each direct message. When relayTakChatToMesh fails to send, or finds no radio that can send, it reports not-sent over the new tak:dmStatus IPC. TakServerManager.reportDmOutcome then writes "mesh-client: Not sent to the mesh: …" into that conversation, on the device that wrote, holding it if that device is away. The same channel carries "delivered" and "Not confirmed", so I've kept it in Colorado-Mesh#1283 rather than add a separate IPC here. Stale protocol radio: valid, and fixed in this PR. findTakSendTargets now drops a direct target whose recorded radio isn't the protocol's current identity (getIdentityIdForProtocol, the resolver App uses). A test covers the switch window.
Failed direct sends reach the originating client: valid for this PR on its own, and handled in the next PR of the stack, Colorado-Mesh#1283 (delivery receipts). There, main attaches a dmRef to each direct message. When relayTakChatToMesh fails to send, or finds no radio that can send, it reports not-sent over the new tak:dmStatus IPC. TakServerManager.reportDmOutcome then writes "mesh-client: Not sent to the mesh: …" into that conversation, on the device that wrote, holding it if that device is away. The same channel carries "delivered" and "Not confirmed", so I've kept it in Colorado-Mesh#1283 rather than add a separate IPC here. Stale protocol radio: valid, and fixed in this PR. findTakSendTargets now drops a direct target whose recorded radio isn't the protocol's current identity (getIdentityIdForProtocol, the resolver App uses). A test covers the switch window.
|
@coderabbitai full review |
|
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Fifth and last of the TAK messaging PRs. **Builds on #1283** (which builds on #1282 and #1280), so until those merge this PR also shows their commits; review the top commit only. ## What it does Reticulum joins MeshCore and Meshtastic for direct messages with ATAK. It has its own **Reticulum messaging in ATAK** section in the TAK panel, holding only a **Direct messages** switch (off by default), since Reticulum has no channels to serve. With it on: - **Peers with a position.** An LXMF peer whose delivery destination is known under its own node id gets a chat endpoint on its `RN-` marker, so ATAK can message it. - A peer whose LXMF address belongs to another destination (a telephony or bare identity hash that remaps) stays a plain marker, because its replies would arrive from a different contact. - RMAP interfaces stay plain markers. - **Peers with no position.** These appear at 0, 0 only once mesh-client has a conversation with them: a DM sent or received, before or since TAK was running. So ATAK's contact list doesn't fill with every peer heard. - The renderer sends main up to 64 such peers, most recent first, over the new `tak:setDirectPeers` IPC. - Main announces their contacts along with the channel contacts, and removes a contact when its peer drops off the list. - **ATAK → Reticulum.** A message goes out as an LXMF DM through the Chat send path, with Chat's automatic resends. Its delivery proof sets the message to acked, which gives the device PR 4's receipt; with no proof after the resends, the device gets the "Not confirmed" note. - **Reticulum → ATAK.** `ingestReticulumLxmfPayload` hands each newly stored inbound LXMF message on to ATAK. Status updates, our own sends and reactions are left out. As with the other radios, a reply goes to the device that last wrote, or to every device when none has. - Nothing about direct messages goes to the remote TAK server. ## Changes - **`shared`.** `TAK_DM_PROTOCOLS` gains `reticulum`, plus `TakDirectPeer` and `TAK_DIRECT_PEERS_MAX`. - **`main`.** - `parseTakDirectPeers` validates the peer list. - `TakServerManager.setDirectPeers` stores conversation peers. They are messageable, announced at 0, 0 while they have no marker, and added or removed when the Reticulum switch changes. - New `tak:setDirectPeers` handler, limited to 60 a minute. - **`renderer`.** - `canTakDirectMessage` handles Reticulum. - `listTakConversationPeers` builds the peer list from the message store, named from the node store. - `useTakInboundChat` records the Reticulum radio and keeps main told which peers have conversations. It only builds the list while TAK is up and the switch is on. - The Reticulum ingest relays new DMs. - `TakDirectMessagesSection` and its wiring in `TakServerPanel` and App; strings, settings search and the README. ## Checks - 2,539 tests pass across TAK, ingest, Reticulum send, auto-resend, settings search and the send hook. - ESLint and Prettier are clean on the changed files, and both typechecks pass. - `check:i18n`, `check:ipc-contract`, `check:console-log` and `check:log-injection` pass. - The main bundle grows 667,331 → 669,365 bytes (+2,034), about 18.8 KB under the 672 KiB budget. ## Still to try on a device - Start an LXMF conversation in mesh-client with a peer that has no position, then carry it on from ATAK. The peer appears at 0, 0, the message arrives, the reply lands on the device that wrote, and ATAK marks it delivered. - A peer with a position can be messaged from its marker. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EHFPfW7vZXpRdR3tBBTX3r <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Reticulum LXMF conversation peers with known delivery addresses can be contacted through TAK direct messaging. Configure Reticulum direct messaging from TAK settings. * Positionless Reticulum peers appear in TAK at coordinates 0, 0 after a conversation is established. * **Improvements** * TAK provides delivery acknowledgements and notices for unconfirmed or unsent direct messages, including resend failures. MeshCore failure notices include a flood-advert hint. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Joey Stanford <nv0n@coloradomesh.org>
Summary by CodeRabbit