Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions reticulum-sidecar/patches/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,16 @@ When [ratspeak/rsReticulum#11](https://github.com/ratspeak/rsReticulum/pull/11)

Recall cached destination public keys in `LinkClient` before waiting on path-response announces; GC temporary announce handlers without wiping long-lived Nomad directory listeners. Fixes Nomad page loads hanging until overall timeout.

Upstream `a945ba0` landed HasPath-gated `RecallDestination`, but still waits on a fresh announce when the path table is cold and still Deregisters handlers by `aspect_filter`. This overlay uses `RecallDestination` without the HasPath gate, then `await_path`, and GCs closed handlers only.

| Field | Value |
| ----- | ----- |
| **Base commit** | `9928abed269a83ec5a7ef165ff1142d938cad706` |
| **Base commit** | `70b7399` (`ratspeak/rsReticulum` `origin/main`) |
| **Upstream PR** | https://github.com/ratspeak/rsReticulum/pull/14 |

**Modifies (4 files):**
**Modifies (1 file):**

- `crates/rns-runtime/src/link_client.rs` — recall + `await_path`; safe announce-handler GC
- `crates/rns-transport/src/messages.rs` — `RecallDestinationPublicKey`, `PublicKeyResult`
- `crates/rns-transport/src/actor/rpc.rs` — recall handler
- `crates/rns-transport/src/actor/mod.rs` — unit tests
- `crates/rns-runtime/src/link_client.rs` — `discover_remote_public_key` + `await_path`; safe announce-handler GC

### Apply locally

Expand Down Expand Up @@ -202,7 +201,7 @@ Debounce BLE RNode reconnect after mid-SMP disconnect (`BLE pairing in progress`

| Field | Value |
| ----- | ----- |
| **Base commit** | `9928abed269a83ec5a7ef165ff1142d938cad706` (after prior overlays) |
| **Base commit** | `70b7399` (`ratspeak/rsReticulum` `origin/main`) |
| **Upstream PR** | https://github.com/ratspeak/rsReticulum/pull/20 |

**Modifies (1 file):**
Expand Down Expand Up @@ -399,7 +398,7 @@ When [ratspeak/rsLXMF#6](https://github.com/ratspeak/rsLXMF/pull/6) merges and f

| Field | Value |
| ----- | ----- |
| **Base commit** | tip of `ratspeak/rsLXMF` `main` + `rsLXMF-propagation-node-policy-setters` overlay |
| **Base commit** | `f9ed81e` (`ratspeak/rsLXMF` `origin/main`) + `rsLXMF-propagation-node-policy-setters` overlay |
| **Upstream PR** | (none yet — mesh-client local API) |

**Modifies (1 file):**
Expand Down Expand Up @@ -461,7 +460,7 @@ Ranked multi-path slots (up to 3 per destination) plus global / per-peer RF-vs-n

| Field | Value |
| ----- | ----- |
| **Base commit** | `9928abed269a83ec5a7ef165ff1142d938cad706` (+ prior mesh-client overlays) |
| **Base commit** | `70b7399` (+ prior mesh-client overlays) |
| **Upstream PR** | none yet (mesh-client-local) |

**Touches:** `constants.rs`, `path_table.rs`, `messages.rs`, `actor/{inbound,mod,rpc,outbound,persistence}.rs`
Expand Down Expand Up @@ -503,7 +502,7 @@ Adds `PropagationClient::abort_transfer` so Cancel / mid-transfer abort leaves t

| Field | Value |
| ----- | ----- |
| **Base commit** | floated `origin/main` (regenerate; record short SHA in PR) |
| **Base commit** | `f9ed81e` (`ratspeak/rsLXMF` `origin/main`) |
| **Upstream PR** | none yet (mesh-client-local; watch ratspeak/rsLXMF) |

**Touches:** rsLXMF `PropagationClient` (abort in-flight list/get transfer → Idle)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
diff --git a/crates/lxmf-core/src/propagation_client.rs b/crates/lxmf-core/src/propagation_client.rs
index a410020..8b8a663 100644
--- a/crates/lxmf-core/src/propagation_client.rs
+++ b/crates/lxmf-core/src/propagation_client.rs
@@ -182,6 +182,24 @@
self.status = PropagationTransferStatus::default();
@@ -202,6 +202,24 @@ impl PropagationClient {
true
}
+
+ /// Abort an in-flight or terminal download and return to [`Idle`].
+ ///
+ /// Unlike [`Self::acknowledge_transfer`], this also tears down mid-transfer
Expand All @@ -22,6 +23,7 @@
+ self.identified = false;
+ self.started_at = None;
+ }
+
pub fn start_download(&mut self) -> bool {
let node_hash = match self.outbound_propagation_node {
self.start_download_with_limit(None)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
diff --git a/crates/lxmf-core/src/propagation_node.rs b/crates/lxmf-core/src/propagation_node.rs
index 26a6c6f..2cdc924 100644
--- a/crates/lxmf-core/src/propagation_node.rs
+++ b/crates/lxmf-core/src/propagation_node.rs
@@ -333,8 +333,21 @@
@@ -416,9 +416,22 @@ impl PropagationNode {
config: PropagationNodeConfig,
dest_hash: [u8; 16],
storage_path: PathBuf,
) -> std::io::Result<Self> {
+ ) -> std::io::Result<Self> {
+ let mut node = Self::with_storage_unloaded(config, dest_hash, storage_path)?;
+ node.load_messagestore_from_disk()?;
+ Ok(node)
Expand All @@ -16,17 +19,17 @@
+ config: PropagationNodeConfig,
+ dest_hash: [u8; 16],
+ storage_path: PathBuf,
+ ) -> std::io::Result<Self> {
) -> std::io::Result<Self> {
std::fs::create_dir_all(&storage_path)?;
- let mut node = Self {
+ Ok(Self {
config,
store: PropagationStore::new(),
sync_sessions: HashMap::new(),
@@ -342,9 +355,13 @@
storage_path: Some(storage_path),
last_offer_times: HashMap::new(),
@@ -428,9 +441,13 @@ impl PropagationNode {
offer_generation: 0,
pending_write_ids: HashSet::new(),
pending_write_bytes: 0,
- };
- node.load_from_disk()?;
- Ok(node)
Expand All @@ -39,4 +42,4 @@
+ self.load_from_disk()
}

/// Returns `true` if the message was stored, `false` on duplicate, overflow,
fn reserve_store_write(
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/crates/rns-interface/src/ble_rnode.rs b/crates/rns-interface/src/ble_rnode.rs
index 1111111..2222222 100644
index 66d5610..dd36309 100644
--- a/crates/rns-interface/src/ble_rnode.rs
+++ b/crates/rns-interface/src/ble_rnode.rs
@@ -190,6 +190,14 @@
@@ -237,6 +237,14 @@ fn is_pairing_transition_error(error: &InterfaceError) -> bool {
)
}

Expand All @@ -17,15 +17,15 @@ index 1111111..2222222 100644
/// Android's native bridge can come up immediately after SMP completes, while
/// rsCardputer's RNode BLE stack is still settling. Probe detect a few times
/// inside one connection attempt so a single dropped early frame does not cost
@@ -1319,6 +1327,7 @@
@@ -1366,6 +1374,7 @@ enum NativeBridgeWrite {
async fn connect_rnode(
adapter: &Adapter,
ble_uri: &str,
+ session_already_bonded: bool,
) -> Result<BleRNodeConnection, InterfaceError> {
ble_diag(format!("[ble] connect_rnode start uri={ble_uri}"));
let peripheral = resolve_ble_target(adapter, ble_uri).await?;
@@ -1403,20 +1412,68 @@
@@ -1450,20 +1459,68 @@ async fn connect_rnode(
// kills any pending subscribe. iOS/macOS share CoreBluetooth; Windows
// (WinRT) and Android auto-prompt and retry on encrypted-char reads.
// Linux used explicit BlueZ pairing before `connect()`, above.
Expand Down Expand Up @@ -100,7 +100,7 @@ index 1111111..2222222 100644

// 244 = ATT MTU 247 - 3-byte header. Larger writes silently drop on
// peripherals with smaller negotiated MTU; 512 (GATT ceiling) isn't
@@ -1963,6 +2020,9 @@
@@ -2025,6 +2082,9 @@ pub async fn spawn_ble_rnode_interface_with_driver_and_options(
let mut tries: usize = 0;
let mut backoff = RECONNECT_WAIT;
let mut initial_attempt = true;
Expand All @@ -110,7 +110,7 @@ index 1111111..2222222 100644

// Drop guard: every early return must clear the running-flag map
// entry, or stale entries confuse later spawns reusing the id.
@@ -2009,9 +2069,25 @@
@@ -2071,9 +2131,25 @@ pub async fn spawn_ble_rnode_interface_with_driver_and_options(
}
};

Expand Down Expand Up @@ -138,7 +138,7 @@ index 1111111..2222222 100644
let pairing_transition = is_pairing_transition_error(&e);
let retry_wait = if pairing_transition {
PAIRING_TRANSITION_RETRY_WAIT
@@ -5432,7 +5508,7 @@
@@ -5607,7 +5683,7 @@ mod tests {
#[ignore]
async fn test_ble_connect_to_rnode() {
let adapter = get_adapter().await.expect("No BLE adapter");
Expand All @@ -147,7 +147,7 @@ index 1111111..2222222 100644
.await
.expect("No RNode found. Pair an RNode first.");
assert!(conn.peripheral.is_connected().await.unwrap_or(false));
@@ -5466,4 +5542,15 @@
@@ -5641,4 +5717,15 @@ mod tests {
"BLE device not found: RNode".into()
)));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
diff --git a/crates/rns-interface/src/ble_rnode.rs b/crates/rns-interface/src/ble_rnode.rs
index a0cf11a..9bd4780 100644
index e431f77..66d5610 100644
--- a/crates/rns-interface/src/ble_rnode.rs
+++ b/crates/rns-interface/src/ble_rnode.rs
@@ -53,6 +53,10 @@ pub const NUS_TX_CHAR_UUID: Uuid = Uuid::from_u128(0x6E400003_B5A3_F393_E0A9_E50
const RECONNECT_WAIT: u64 = 5;
/// Capped below TCP's 300s — a BLE radio is either in range or not.
const RECONNECT_WAIT_MAX: u64 = 120;
@@ -54,6 +54,10 @@ const RECONNECT_WAIT: u64 = 1;
/// Fast early recovery, then indefinite low-duty retries. A two-minute cap made
/// a reachable radio appear dead long after returning to range.
const RECONNECT_WAIT_MAX: u64 = 30;
+/// After a mid-SMP disconnect (`BLE pairing in progress`), wait before
+/// reconnecting so the OS passkey dialog is not re-fired every second while
+/// the user is typing the PIN (desktop BLE pairing UX).
+const PAIRING_TRANSITION_RETRY_WAIT: u64 = 30;
/// `None` retries forever; teardown goes via `stop_ble_rnode_interface`.
const MAX_RECONNECT_TRIES: Option<usize> = None;
const SCAN_TIMEOUT: u64 = 3;
@@ -2009,7 +2013,11 @@ pub async fn spawn_ble_rnode_interface_with_driver_and_options(
@@ -2071,7 +2075,11 @@ pub async fn spawn_ble_rnode_interface_with_driver_and_options(
Ok(c) => c,
Err(e) => {
let pairing_transition = is_pairing_transition_error(&e);
Expand All @@ -26,7 +26,7 @@ index a0cf11a..9bd4780 100644
snapshot_publisher.connection_attempt_failed();
tracing::warn!(name = %log_name, error = %e, "BLE RNode connect failed");
ble_diag(format!(
@@ -5447,4 +5455,15 @@ mod tests {
@@ -5622,4 +5630,15 @@ mod tests {
tokio::time::sleep(Duration::from_secs(2)).await;
handle.online.store(false, Ordering::SeqCst);
}
Expand Down
Loading