feat(mesh): native-unicast DMs, contact import/remove, reachability, contact search
- DMs now use native meshcore unicast (CMD_SEND_TXT_MSG) instead of @DM2 channel broadcasts: private (E2E-encrypted to the recipient pubkey by firmware), off the public channel, and decodable by stock clients. Plain text (split, not MC-chunked) to non-archipelago contacts; typed envelopes to archy peers. - !ai replies now DM the asker privately (RadioDm) instead of broadcasting on ch0. - Auto contact-import: a heard advert (PUSH_CONTACT_ADVERT/0x80, 32-byte pubkey) is added via CMD_ADD_UPDATE_CONTACT (0x09) so contacts appear without a flood advert. - clear-all now DELETES firmware contacts via CMD_REMOVE_CONTACT (0x0F) instead of blocklisting; blocking filter removed entirely. Wiped contacts return when reachable. - Contact reachability: MeshPeer carries last_advert + reachable (path-based); UI shows a reachability dot. - Peers list: contact search box (filter by name/DID/npub/pubkey) with a clear button. - send_message routes stock contacts as plain native text (fixes garbled envelopes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9f2edf6b7a
commit
f0fdc23cc9
@@ -30,6 +30,13 @@ pub const CMD_SYNC_NEXT_MESSAGE: u8 = 0x0A;
|
||||
/// known" — without this, the firmware silently drops outbound TXT_MSG
|
||||
/// frames to such contacts.
|
||||
pub const CMD_RESET_PATH: u8 = 0x0D;
|
||||
/// CMD_ADD_UPDATE_CONTACT (0x09): add or update a contact in the firmware
|
||||
/// table. 144-byte frame (see `build_add_contact`).
|
||||
pub const CMD_ADD_UPDATE_CONTACT: u8 = 0x09;
|
||||
/// CMD_REMOVE_CONTACT (0x0F): `[0x0F][pub_key:32]` — delete a contact from the
|
||||
/// firmware's persistent table (used by clear-all so wiped contacts actually
|
||||
/// go away and only return when they re-advertise).
|
||||
pub const CMD_REMOVE_CONTACT: u8 = 0x0F;
|
||||
pub const CMD_SET_RADIO_PARAMS: u8 = 0x0B;
|
||||
pub const CMD_SET_RADIO_TX_POWER: u8 = 0x0C;
|
||||
pub const CMD_SET_TUNING_PARAMS: u8 = 0x15;
|
||||
@@ -258,6 +265,45 @@ pub fn build_reset_path(pubkey: &[u8; 32]) -> Vec<u8> {
|
||||
encode_frame(&data)
|
||||
}
|
||||
|
||||
/// CMD_REMOVE_CONTACT (0x0F): `[0x0F][pub_key:32]`. Removes the contact from
|
||||
/// the firmware's persistent contact table.
|
||||
pub fn build_remove_contact(pubkey: &[u8; 32]) -> Vec<u8> {
|
||||
let mut data = vec![CMD_REMOVE_CONTACT];
|
||||
data.extend_from_slice(pubkey);
|
||||
encode_frame(&data)
|
||||
}
|
||||
|
||||
/// CMD_ADD_UPDATE_CONTACT (0x09): add/update a contact. 144-byte body:
|
||||
/// `[0x09][pub_key:32][type:1][flags:1][out_path_len:1][out_path:64][name:32]
|
||||
/// [last_advert:4 LE][adv_lat:4 LE][adv_lon:4 LE]`.
|
||||
/// `name` is zero-padded to 32 bytes (the firmware fills it from the heard
|
||||
/// advert on its side too, so an empty name still resolves on get-contacts).
|
||||
pub fn build_add_contact(
|
||||
pubkey: &[u8; 32],
|
||||
contact_type: u8,
|
||||
flags: u8,
|
||||
out_path_len: u8,
|
||||
name: &str,
|
||||
last_advert: u32,
|
||||
) -> Vec<u8> {
|
||||
let mut data = Vec::with_capacity(144);
|
||||
data.push(CMD_ADD_UPDATE_CONTACT);
|
||||
data.extend_from_slice(pubkey); // 32
|
||||
data.push(contact_type); // 1
|
||||
data.push(flags); // 1
|
||||
data.push(out_path_len); // 1
|
||||
data.extend_from_slice(&[0u8; 64]); // out_path (64)
|
||||
let mut name_buf = [0u8; 32];
|
||||
let nb = name.as_bytes();
|
||||
let n = nb.len().min(32);
|
||||
name_buf[..n].copy_from_slice(&nb[..n]);
|
||||
data.extend_from_slice(&name_buf); // name (32)
|
||||
data.extend_from_slice(&last_advert.to_le_bytes()); // last_advert (4)
|
||||
data.extend_from_slice(&0i32.to_le_bytes()); // adv_lat (4)
|
||||
data.extend_from_slice(&0i32.to_le_bytes()); // adv_lon (4)
|
||||
encode_frame(&data)
|
||||
}
|
||||
|
||||
/// CMD_SYNC_NEXT_MESSAGE (0x0A): Retrieve the next queued message.
|
||||
pub fn build_sync_next_message() -> Vec<u8> {
|
||||
encode_frame(&[CMD_SYNC_NEXT_MESSAGE])
|
||||
|
||||
Reference in New Issue
Block a user