1111use super :: {
1212 central_delegate:: { CentralDelegate , CentralDelegateEvent } ,
1313 framework:: {
14- cb:: { self , CBManagerAuthorization , CBPeripheralState } ,
14+ cb:: { self , CBManagerAuthorization , CBManagerState , CBPeripheralState } ,
1515 ns,
1616 } ,
1717 future:: { BtlePlugFuture , BtlePlugFutureStateShared } ,
@@ -21,10 +21,7 @@ use super::{
2121 nsuuid_to_uuid,
2222 } ,
2323} ;
24- use crate :: api:: {
25- bleuuid:: uuid_from_u16, CharPropFlags , Characteristic , Descriptor , ScanFilter , Service ,
26- WriteType ,
27- } ;
24+ use crate :: api:: { CharPropFlags , Characteristic , Descriptor , ScanFilter , Service , WriteType } ;
2825use crate :: Error ;
2926use cocoa:: {
3027 base:: { id, nil} ,
@@ -148,6 +145,7 @@ pub enum CoreBluetoothReply {
148145 ReadResult ( Vec < u8 > ) ,
149146 Connected ( BTreeSet < Service > ) ,
150147 State ( CBPeripheralState ) ,
148+ ManagerState ( CBManagerState ) ,
151149 Ok ,
152150 Err ( String ) ,
153151}
@@ -408,11 +406,14 @@ pub enum CoreBluetoothMessage {
408406 data : Vec < u8 > ,
409407 future : CoreBluetoothReplyStateShared ,
410408 } ,
409+ FetchManagerState {
410+ future : CoreBluetoothReplyStateShared ,
411+ } ,
411412}
412413
413414#[ derive( Debug ) ]
414415pub enum CoreBluetoothEvent {
415- AdapterConnected ,
416+ DidUpdateState ,
416417 DeviceDiscovered {
417418 uuid : Uuid ,
418419 name : Option < String > ,
@@ -795,6 +796,18 @@ impl CoreBluetoothInternal {
795796 }
796797 }
797798
799+ fn get_manager_state_sync ( & mut self ) -> CBManagerState {
800+ cb:: centeralmanger_state ( * self . manager )
801+ }
802+
803+ fn get_manager_state ( & mut self , fut : CoreBluetoothReplyStateShared ) {
804+ let state = cb:: centeralmanger_state ( * self . manager ) ;
805+ trace ! ( "Manager state {:?} " , state) ;
806+ fut. lock ( )
807+ . unwrap ( )
808+ . set_reply ( CoreBluetoothReply :: ManagerState ( state) ) ;
809+ }
810+
798811 fn write_value (
799812 & mut self ,
800813 peripheral_uuid : Uuid ,
@@ -837,6 +850,11 @@ impl CoreBluetoothInternal {
837850 characteristic_uuid : Uuid ,
838851 fut : CoreBluetoothReplyStateShared ,
839852 ) {
853+ trace ! (
854+ "Manager State {:?}" ,
855+ cb:: centeralmanger_state( * self . manager)
856+ ) ;
857+
840858 if let Some ( peripheral) = self . peripherals . get_mut ( & peripheral_uuid) {
841859 if let Some ( service) = peripheral. services . get_mut ( & service_uuid) {
842860 if let Some ( characteristic) = service. characteristics . get_mut ( & characteristic_uuid)
@@ -1010,7 +1028,7 @@ impl CoreBluetoothInternal {
10101028 // "ready" variable in our adapter that will cause scans/etc
10111029 // to fail if this hasn't updated.
10121030 CentralDelegateEvent :: DidUpdateState => {
1013- self . dispatch_event( CoreBluetoothEvent :: AdapterConnected ) . await
1031+ self . dispatch_event( CoreBluetoothEvent :: DidUpdateState ) . await
10141032 }
10151033 CentralDelegateEvent :: DiscoveredPeripheral { cbperipheral} => {
10161034 self . on_discovered_peripheral( cbperipheral) . await
@@ -1109,6 +1127,9 @@ impl CoreBluetoothInternal {
11091127 CoreBluetoothMessage :: IsConnected { peripheral_uuid, future} => {
11101128 self . is_connected( peripheral_uuid, future) ;
11111129 } ,
1130+ CoreBluetoothMessage :: FetchManagerState { future} =>{
1131+ self . get_manager_state( future) ;
1132+ } ,
11121133 CoreBluetoothMessage :: ReadDescriptorValue { peripheral_uuid, service_uuid, characteristic_uuid, descriptor_uuid, future} => {
11131134 self . read_descriptor_value( peripheral_uuid, service_uuid, characteristic_uuid, descriptor_uuid, future)
11141135 }
@@ -1189,6 +1210,14 @@ pub fn run_corebluetooth_thread(
11891210 runtime. block_on ( async move {
11901211 let mut cbi = CoreBluetoothInternal :: new ( receiver, event_sender) ;
11911212 loop {
1213+ // When the IOS or MacOS device if powered off or locked
1214+ // the manager state will suddenly throw DidUpdateState event and turn off.
1215+ // If we are not exiting the main loop here the futures requested after
1216+ // power off will be stuck forever.
1217+ if cbi. get_manager_state_sync ( ) == CBManagerState :: PoweredOff {
1218+ trace ! ( "Breaking out of the corebluetooth loop. Manager is off." ) ;
1219+ break ;
1220+ }
11921221 cbi. wait_for_message ( ) . await ;
11931222 }
11941223 } )
0 commit comments