From 4c8dbfe92faa79ab9e4ba3f261bc04dbce1ec40d Mon Sep 17 00:00:00 2001 From: Vitalii Popov Date: Thu, 12 Feb 2026 18:05:22 +0200 Subject: [PATCH] Revert "bond" This reverts commit 1ca2aeb3f528ff41e7f60270ade243ace22f6a35. --- Cargo.lock | 100 +++++++++++++++++++------- Cargo.toml | 4 +- src/main.rs | 198 ++++++++++------------------------------------------ 3 files changed, 113 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6527063..f7c8e17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,6 +7,19 @@ name = "Inflector" version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] [[package]] name = "autocfg" @@ -352,14 +365,13 @@ dependencies = [ [[package]] name = "embassy-sync" -version = "0.6.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" dependencies = [ "cfg-if", "critical-section", "embedded-io-async", - "futures-sink", "futures-util", "heapless", ] @@ -605,12 +617,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "litrs" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + [[package]] name = "nb" version = "0.1.3" @@ -639,13 +663,15 @@ dependencies = [ [[package]] name = "nrf-softdevice" version = "0.1.0" -source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225a21d963b2382617dbbff5953dc8c6c43fe56db5c5155f4d20a30c50c2766d" dependencies = [ "cortex-m", + "cortex-m-rt", "critical-section", "defmt 0.3.100", "embassy-futures", - "embassy-sync 0.6.2", + "embassy-sync 0.5.0", "embedded-storage", "embedded-storage-async", "fixed", @@ -653,13 +679,15 @@ dependencies = [ "heapless", "nrf-softdevice-macro", "nrf-softdevice-s140", + "nrf52840-pac", "num_enum", ] [[package]] name = "nrf-softdevice-macro" version = "0.1.0" -source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af0752f2f12e202fa29f5a8d2f6dcc8a421c7a7e368d9dab7feb6bfe24ff0e9" dependencies = [ "Inflector", "darling 0.13.4", @@ -672,7 +700,19 @@ dependencies = [ [[package]] name = "nrf-softdevice-s140" version = "0.1.2" -source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea93a1e11efdafcf914ed6b81b5be0cd99ee8ff6c3060102265ea863a355393" + +[[package]] +name = "nrf52840-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] [[package]] name = "num-traits" @@ -719,11 +759,9 @@ dependencies = [ "embassy-time", "embedded-storage-async", "futures", - "heapless", "nrf-softdevice", "panic-halt", "panic-probe", - "static_cell", ] [[package]] @@ -760,12 +798,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "portable-atomic" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -818,6 +850,35 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + [[package]] name = "rustc_version" version = "0.2.3" @@ -854,15 +915,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" -[[package]] -name = "static_cell" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" -dependencies = [ - "portable-atomic", -] - [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index e52bb4e..ff991ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,11 +17,9 @@ embassy-sync = { version = "0.7.2", features = ["defmt"] } embassy-time = { version = "0.5.0", features = ["tick-hz-32_768", "defmt", "defmt-timestamp-uptime"] } panic-halt = "1.0.0" panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true } -nrf-softdevice = { git = "https://github.com/embassy-rs/nrf-softdevice", features = ["s140", "ble-peripheral", "nrf52840", "nrf-softdevice-s140", "critical-section-impl", "defmt", "critical-section", "ble-gatt-server", "ble-sec"] } +nrf-softdevice = { version = "0.1.0", features = ["s140", "ble-peripheral", "nrf52840", "nrf-softdevice-s140", "critical-section-impl", "defmt", "nrf52840-pac", "critical-section", "ble-gatt-server"] } futures = { version = "0.3", default-features = false, features = [] } embedded-storage-async = "0.4.1" -heapless = "0.8.0" -static_cell = "2.1.1" [[bin]] name = "odesa" diff --git a/src/main.rs b/src/main.rs index a5c71a6..25b15b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,9 @@ mod fmt; -use core::cell::{Cell, RefCell}; use core::mem; use core::ops::{AddAssign, SubAssign}; use core::pin::Pin; -use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; use defmt::{error, Format}; #[cfg(not(feature = "defmt"))] use panic_halt as _; @@ -18,11 +16,10 @@ use defmt::info; use embassy_executor::Spawner; use embassy_futures::join::{join3, join4}; -use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pull}; +use embassy_nrf::gpio::{AnyPin, Input, OutputDrive, Pull}; use embassy_nrf::interrupt::{InterruptExt, Priority}; use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; use embassy_nrf::{bind_interrupts, interrupt, saadc, Peri}; -use embassy_nrf::gpio::OutputDrive::Standard; use embassy_nrf::peripherals::SAADC; use embassy_nrf::saadc::{ChannelConfig, Gain, Reference, Saadc}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; @@ -33,11 +30,8 @@ use futures::future::{select, Either}; use futures::pin_mut; use nrf_softdevice::{raw, Flash, Softdevice}; use nrf_softdevice::ble::advertisement_builder::{Flag, LegacyAdvertisementBuilder, LegacyAdvertisementPayload, ServiceList, ServiceUuid16}; -use nrf_softdevice::ble::{peripheral, gatt_server, Connection, MasterId, EncryptionInfo, IdentityKey, PasskeyReply}; +use nrf_softdevice::ble::{peripheral, gatt_server, Connection}; use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash}; -use nrf_softdevice::ble::gatt_server::set_sys_attrs; -use nrf_softdevice::ble::security::{IoCapabilities, SecurityHandler}; -use static_cell::StaticCell; #[derive(Copy, Clone, Eq, PartialEq, Format)] enum SysAction { @@ -133,24 +127,23 @@ static TEXT_ANIMATION_SIGNAL: Signal> = Signal::new(); static SYS_ACTION: Mutex = Mutex::new(SysAction::PresentenceOn); static SAVE_SIGNAL: Signal = Signal::new(); -static BOND_COUNTER: AtomicU8 = AtomicU8::new(0); #[nrf_softdevice::gatt_service(uuid = "9e7312e0-2354-11eb-9f10-fbc30a62cf38")] struct AnimationService { - #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a63cf38", read, write, notify, indicate, security = "JustWorks")] + #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a63cf38", read, write, notify, indicate)] text_mode: u16, - #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a64cf38", read, write, notify, indicate, security = "JustWorks")] + #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a64cf38", read, write, notify, indicate)] text_color: u16, - #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a65cf38", read, write, notify, indicate, security = "JustWorks")] + #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a65cf38", read, write, notify, indicate)] heart_mode: u16, - #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a66cf38", read, write, notify, indicate, security = "JustWorks")] + #[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a66cf38", read, write, notify, indicate)] heart_color: u16, } #[nrf_softdevice::gatt_service(uuid = "180f")] struct BatteryService { - #[characteristic(uuid = "2a19", read, notify, security = "JustWorks")] + #[characteristic(uuid = "2a19", read, notify)] battery_level: u8, } @@ -166,99 +159,6 @@ bind_interrupts!(struct AdcIrqs { const DATA_POINT: u32 = 0x000F9800 - 4096; -#[derive(Debug, Clone, Copy)] -struct Peer { - master_id: MasterId, - key: EncryptionInfo, - peer_id: IdentityKey, -} - -pub struct Bonder { - peer: Cell>, - sys_attrs: RefCell>, -} - -impl Default for Bonder { - fn default() -> Self { - Bonder { - peer: Cell::new(None), - sys_attrs: Default::default(), - } - } -} - -impl SecurityHandler for Bonder { - fn io_capabilities(&self) -> IoCapabilities { - let val = BOND_COUNTER.load(Ordering::Relaxed); - if val > 0 { - IoCapabilities::None - } else { - IoCapabilities::DisplayYesNo - } - } - - fn can_bond(&self, _conn: &Connection) -> bool { - true - } - - fn display_passkey(&self, passkey: &[u8; 6]) { - info!("The passkey is \"{:a}\"", passkey) - } - - fn enter_passkey(&self, _reply: PasskeyReply) { - } - - fn on_bonded(&self, _conn: &Connection, master_id: MasterId, key: EncryptionInfo, peer_id: IdentityKey) { - info!("storing bond for: id: {}, key: {}", master_id, key); - - // In a real application you would want to signal another task to permanently store the keys in non-volatile memory here. - self.sys_attrs.borrow_mut().clear(); - self.peer.set(Some(Peer { - master_id, - key, - peer_id, - })); - } - - fn get_key(&self, _conn: &Connection, master_id: MasterId) -> Option { - info!("getting bond for: id: {}", master_id); - - self.peer - .get() - .and_then(|peer| (master_id == peer.master_id).then_some(peer.key)) - } - - fn save_sys_attrs(&self, conn: &Connection) { - info!("saving system attributes for: {}", conn.peer_address()); - - if let Some(peer) = self.peer.get() { - if peer.peer_id.is_match(conn.peer_address()) { - let mut sys_attrs = self.sys_attrs.borrow_mut(); - let capacity = sys_attrs.capacity(); - sys_attrs.resize(capacity, 0).expect("failed to resize sys attributes"); - let len = gatt_server::get_sys_attrs(conn, &mut sys_attrs).expect("failed to get sys attributes") as u16; - sys_attrs.truncate(usize::from(len)); - // In a real application you would want to signal another task to permanently store sys_attrs for this connection's peer - } - } - } - - fn load_sys_attrs(&self, conn: &Connection) { - let addr = conn.peer_address(); - info!("loading system attributes for: {}", addr); - - let attrs = self.sys_attrs.borrow(); - // In a real application you would search all stored peers to find a match - let attrs = if self.peer.get().map(|peer| peer.peer_id.is_match(addr)).unwrap_or(false) { - (!attrs.is_empty()).then_some(attrs.as_slice()) - } else { - None - }; - - set_sys_attrs(conn, attrs).expect("failed to set sys attributes"); - } -} - #[embassy_executor::main] async fn main(spawner: Spawner) { let mut config = embassy_nrf::config::Config::default(); @@ -325,7 +225,7 @@ async fn main(spawner: Spawner) { let pwm_heart = SimplePwm::new_3ch(p.PWM2, p.P0_17, p.P0_20, p.P0_22, &Default::default()); spawner.spawn(radar_task()).expect("failed to spawn radar task"); spawner.spawn(touch_button(p.P0_08.into())).expect("failed to spawn touch task"); - spawner.spawn(actions_task(p.P0_15.into())).expect("failed to spawn actions task"); + spawner.spawn(actions_task()).expect("failed to spawn actions task"); spawner.spawn(softdevice_task(sd)).expect("failed to spawn softdevice task"); spawner.spawn(storage_task(flash, initial_data.0, initial_data.1, initial_data.2, initial_data.3)).expect("failed to spawn softdevice task"); @@ -418,21 +318,13 @@ async fn gatt_task(server: Server, mut saadc: Saadc<'static, 1>, sd: &'static So ) .build(); - static BONDER: StaticCell = StaticCell::new(); - let bonder = BONDER.init(Bonder::default()); - loop { let config = peripheral::Config::default(); let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { adv_data: &ADV_DATA, scan_data: &SCAN_DATA, }; - let conn = peripheral::advertise_pairable(sd, adv, &config, bonder).await.expect("failed to advertise"); - - if let Err(e) = conn.request_security() { - info!("Failed to request security: {}", e); - continue; - } + let conn = peripheral::advertise_connectable(sd, adv, &config).await.expect("failed to advertise"); info!("advertising done!"); @@ -625,55 +517,38 @@ fn battery_mv_to_percent(mv: u16) -> u8 { } #[embassy_executor::task] -async fn actions_task(pin: Peri<'static, AnyPin>) { - let mut led_pin = Output::new(pin, Level::High, Standard); - +async fn actions_task() { loop { - if let Ok(signal) = with_timeout(Duration::from_secs(60), TOUCH_SIGNAL.wait()).await { - info!("Action: {:?}", signal); - match signal { - // constant on vs presentence - TouchAction::Tap => { - let mut action = SYS_ACTION.lock().await; - match *action { - SysAction::PresentenceOn | - SysAction::PresentenceOff => { - *action = SysAction::ConstantOn; - info!("Constant light"); - } - SysAction::ConstantOn => { - *action = SysAction::PresentenceOn; - info!("Light by presentence"); - } + let signal = TOUCH_SIGNAL.wait().await; + info!("Action: {:?}", signal); + match signal { + // constant on vs presentence + TouchAction::Tap => { + let mut action = SYS_ACTION.lock().await; + match *action { + SysAction::PresentenceOn | + SysAction::PresentenceOff => { + *action = SysAction::ConstantOn; + info!("Constant light"); } - info!("Light mode {:?}", *action); - } - // change text animation - TouchAction::DoubleTap => { - TEXT_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation); - } - // change anchor animation - TouchAction::TripleTap => { - HEART_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation); - } - // enter pairing mode - TouchAction::Hold => { - let current = BOND_COUNTER.load(Ordering::Relaxed); - let next = if current > 0 { 0 } else { 1 }; - BOND_COUNTER.store(next, Ordering::Relaxed); - info!("Set bond: {}", next); - if next > 0 { - led_pin.set_low(); + SysAction::ConstantOn => { + *action = SysAction::PresentenceOn; + info!("Light by presentence"); } } + info!("Light mode {:?}", *action); } - } else { - let current = BOND_COUNTER.load(Ordering::Relaxed); - if current > 0 { - BOND_COUNTER.store(0, Ordering::Relaxed); - led_pin.set_high(); + // change text animation + TouchAction::DoubleTap => { + TEXT_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation); + } + // change anchor animation + TouchAction::TripleTap => { + HEART_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation); + } + // enter pairing mode + TouchAction::Hold => { } - info!("Timeout bond"); } } } @@ -720,11 +595,10 @@ async fn moving_radar(pin: Peri<'static, AnyPin>) { info!("Waiting for radar"); radar.wait_for_high().await; RADAR_SIGNAL.signal(0); - info!("Moving!!"); while let Err(_) = with_timeout(Duration::from_secs(1), radar.wait_for_low()).await { + info!("Moving!!"); RADAR_SIGNAL.signal(0); } - info!("Stopped"); } }