linux-rust: show device info in UI
This commit is contained in:
@@ -9,18 +9,13 @@ use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::path::PathBuf;
|
||||
use crate::utils::get_devices_path;
|
||||
|
||||
const PSM: u16 = 0x1001;
|
||||
const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
const POLL_INTERVAL: Duration = Duration::from_millis(200);
|
||||
const HEADER_BYTES: [u8; 4] = [0x04, 0x00, 0x04, 0x00];
|
||||
|
||||
fn get_devices_path() -> PathBuf {
|
||||
let data_dir = std::env::var("XDG_DATA_HOME")
|
||||
.unwrap_or_else(|_| format!("{}/.local/share", std::env::var("HOME").unwrap_or_default()));
|
||||
PathBuf::from(data_dir).join("librepods").join("devices.json")
|
||||
}
|
||||
|
||||
pub mod opcodes {
|
||||
pub const SET_FEATURE_FLAGS: u8 = 0x4D;
|
||||
pub const REQUEST_NOTIFICATIONS: u8 = 0x0F;
|
||||
@@ -268,11 +263,18 @@ pub struct AirPodsInformation {
|
||||
pub version3: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "kind", content = "data")]
|
||||
pub enum DeviceInformation {
|
||||
AirPods(AirPodsInformation),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeviceData {
|
||||
pub name: String,
|
||||
pub type_: DeviceType,
|
||||
pub le: LEData,
|
||||
pub information: Option<AirPodsInformation>,
|
||||
pub information: Option<DeviceInformation>,
|
||||
}
|
||||
|
||||
pub struct AACPManagerState {
|
||||
@@ -620,7 +622,8 @@ impl AACPManager {
|
||||
let mut state = self.state.lock().await;
|
||||
if let Some(mac) = state.airpods_mac {
|
||||
if let Some(device_data) = state.devices.get_mut(&mac.to_string()) {
|
||||
device_data.information = Some(info.clone());
|
||||
device_data.name = info.name.clone();
|
||||
device_data.information = Some(DeviceInformation::AirPods(info.clone()));
|
||||
}
|
||||
}
|
||||
let json = serde_json::to_string(&state.devices).unwrap();
|
||||
@@ -668,6 +671,7 @@ impl AACPManager {
|
||||
if let Some(mac) = state.airpods_mac {
|
||||
let mac_str = mac.to_string();
|
||||
let device_data = state.devices.entry(mac_str.clone()).or_insert(DeviceData {
|
||||
name: mac_str.clone(),
|
||||
type_: DeviceType::AirPods,
|
||||
le: LEData { irk: "".to_string(), enc_key: "".to_string() },
|
||||
information: None,
|
||||
|
||||
@@ -2,46 +2,20 @@ use std::cmp::PartialEq;
|
||||
use bluer::monitor::{Monitor, MonitorEvent, Pattern};
|
||||
use bluer::{Address, Session};
|
||||
use aes::Aes128;
|
||||
use aes::cipher::{BlockEncrypt, KeyInit, BlockDecrypt};
|
||||
use aes::cipher::{KeyInit, BlockDecrypt};
|
||||
use aes::cipher::generic_array::GenericArray;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use log::{info, debug};
|
||||
use serde_json;
|
||||
use crate::bluetooth::aacp::ProximityKeyType;
|
||||
use futures::StreamExt;
|
||||
use hex;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::bluetooth::aacp::BatteryStatus;
|
||||
use crate::ui::tray::MyTray;
|
||||
use crate::bluetooth::aacp::{DeviceData, LEData, DeviceType};
|
||||
|
||||
fn get_devices_path() -> PathBuf {
|
||||
let data_dir = std::env::var("XDG_DATA_HOME")
|
||||
.unwrap_or_else(|_| format!("{}/.local/share", std::env::var("HOME").unwrap_or_default()));
|
||||
PathBuf::from(data_dir).join("librepods").join("devices.json")
|
||||
}
|
||||
|
||||
fn get_preferences_path() -> PathBuf {
|
||||
let config_dir = std::env::var("XDG_CONFIG_HOME")
|
||||
.unwrap_or_else(|_| format!("{}/.config", std::env::var("HOME").unwrap_or_default()));
|
||||
PathBuf::from(config_dir).join("librepods").join("preferences.json")
|
||||
}
|
||||
|
||||
fn e(key: &[u8; 16], data: &[u8; 16]) -> [u8; 16] {
|
||||
let mut swapped_key = *key;
|
||||
swapped_key.reverse();
|
||||
let mut swapped_data = *data;
|
||||
swapped_data.reverse();
|
||||
let cipher = Aes128::new(&GenericArray::from(swapped_key));
|
||||
let mut block = GenericArray::from(swapped_data);
|
||||
cipher.encrypt_block(&mut block);
|
||||
let mut result: [u8; 16] = block.into();
|
||||
result.reverse();
|
||||
result
|
||||
}
|
||||
use crate::bluetooth::aacp::{DeviceData, DeviceType};
|
||||
use crate::utils::{get_devices_path, get_preferences_path, ah};
|
||||
|
||||
fn decrypt(key: &[u8; 16], data: &[u8; 16]) -> [u8; 16] {
|
||||
let cipher = Aes128::new(&GenericArray::from(*key));
|
||||
@@ -50,15 +24,6 @@ fn decrypt(key: &[u8; 16], data: &[u8; 16]) -> [u8; 16] {
|
||||
block.into()
|
||||
}
|
||||
|
||||
fn ah(k: &[u8; 16], r: &[u8; 3]) -> [u8; 3] {
|
||||
let mut r_padded = [0u8; 16];
|
||||
r_padded[..3].copy_from_slice(r);
|
||||
let encrypted = e(k, &r_padded);
|
||||
let mut hash = [0u8; 3];
|
||||
hash.copy_from_slice(&encrypted[..3]);
|
||||
hash
|
||||
}
|
||||
|
||||
fn verify_rpa(addr: &str, irk: &[u8; 16]) -> bool {
|
||||
let rpa: Vec<u8> = addr.split(':')
|
||||
.map(|s| u8::from_str_radix(s, 16).unwrap())
|
||||
|
||||
Reference in New Issue
Block a user