fix(mesh): native E2E DM for archy↔archy text + software radio-reboot
- send_message now sends archy↔archy plain text as a native TEXT_MESSAGE_APP DM (firmware PKC-encrypts E2E), not wrapped in the binary typed envelope that silently broke archy↔archy LoRa delivery. Archy peers' Sent rows are marked encrypted so the E2E pill shows; rich typed msgs still use the typed-wire path. - Add a software radio-reboot to recover a wedged/RX-deaf radio without physical access (and for the Device-tab settings panel): driver reboot() via AdminMessage reboot_seconds=97 (verified vs meshtastic/protobufs), MeshCommand::RebootRadio, MeshService::reboot_radio, RPC mesh.reboot-radio. - Handoff doc: docs/SESSION-1.8.0-OTA-PROGRESS.md "RESUME HERE" — RF link is the proven blocker (radios not hearing each other); modem_preset mismatch is the prime suspect; on-device Meshtastic-app check + fix plan documented. 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
b4531bb4fc
commit
fbfeeeb0f5
@@ -59,6 +59,10 @@ const FROM_RADIO_MAX: usize = 4096;
|
||||
const ADMIN_SET_CONFIG_FIELD: u64 = 34;
|
||||
/// AdminMessage.set_channel oneof field number (carries a `Channel`).
|
||||
const ADMIN_SET_CHANNEL_FIELD: u64 = 33;
|
||||
/// AdminMessage.reboot_seconds oneof field number (int32). Verified against
|
||||
/// meshtastic/protobufs admin.proto: `reboot_seconds = 97` (NOT 40 — the
|
||||
/// payload_variant numbers jump after the setters).
|
||||
const ADMIN_REBOOT_SECONDS_FIELD: u64 = 97;
|
||||
/// FromRadio.channel (field 10): a `Channel` streamed during want_config.
|
||||
const FROM_RADIO_CHANNEL: u64 = 10;
|
||||
const FROM_RADIO_QUEUE_STATUS: u64 = 11;
|
||||
@@ -383,6 +387,34 @@ impl MeshtasticDevice {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reboot the locally-connected radio via `AdminMessage { reboot_seconds }`
|
||||
/// on the ADMIN_APP port — the same local-admin path `set_advert_name` /
|
||||
/// `set_lora_region` use (no session passkey needed over serial). The
|
||||
/// firmware reboots after `seconds`, which clears a wedged / RX-deaf radio
|
||||
/// (a radio that has stopped hearing the mesh while still transmitting) and
|
||||
/// re-runs its LoRa init. The listener's reboot→reconnect loop reopens the
|
||||
/// serial link when it comes back.
|
||||
pub async fn reboot(&mut self, seconds: i64) -> Result<()> {
|
||||
let Some(node_num) = self.node_num else {
|
||||
anyhow::bail!("Meshtastic reboot: node_num unknown");
|
||||
};
|
||||
// AdminMessage { reboot_seconds(97): int32 }. We only ever pass a small
|
||||
// positive delay, which encodes as a plain varint.
|
||||
let mut admin = Vec::new();
|
||||
encode_varint_field_into(ADMIN_REBOOT_SECONDS_FIELD, seconds as u64, &mut admin);
|
||||
|
||||
let packet = encode_mesh_packet(node_num, ADMIN_APP, &admin);
|
||||
self.send_to_radio(&encode_to_radio_variant(TO_RADIO_PACKET, &packet))
|
||||
.await
|
||||
.context("Failed to send Meshtastic reboot admin packet")?;
|
||||
|
||||
info!(
|
||||
node_num,
|
||||
seconds, "Sent Meshtastic radio reboot (device will reboot to recover)"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Provision archy's two channels so the radio works like off-the-shelf
|
||||
/// Meshtastic AND carries our private group:
|
||||
/// - slot 0 (PRIMARY) = the DEFAULT public channel (name "", default key)
|
||||
|
||||
Reference in New Issue
Block a user