|
10 | 10 |
|
11 | 11 | use super::{
|
12 | 12 | central_delegate::{CentralDelegate, CentralDelegateEvent},
|
13 |
| - framework::cb::{self, CBManagerAuthorization, CBPeripheralState}, |
| 13 | + framework::cb::{self, CBManagerAuthorization, CBManagerState, CBPeripheralState}, |
14 | 14 | future::{BtlePlugFuture, BtlePlugFutureStateShared},
|
15 | 15 | utils::{
|
16 | 16 | core_bluetooth::{cbuuid_to_uuid, uuid_to_cbuuid},
|
@@ -139,6 +139,7 @@ pub enum CoreBluetoothReply {
|
139 | 139 | ReadResult(Vec<u8>),
|
140 | 140 | Connected(BTreeSet<Service>),
|
141 | 141 | State(CBPeripheralState),
|
| 142 | + ManagerState(CBManagerState), |
142 | 143 | Ok,
|
143 | 144 | Err(String),
|
144 | 145 | }
|
@@ -399,11 +400,14 @@ pub enum CoreBluetoothMessage {
|
399 | 400 | data: Vec<u8>,
|
400 | 401 | future: CoreBluetoothReplyStateShared,
|
401 | 402 | },
|
| 403 | + FetchManagerState { |
| 404 | + future: CoreBluetoothReplyStateShared, |
| 405 | + }, |
402 | 406 | }
|
403 | 407 |
|
404 | 408 | #[derive(Debug)]
|
405 | 409 | pub enum CoreBluetoothEvent {
|
406 |
| - AdapterConnected, |
| 410 | + DidUpdateState, |
407 | 411 | DeviceDiscovered {
|
408 | 412 | uuid: Uuid,
|
409 | 413 | name: Option<String>,
|
@@ -789,6 +793,18 @@ impl CoreBluetoothInternal {
|
789 | 793 | }
|
790 | 794 | }
|
791 | 795 |
|
| 796 | + fn get_manager_state(&mut self) -> CBManagerState { |
| 797 | + cb::centeralmanger_state(&*self.manager) |
| 798 | + } |
| 799 | + |
| 800 | + fn get_manager_state_async(&mut self, fut: CoreBluetoothReplyStateShared) { |
| 801 | + let state = cb::centeralmanger_state(&*self.manager); |
| 802 | + trace!("Manager state {:?} ", state); |
| 803 | + fut.lock() |
| 804 | + .unwrap() |
| 805 | + .set_reply(CoreBluetoothReply::ManagerState(state)); |
| 806 | + } |
| 807 | + |
792 | 808 | fn write_value(
|
793 | 809 | &mut self,
|
794 | 810 | peripheral_uuid: Uuid,
|
@@ -831,6 +847,11 @@ impl CoreBluetoothInternal {
|
831 | 847 | characteristic_uuid: Uuid,
|
832 | 848 | fut: CoreBluetoothReplyStateShared,
|
833 | 849 | ) {
|
| 850 | + trace!( |
| 851 | + "Manager State {:?}", |
| 852 | + cb::centeralmanger_state(&*self.manager) |
| 853 | + ); |
| 854 | + |
834 | 855 | if let Some(peripheral) = self.peripherals.get_mut(&peripheral_uuid) {
|
835 | 856 | if let Some(service) = peripheral.services.get_mut(&service_uuid) {
|
836 | 857 | if let Some(characteristic) = service.characteristics.get_mut(&characteristic_uuid)
|
@@ -1004,7 +1025,7 @@ impl CoreBluetoothInternal {
|
1004 | 1025 | // "ready" variable in our adapter that will cause scans/etc
|
1005 | 1026 | // to fail if this hasn't updated.
|
1006 | 1027 | CentralDelegateEvent::DidUpdateState => {
|
1007 |
| - self.dispatch_event(CoreBluetoothEvent::AdapterConnected).await |
| 1028 | + self.dispatch_event(CoreBluetoothEvent::DidUpdateState).await |
1008 | 1029 | }
|
1009 | 1030 | CentralDelegateEvent::DiscoveredPeripheral{cbperipheral} => {
|
1010 | 1031 | self.on_discovered_peripheral(cbperipheral).await
|
@@ -1103,6 +1124,9 @@ impl CoreBluetoothInternal {
|
1103 | 1124 | CoreBluetoothMessage::IsConnected{peripheral_uuid, future} => {
|
1104 | 1125 | self.is_connected(peripheral_uuid, future);
|
1105 | 1126 | },
|
| 1127 | + CoreBluetoothMessage::FetchManagerState {future} =>{ |
| 1128 | + self.get_manager_state_async(future); |
| 1129 | + }, |
1106 | 1130 | CoreBluetoothMessage::ReadDescriptorValue{peripheral_uuid, service_uuid, characteristic_uuid, descriptor_uuid, future} => {
|
1107 | 1131 | self.read_descriptor_value(peripheral_uuid, service_uuid, characteristic_uuid, descriptor_uuid, future)
|
1108 | 1132 | }
|
@@ -1184,6 +1208,14 @@ pub fn run_corebluetooth_thread(
|
1184 | 1208 | runtime.block_on(async move {
|
1185 | 1209 | let mut cbi = CoreBluetoothInternal::new(receiver, event_sender);
|
1186 | 1210 | loop {
|
| 1211 | + // When the IOS or MacOS device if powered off or locked |
| 1212 | + // the manager state will suddenly throw DidUpdateState event and turn off. |
| 1213 | + // If we are not exiting the main loop here the futures requested after |
| 1214 | + // power off will be stuck forever. |
| 1215 | + if cbi.get_manager_state() == CBManagerState::PoweredOff { |
| 1216 | + trace!("Breaking out of the corebluetooth loop. Manager is off."); |
| 1217 | + break; |
| 1218 | + } |
1187 | 1219 | cbi.wait_for_message().await;
|
1188 | 1220 | }
|
1189 | 1221 | })
|
|
0 commit comments