diff --git a/src/winrtble/adapter.rs b/src/winrtble/adapter.rs index 82e6741b..20c07050 100644 --- a/src/winrtble/adapter.rs +++ b/src/winrtble/adapter.rs @@ -23,19 +23,48 @@ use std::convert::TryInto; use std::fmt::{self, Debug, Formatter}; use std::pin::Pin; use std::sync::{Arc, Mutex}; +use windows::{ + Devices::Radios::{Radio, RadioState}, + Foundation::TypedEventHandler, +}; /// Implementation of [api::Central](crate::api::Central). #[derive(Clone)] pub struct Adapter { watcher: Arc>, manager: Arc>, + radio: Radio, +} + +// https://github.com/microsoft/windows-rs/blob/master/crates/libs/windows/src/Windows/Devices/Radios/mod.rs +fn get_central_state(radio: Radio) -> CentralState { + let state = radio.State().unwrap_or(RadioState::Unknown); + match state { + RadioState::On => CentralState::PoweredOn, + RadioState::Off => CentralState::PoweredOff, + _ => CentralState::Unknown, + } } impl Adapter { - pub(crate) fn new() -> Self { + pub(crate) fn new(radio: Radio) -> Self { let watcher = Arc::new(Mutex::new(BLEWatcher::new())); let manager = Arc::new(AdapterManager::default()); - Adapter { watcher, manager } + + let radio_clone = radio.clone(); + let manager_clone = manager.clone(); + let handler = TypedEventHandler::new(move |_sender, _args| { + let state = get_central_state(radio_clone.clone()); + manager_clone.emit(CentralEvent::StateUpdate(state.into())); + Ok(()) + }); + radio.StateChanged(&handler); + + Adapter { + watcher, + manager, + radio, + } } } @@ -102,6 +131,6 @@ impl Central for Adapter { } async fn adapter_state(&self) -> Result { - Ok(CentralState::Unknown) + Ok(get_central_state(self.radio.clone())) } } diff --git a/src/winrtble/manager.rs b/src/winrtble/manager.rs index da525843..e73979e0 100644 --- a/src/winrtble/manager.rs +++ b/src/winrtble/manager.rs @@ -35,7 +35,7 @@ impl api::Manager for Manager { Ok(radios .into_iter() .filter(|radio| radio.Kind() == Ok(RadioKind::Bluetooth)) - .map(|_| Adapter::new()) + .map(|radio| Adapter::new(radio.clone())) .collect()) } }