From ccee82026dd1e4ff2e00668a0c4b368df05e6bb9 Mon Sep 17 00:00:00 2001 From: Kavish Devar Date: Thu, 23 Oct 2025 12:48:15 +0530 Subject: [PATCH] linux-rust: store irk and enc keys --- linux-rust/Cargo.lock | 2 ++ linux-rust/Cargo.toml | 2 ++ linux-rust/src/bluetooth/aacp.rs | 36 ++++++++++++++++++++++++++++---- linux-rust/src/bluetooth/le.rs | 0 linux-rust/src/bluetooth/mod.rs | 3 ++- 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 linux-rust/src/bluetooth/le.rs diff --git a/linux-rust/Cargo.lock b/linux-rust/Cargo.lock index 499df61..40a3922 100644 --- a/linux-rust/Cargo.lock +++ b/linux-rust/Cargo.lock @@ -1105,6 +1105,8 @@ dependencies = [ "ksni", "libpulse-binding", "log", + "serde", + "serde_json", "tokio", "uuid", ] diff --git a/linux-rust/Cargo.toml b/linux-rust/Cargo.toml index a4f548b..611b261 100644 --- a/linux-rust/Cargo.toml +++ b/linux-rust/Cargo.toml @@ -18,6 +18,8 @@ image = "0.25.8" imageproc = "0.25.0" ab_glyph = "0.2.32" clap = { version = "4.5.50", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [profile.release] opt-level = "s" diff --git a/linux-rust/src/bluetooth/aacp.rs b/linux-rust/src/bluetooth/aacp.rs index fac331a..7aa320c 100644 --- a/linux-rust/src/bluetooth/aacp.rs +++ b/linux-rust/src/bluetooth/aacp.rs @@ -6,6 +6,8 @@ use tokio::sync::{Mutex, mpsc}; use tokio::task::JoinSet; use tokio::time::{sleep, Instant}; use std::collections::HashMap; +use serde::{Deserialize, Serialize}; +use serde_json; const PSM: u16 = 0x1001; const CONNECT_TIMEOUT: Duration = Duration::from_secs(10); @@ -124,12 +126,22 @@ impl ControlCommandIdentifiers { } #[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)] pub enum ProximityKeyType { Irk = 0x01, EncKey = 0x04, } +impl ProximityKeyType { + fn from_u8(value: u8) -> Option { + match value { + 0x01 => Some(Self::Irk), + 0x04 => Some(Self::EncKey), + _ => None, + } + } +} + #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum StemPressType { @@ -236,10 +248,15 @@ struct AACPManagerState { old_ear_detection_status: Vec, ear_detection_status: Vec, event_tx: Option>, + proximity_keys: HashMap>, } impl AACPManagerState { fn new() -> Self { + let proximity_keys = std::fs::read_to_string("proximity_keys.json") + .ok() + .and_then(|s| serde_json::from_str(&s).ok()) + .unwrap_or_default(); AACPManagerState { sender: None, control_command_status_list: Vec::new(), @@ -253,13 +270,14 @@ impl AACPManagerState { old_ear_detection_status: Vec::new(), ear_detection_status: Vec::new(), event_tx: None, + proximity_keys, } } } #[derive(Clone)] pub struct AACPManager { - state: Arc>, + pub state: Arc>, tasks: Arc>>, } @@ -541,7 +559,17 @@ impl AACPManager { offset += key_length; } info!("Received Proximity Keys Response: {:?}", keys.iter().map(|(kt, kd)| (kt, hex::encode(kd))).collect::>()); - let state = self.state.lock().await; + let mut state = self.state.lock().await; + for (key_type, key_data) in &keys { + if let Some(kt) = ProximityKeyType::from_u8(*key_type) { + state.proximity_keys.insert(kt, key_data.clone()); + } + } + // Persist to file + let json = serde_json::to_string(&state.proximity_keys).unwrap(); + if let Err(e) = tokio::fs::write("proximity_keys.json", json).await { + error!("Failed to save proximity keys: {}", e); + } if let Some(ref tx) = state.event_tx { let _ = tx.send(AACPEvent::ProximityKeys(keys)); } @@ -688,7 +716,7 @@ impl AACPManager { buffer.push(0x46); buffer.extend_from_slice(b"btName"); buffer.push(0x43); - buffer.extend_from_slice(b"Mac");; + buffer.extend_from_slice(b"Mac"); buffer.push(0x58); buffer.extend_from_slice(b"otherDevice"); buffer.extend_from_slice(b"AudioCategory"); diff --git a/linux-rust/src/bluetooth/le.rs b/linux-rust/src/bluetooth/le.rs new file mode 100644 index 0000000..e69de29 diff --git a/linux-rust/src/bluetooth/mod.rs b/linux-rust/src/bluetooth/mod.rs index bf501c3..b9f7dab 100644 --- a/linux-rust/src/bluetooth/mod.rs +++ b/linux-rust/src/bluetooth/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod discovery; pub mod aacp; -// pub mod att; \ No newline at end of file +// pub mod att; +pub mod le; \ No newline at end of file