diff --git a/components/bluetooth/lib.rs b/components/bluetooth/lib.rs index cc9693c69d6b..300927d440f8 100644 --- a/components/bluetooth/lib.rs +++ b/components/bluetooth/lib.rs @@ -75,9 +75,12 @@ impl BluetoothThreadFactory for IpcSender { } else { BluetoothAdapter::init_mock() }.ok(); - thread::Builder::new().name("BluetoothThread".to_owned()).spawn(move || { - BluetoothManager::new(receiver, adapter, embedder_proxy).start(); - }).expect("Thread spawning failed"); + thread::Builder::new() + .name("BluetoothThread".to_owned()) + .spawn(move || { + BluetoothManager::new(receiver, adapter, embedder_proxy).start(); + }) + .expect("Thread spawning failed"); sender } } @@ -179,7 +182,7 @@ fn matches_filters(device: &BluetoothDevice, filters: &BluetoothScanfilterSequen return false; } - return filters.iter().any(|f| matches_filter(device, f)) + return filters.iter().any(|f| matches_filter(device, f)); } fn is_mock_adapter(adapter: &BluetoothAdapter) -> bool { @@ -205,9 +208,11 @@ pub struct BluetoothManager { } impl BluetoothManager { - pub fn new(receiver: IpcReceiver, - adapter: Option, - embedder_proxy: EmbedderProxy) -> BluetoothManager { + pub fn new( + receiver: IpcReceiver, + adapter: Option, + embedder_proxy: EmbedderProxy, + ) -> BluetoothManager { BluetoothManager { receiver: receiver, adapter: adapter, @@ -254,9 +259,11 @@ impl BluetoothManager { BluetoothRequest::Test(data_set_name, sender) => { let _ = sender.send(self.test(data_set_name)); }, - BluetoothRequest::SetRepresentedToNull(service_ids, characteristic_ids, descriptor_ids) => { - self.remove_ids_from_caches(service_ids, characteristic_ids, descriptor_ids) - }, + BluetoothRequest::SetRepresentedToNull( + service_ids, + characteristic_ids, + descriptor_ids, + ) => self.remove_ids_from_caches(service_ids, characteristic_ids, descriptor_ids), BluetoothRequest::IsRepresentedDeviceNull(id, sender) => { let _ = sender.send(!self.device_is_cached(&id)); }, @@ -266,9 +273,7 @@ impl BluetoothManager { BluetoothRequest::MatchesFilter(id, filters, sender) => { let _ = sender.send(self.device_matches_filter(&id, &filters)); }, - BluetoothRequest::Exit => { - break - }, + BluetoothRequest::Exit => break, } } } @@ -292,10 +297,12 @@ impl BluetoothManager { } } - fn remove_ids_from_caches(&mut self, - service_ids: Vec, - characteristic_ids: Vec, - descriptor_ids: Vec) { + fn remove_ids_from_caches( + &mut self, + service_ids: Vec, + characteristic_ids: Vec, + descriptor_ids: Vec, + ) { for id in service_ids { self.cached_services.remove(&id); self.service_to_device.remove(&id); @@ -315,7 +322,10 @@ impl BluetoothManager { // Adapter pub fn get_or_create_adapter(&mut self) -> Option { - let adapter_valid = self.adapter.as_ref().map_or(false, |a| a.get_address().is_ok()); + let adapter_valid = self + .adapter + .as_ref() + .map_or(false, |a| a.get_address().is_ok()); if !adapter_valid { self.adapter = BluetoothAdapter::init().ok(); } @@ -344,13 +354,14 @@ impl BluetoothManager { // Device fn get_and_cache_devices(&mut self, adapter: &mut BluetoothAdapter) -> Vec { - let devices = adapter.get_devices().unwrap_or(vec!()); + let devices = adapter.get_devices().unwrap_or(vec![]); for device in &devices { if let Ok(address) = device.get_address() { if !self.address_to_id.contains_key(&address) { let generated_id = self.generate_device_id(); self.address_to_id.insert(address, generated_id.clone()); - self.cached_devices.insert(generated_id.clone(), device.clone()); + self.cached_devices + .insert(generated_id.clone(), device.clone()); self.allowed_services.insert(generated_id, HashSet::new()); } } @@ -358,14 +369,22 @@ impl BluetoothManager { self.cached_devices.iter().map(|(_, d)| d.clone()).collect() } - fn get_device(&mut self, adapter: &mut BluetoothAdapter, device_id: &str) -> Option<&BluetoothDevice> { + fn get_device( + &mut self, + adapter: &mut BluetoothAdapter, + device_id: &str, + ) -> Option<&BluetoothDevice> { return_if_cached!(self.cached_devices, device_id); self.get_and_cache_devices(adapter); return_if_cached!(self.cached_devices, device_id); None } - fn select_device(&mut self, devices: Vec, adapter: &BluetoothAdapter) -> Option { + fn select_device( + &mut self, + devices: Vec, + adapter: &BluetoothAdapter, + ) -> Option { if is_mock_adapter(adapter) || opts::get().headless { for device in &devices { if let Ok(address) = device.get_address() { @@ -375,14 +394,19 @@ impl BluetoothManager { return None; } - let mut dialog_rows: Vec = vec!(); + let mut dialog_rows: Vec = vec![]; for device in devices { - dialog_rows.extend_from_slice(&[device.get_address().unwrap_or("".to_string()), - device.get_name().unwrap_or("".to_string())]); + dialog_rows.extend_from_slice(&[ + device.get_address().unwrap_or("".to_string()), + device.get_name().unwrap_or("".to_string()), + ]); } let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = (None, EmbedderMsg::GetSelectedBluetoothDevice(dialog_rows, ipc_sender)); + let msg = ( + None, + EmbedderMsg::GetSelectedBluetoothDevice(dialog_rows, ipc_sender), + ); self.embedder_proxy.send(msg); match ipc_receiver.recv() { @@ -390,7 +414,7 @@ impl BluetoothManager { Err(e) => { warn!("Failed to receive files from embedder ({}).", e); None - } + }, } } @@ -412,13 +436,15 @@ impl BluetoothManager { } fn device_is_cached(&self, device_id: &str) -> bool { - self.cached_devices.contains_key(device_id) && self.address_to_id.values().any(|v| v == device_id) + self.cached_devices.contains_key(device_id) && + self.address_to_id.values().any(|v| v == device_id) } - fn device_matches_filter(&mut self, - device_id: &str, - filters: &BluetoothScanfilterSequence) - -> BluetoothResult { + fn device_matches_filter( + &mut self, + device_id: &str, + filters: &BluetoothScanfilterSequence, + ) -> BluetoothResult { let mut adapter = self.get_adapter()?; match self.get_device(&mut adapter, device_id) { Some(ref device) => Ok(matches_filters(device, filters)), @@ -428,27 +454,36 @@ impl BluetoothManager { // Service - fn get_and_cache_gatt_services(&mut self, - adapter: &mut BluetoothAdapter, - device_id: &str) - -> Vec { + fn get_and_cache_gatt_services( + &mut self, + adapter: &mut BluetoothAdapter, + device_id: &str, + ) -> Vec { let mut services = match self.get_device(adapter, device_id) { - Some(d) => d.get_gatt_services().unwrap_or(vec!()), - None => vec!(), + Some(d) => d.get_gatt_services().unwrap_or(vec![]), + None => vec![], }; - services.retain(|s| !uuid_is_blocklisted(&s.get_uuid().unwrap_or(String::new()), Blocklist::All) && - self.allowed_services - .get(device_id) - .map_or(false, |uuids| uuids.contains(&s.get_uuid().unwrap_or(String::new())))); + services.retain(|s| { + !uuid_is_blocklisted(&s.get_uuid().unwrap_or(String::new()), Blocklist::All) && + self.allowed_services.get(device_id).map_or(false, |uuids| { + uuids.contains(&s.get_uuid().unwrap_or(String::new())) + }) + }); for service in &services { - self.cached_services.insert(service.get_id(), service.clone()); - self.service_to_device.insert(service.get_id(), device_id.to_owned()); + self.cached_services + .insert(service.get_id(), service.clone()); + self.service_to_device + .insert(service.get_id(), device_id.to_owned()); } services } - fn get_gatt_service(&mut self, adapter: &mut BluetoothAdapter, service_id: &str) -> Option<&BluetoothGATTService> { + fn get_gatt_service( + &mut self, + adapter: &mut BluetoothAdapter, + service_id: &str, + ) -> Option<&BluetoothGATTService> { return_if_cached!(self.cached_services, service_id); let device_id = self.service_to_device.get(service_id)?.clone(); self.get_and_cache_gatt_services(adapter, &device_id); @@ -457,34 +492,44 @@ impl BluetoothManager { } fn service_is_cached(&self, service_id: &str) -> bool { - self.cached_services.contains_key(service_id) && self.service_to_device.contains_key(service_id) + self.cached_services.contains_key(service_id) && + self.service_to_device.contains_key(service_id) } // Characteristic - fn get_and_cache_gatt_characteristics(&mut self, - adapter: &mut BluetoothAdapter, - service_id: &str) - -> Vec { + fn get_and_cache_gatt_characteristics( + &mut self, + adapter: &mut BluetoothAdapter, + service_id: &str, + ) -> Vec { let mut characteristics = match self.get_gatt_service(adapter, service_id) { - Some(s) => s.get_gatt_characteristics().unwrap_or(vec!()), - None => vec!(), + Some(s) => s.get_gatt_characteristics().unwrap_or(vec![]), + None => vec![], }; - characteristics.retain(|c| !uuid_is_blocklisted(&c.get_uuid().unwrap_or(String::new()), Blocklist::All)); + characteristics.retain(|c| { + !uuid_is_blocklisted(&c.get_uuid().unwrap_or(String::new()), Blocklist::All) + }); for characteristic in &characteristics { - self.cached_characteristics.insert(characteristic.get_id(), characteristic.clone()); - self.characteristic_to_service.insert(characteristic.get_id(), service_id.to_owned()); + self.cached_characteristics + .insert(characteristic.get_id(), characteristic.clone()); + self.characteristic_to_service + .insert(characteristic.get_id(), service_id.to_owned()); } characteristics } - fn get_gatt_characteristic(&mut self, - adapter: &mut BluetoothAdapter, - characteristic_id: &str) - -> Option<&BluetoothGATTCharacteristic> { + fn get_gatt_characteristic( + &mut self, + adapter: &mut BluetoothAdapter, + characteristic_id: &str, + ) -> Option<&BluetoothGATTCharacteristic> { return_if_cached!(self.cached_characteristics, characteristic_id); - let service_id = self.characteristic_to_service.get(characteristic_id)?.clone(); + let service_id = self + .characteristic_to_service + .get(characteristic_id)? + .clone(); self.get_and_cache_gatt_characteristics(adapter, &service_id); return_if_cached!(self.cached_characteristics, characteristic_id); None @@ -492,7 +537,7 @@ impl BluetoothManager { fn get_characteristic_properties(&self, characteristic: &BluetoothGATTCharacteristic) -> Flags { let mut props: Flags = Flags::empty(); - let flags = characteristic.get_flags().unwrap_or(vec!()); + let flags = characteristic.get_flags().unwrap_or(vec![]); for flag in flags { match flag.as_ref() { "broadcast" => props.insert(Flags::BROADCAST), @@ -512,34 +557,44 @@ impl BluetoothManager { fn characteristic_is_cached(&self, characteristic_id: &str) -> bool { self.cached_characteristics.contains_key(characteristic_id) && - self.characteristic_to_service.contains_key(characteristic_id) + self.characteristic_to_service + .contains_key(characteristic_id) } // Descriptor - fn get_and_cache_gatt_descriptors(&mut self, - adapter: &mut BluetoothAdapter, - characteristic_id: &str) - -> Vec { + fn get_and_cache_gatt_descriptors( + &mut self, + adapter: &mut BluetoothAdapter, + characteristic_id: &str, + ) -> Vec { let mut descriptors = match self.get_gatt_characteristic(adapter, characteristic_id) { - Some(c) => c.get_gatt_descriptors().unwrap_or(vec!()), - None => vec!(), + Some(c) => c.get_gatt_descriptors().unwrap_or(vec![]), + None => vec![], }; - descriptors.retain(|d| !uuid_is_blocklisted(&d.get_uuid().unwrap_or(String::new()), Blocklist::All)); + descriptors.retain(|d| { + !uuid_is_blocklisted(&d.get_uuid().unwrap_or(String::new()), Blocklist::All) + }); for descriptor in &descriptors { - self.cached_descriptors.insert(descriptor.get_id(), descriptor.clone()); - self.descriptor_to_characteristic.insert(descriptor.get_id(), characteristic_id.to_owned()); + self.cached_descriptors + .insert(descriptor.get_id(), descriptor.clone()); + self.descriptor_to_characteristic + .insert(descriptor.get_id(), characteristic_id.to_owned()); } descriptors } - fn get_gatt_descriptor(&mut self, - adapter: &mut BluetoothAdapter, - descriptor_id: &str) - -> Option<&BluetoothGATTDescriptor> { + fn get_gatt_descriptor( + &mut self, + adapter: &mut BluetoothAdapter, + descriptor_id: &str, + ) -> Option<&BluetoothGATTDescriptor> { return_if_cached!(self.cached_descriptors, descriptor_id); - let characteristic_id = self.descriptor_to_characteristic.get(descriptor_id)?.clone(); + let characteristic_id = self + .descriptor_to_characteristic + .get(descriptor_id)? + .clone(); self.get_and_cache_gatt_descriptors(adapter, &characteristic_id); return_if_cached!(self.cached_descriptors, descriptor_id); None @@ -548,9 +603,7 @@ impl BluetoothManager { // Methods // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices - fn request_device(&mut self, - options: RequestDeviceoptions) - -> BluetoothResponseResult { + fn request_device(&mut self, options: RequestDeviceoptions) -> BluetoothResponseResult { // Step 6. let mut adapter = self.get_adapter()?; @@ -569,9 +622,10 @@ impl BluetoothManager { // Step 8. if !options.is_accepting_all_devices() { - matched_devices = matched_devices.into_iter() - .filter(|d| matches_filters(d, options.get_filters())) - .collect(); + matched_devices = matched_devices + .into_iter() + .filter(|d| matches_filters(d, options.get_filters())) + .collect(); } // Step 9. @@ -623,7 +677,7 @@ impl BluetoothManager { thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS)); }, } - // TODO: Step 5.1.4: Use the exchange MTU procedure. + // TODO: Step 5.1.4: Use the exchange MTU procedure. } // Step 5.1.3. return Err(BluetoothError::Network); @@ -655,12 +709,13 @@ impl BluetoothManager { } // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_gatt_children(&mut self, - id: String, - uuid: Option, - single: bool, - child_type: GATTType) - -> BluetoothResponseResult { + fn get_gatt_children( + &mut self, + id: String, + uuid: Option, + single: bool, + child_type: GATTType, + ) -> BluetoothResponseResult { let mut adapter = self.get_adapter()?; match child_type { GATTType::PrimaryService => { @@ -670,7 +725,11 @@ impl BluetoothManager { } // Step 6. if let Some(ref uuid) = uuid { - if !self.allowed_services.get(&id).map_or(false, |s| s.contains(uuid)) { + if !self + .allowed_services + .get(&id) + .map_or(false, |s| s.contains(uuid)) + { return Err(BluetoothError::Security); } } @@ -678,17 +737,15 @@ impl BluetoothManager { if let Some(uuid) = uuid { services.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); } - let mut services_vec = vec!(); + let mut services_vec = vec![]; for service in services { if service.is_primary().unwrap_or(false) { if let Ok(uuid) = service.get_uuid() { - services_vec.push( - BluetoothServiceMsg { - uuid: uuid, - is_primary: true, - instance_id: service.get_id(), - } - ); + services_vec.push(BluetoothServiceMsg { + uuid: uuid, + is_primary: true, + instance_id: service.get_id(), + }); } } } @@ -705,29 +762,30 @@ impl BluetoothManager { return Err(BluetoothError::InvalidState); } // Step 6. - let mut characteristics = self.get_and_cache_gatt_characteristics(&mut adapter, &id); + let mut characteristics = + self.get_and_cache_gatt_characteristics(&mut adapter, &id); if let Some(uuid) = uuid { characteristics.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); } - let mut characteristics_vec = vec!(); + let mut characteristics_vec = vec![]; for characteristic in characteristics { if let Ok(uuid) = characteristic.get_uuid() { let properties = self.get_characteristic_properties(&characteristic); - characteristics_vec.push( - BluetoothCharacteristicMsg { - uuid: uuid, - instance_id: characteristic.get_id(), - broadcast: properties.contains(Flags::BROADCAST), - read: properties.contains(Flags::READ), - write_without_response: properties.contains(Flags::WRITE_WITHOUT_RESPONSE), - write: properties.contains(Flags::WRITE), - notify: properties.contains(Flags::NOTIFY), - indicate: properties.contains(Flags::INDICATE), - authenticated_signed_writes: properties.contains(Flags::AUTHENTICATED_SIGNED_WRITES), - reliable_write: properties.contains(Flags::RELIABLE_WRITE), - writable_auxiliaries: properties.contains(Flags::WRITABLE_AUXILIARIES), - } - ); + characteristics_vec.push(BluetoothCharacteristicMsg { + uuid: uuid, + instance_id: characteristic.get_id(), + broadcast: properties.contains(Flags::BROADCAST), + read: properties.contains(Flags::READ), + write_without_response: properties + .contains(Flags::WRITE_WITHOUT_RESPONSE), + write: properties.contains(Flags::WRITE), + notify: properties.contains(Flags::NOTIFY), + indicate: properties.contains(Flags::INDICATE), + authenticated_signed_writes: properties + .contains(Flags::AUTHENTICATED_SIGNED_WRITES), + reliable_write: properties.contains(Flags::RELIABLE_WRITE), + writable_auxiliaries: properties.contains(Flags::WRITABLE_AUXILIARIES), + }); } } @@ -736,7 +794,10 @@ impl BluetoothManager { return Err(BluetoothError::NotFound); } - return Ok(BluetoothResponse::GetCharacteristics(characteristics_vec, single)); + return Ok(BluetoothResponse::GetCharacteristics( + characteristics_vec, + single, + )); }, GATTType::IncludedService => { // Step 5. @@ -752,17 +813,15 @@ impl BluetoothManager { Some(s) => s, None => return Err(BluetoothError::NotFound), }; - let services = primary_service.get_includes(device).unwrap_or(vec!()); - let mut services_vec = vec!(); + let services = primary_service.get_includes(device).unwrap_or(vec![]); + let mut services_vec = vec![]; for service in services { if let Ok(service_uuid) = service.get_uuid() { - services_vec.push( - BluetoothServiceMsg { - uuid: service_uuid, - is_primary: service.is_primary().unwrap_or(false), - instance_id: service.get_id(), - } - ); + services_vec.push(BluetoothServiceMsg { + uuid: service_uuid, + is_primary: service.is_primary().unwrap_or(false), + instance_id: service.get_id(), + }); } } if let Some(uuid) = uuid { @@ -787,15 +846,13 @@ impl BluetoothManager { if let Some(uuid) = uuid { descriptors.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); } - let mut descriptors_vec = vec!(); + let mut descriptors_vec = vec![]; for descriptor in descriptors { if let Ok(uuid) = descriptor.get_uuid() { - descriptors_vec.push( - BluetoothDescriptorMsg { - uuid: uuid, - instance_id: descriptor.get_id(), - } - ); + descriptors_vec.push(BluetoothDescriptorMsg { + uuid: uuid, + instance_id: descriptor.get_id(), + }); } } @@ -816,15 +873,17 @@ impl BluetoothManager { let mut adapter = self.get_adapter()?; // (Characteristic) Step 5.3. - let mut value = self.get_gatt_characteristic(&mut adapter, &id) - .map(|c| c.read_value().unwrap_or(vec![])); + let mut value = self + .get_gatt_characteristic(&mut adapter, &id) + .map(|c| c.read_value().unwrap_or(vec![])); // (Characteristic) TODO: Step 5.4: Handle all the errors returned from the read_value call. // (Descriptor) Step 5.2. if value.is_none() { - value = self.get_gatt_descriptor(&mut adapter, &id) - .map(|d| d.read_value().unwrap_or(vec![])); + value = self + .get_gatt_descriptor(&mut adapter, &id) + .map(|d| d.read_value().unwrap_or(vec![])); } // (Descriptor) TODO: Step 5.3: Handle all the errors returned from the read_value call. @@ -848,15 +907,17 @@ impl BluetoothManager { let mut adapter = self.get_adapter()?; // (Characteristic) Step 7.3. - let mut result = self.get_gatt_characteristic(&mut adapter, &id) - .map(|c| c.write_value(value.clone())); + let mut result = self + .get_gatt_characteristic(&mut adapter, &id) + .map(|c| c.write_value(value.clone())); // (Characteristic) TODO: Step 7.4: Handle all the errors returned from the write_value call. // (Descriptor) Step 7.2. if result.is_none() { - result = self.get_gatt_descriptor(&mut adapter, &id) - .map(|d| d.write_value(value.clone())); + result = self + .get_gatt_descriptor(&mut adapter, &id) + .map(|d| d.write_value(value.clone())); } // (Descriptor) TODO: Step 7.3: Handle all the errors returned from the write_value call. @@ -921,6 +982,8 @@ impl BluetoothManager { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability fn get_availability(&mut self) -> BluetoothResponseResult { - Ok(BluetoothResponse::GetAvailability(self.get_adapter().is_ok())) + Ok(BluetoothResponse::GetAvailability( + self.get_adapter().is_ok(), + )) } } diff --git a/components/bluetooth/test.rs b/components/bluetooth/test.rs index 29541123d4a1..d7410719608f 100644 --- a/components/bluetooth/test.rs +++ b/components/bluetooth/test.rs @@ -34,7 +34,8 @@ const UNICODE_DEVICE_ADAPTER: &'static str = "UnicodeDeviceAdapter"; // https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=205 const MISSING_SERVICE_HEART_RATE_ADAPTER: &'static str = "MissingServiceHeartRateAdapter"; // https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=219 -const MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER: &'static str = "MissingCharacteristicHeartRateAdapter"; +const MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER: &'static str = + "MissingCharacteristicHeartRateAdapter"; const MISSING_DESCRIPTOR_HEART_RATE_ADAPTER: &'static str = "MissingDescriptorHeartRateAdapter"; // https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=234 const HEART_RATE_ADAPTER: &'static str = "HeartRateAdapter"; @@ -80,32 +81,38 @@ const HUMAN_INTERFACE_DEVICE_SERVICE_UUID: &'static str = "00001812-0000-1000-80 const TX_POWER_SERVICE_UUID: &'static str = "00001804-0000-1000-8000-00805f9b34fb"; // Characteristic UUIDs -const BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID: &'static str = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135"; +const BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID: &'static str = + "bad1c9a2-9a5b-4015-8b60-1579bbbf2135"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml -const BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID: &'static str = "00002a38-0000-1000-8000-00805f9b34fb"; +const BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID: &'static str = + "00002a38-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.characteristic.gap.device_name.xml const DEVICE_NAME_CHARACTERISTIC_UUID: &'static str = "00002a00-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml -const HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID: &'static str = "00002a37-0000-1000-8000-00805f9b34fb"; +const HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID: &'static str = + "00002a37-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.characteristic.gap.peripheral_privacy_flag.xml -const PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID: &'static str = "00002a02-0000-1000-8000-00805f9b34fb"; +const PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID: &'static str = + "00002a02-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.characteristic.serial_number_string.xml const SERIAL_NUMBER_STRING_UUID: &'static str = "00002a25-0000-1000-8000-00805f9b34fb"; // Descriptor UUIDs -const BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID: &'static str = "aaaaaaaa-aaaa-1181-0510-810819516110"; +const BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID: &'static str = + "aaaaaaaa-aaaa-1181-0510-810819516110"; const BLOCKLIST_DESCRIPTOR_UUID: &'static str = "07711111-6104-0970-7011-1107105110aa"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml const CHARACTERISTIC_USER_DESCRIPTION_UUID: &'static str = "00002901-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml -const CLIENT_CHARACTERISTIC_CONFIGURATION_UUID: &'static str = "00002902-0000-1000-8000-00805f9b34fb"; +const CLIENT_CHARACTERISTIC_CONFIGURATION_UUID: &'static str = + "00002902-0000-1000-8000-00805f9b34fb"; // https://www.bluetooth.com/specifications/gatt/ // viewer?attributeXmlFile=org.bluetooth.descriptor.number_of_digitals.xml const NUMBER_OF_DIGITALS_UUID: &'static str = "00002909-0000-1000-8000-00805f9b34fb"; @@ -117,12 +124,12 @@ fn generate_id() -> Uuid { let mut generated = false; while !generated { id = Uuid::new_v4(); - CACHED_IDS.with(|cache| + CACHED_IDS.with(|cache| { if !cache.borrow().contains(&id) { cache.borrow_mut().insert(id.clone()); generated = true; } - ); + }); } id } @@ -136,10 +143,11 @@ fn set_adapter(adapter: &BluetoothAdapter, adapter_name: String) -> Result<(), B } // Create Device -fn create_device(adapter: &BluetoothAdapter, - name: String, - address: String) - -> Result> { +fn create_device( + adapter: &BluetoothAdapter, + name: String, + address: String, +) -> Result> { let device = BluetoothDevice::create_mock_device(adapter.clone(), generate_id().to_string())?; device.set_name(Some(name))?; device.set_address(address)?; @@ -148,162 +156,192 @@ fn create_device(adapter: &BluetoothAdapter, } // Create Device with UUIDs -fn create_device_with_uuids(adapter: &BluetoothAdapter, - name: String, - address: String, - uuids: Vec) - -> Result> { +fn create_device_with_uuids( + adapter: &BluetoothAdapter, + name: String, + address: String, + uuids: Vec, +) -> Result> { let device = create_device(adapter, name, address)?; device.set_uuids(uuids)?; Ok(device) } // Create Service -fn create_service(device: &BluetoothDevice, - uuid: String) - -> Result> { - let service = BluetoothGATTService::create_mock_service(device.clone(), generate_id().to_string())?; +fn create_service( + device: &BluetoothDevice, + uuid: String, +) -> Result> { + let service = + BluetoothGATTService::create_mock_service(device.clone(), generate_id().to_string())?; service.set_uuid(uuid)?; Ok(service) } // Create Characteristic -fn create_characteristic(service: &BluetoothGATTService, - uuid: String) - -> Result> { - let characteristic = - BluetoothGATTCharacteristic::create_mock_characteristic(service.clone(), generate_id().to_string())?; +fn create_characteristic( + service: &BluetoothGATTService, + uuid: String, +) -> Result> { + let characteristic = BluetoothGATTCharacteristic::create_mock_characteristic( + service.clone(), + generate_id().to_string(), + )?; characteristic.set_uuid(uuid)?; Ok(characteristic) } // Create Characteristic with value -fn create_characteristic_with_value(service: &BluetoothGATTService, - uuid: String, - value: Vec) - -> Result> { +fn create_characteristic_with_value( + service: &BluetoothGATTService, + uuid: String, + value: Vec, +) -> Result> { let characteristic = create_characteristic(service, uuid)?; characteristic.set_value(value)?; Ok(characteristic) } // Create Descriptor -fn create_descriptor(characteristic: &BluetoothGATTCharacteristic, - uuid: String) - -> Result> { - let descriptor = - BluetoothGATTDescriptor::create_mock_descriptor(characteristic.clone(), generate_id().to_string())?; +fn create_descriptor( + characteristic: &BluetoothGATTCharacteristic, + uuid: String, +) -> Result> { + let descriptor = BluetoothGATTDescriptor::create_mock_descriptor( + characteristic.clone(), + generate_id().to_string(), + )?; descriptor.set_uuid(uuid)?; Ok(descriptor) } // Create Descriptor with value -fn create_descriptor_with_value(characteristic: &BluetoothGATTCharacteristic, - uuid: String, - value: Vec) - -> Result> { +fn create_descriptor_with_value( + characteristic: &BluetoothGATTCharacteristic, + uuid: String, + value: Vec, +) -> Result> { let descriptor = create_descriptor(characteristic, uuid)?; descriptor.set_value(value)?; Ok(descriptor) } -fn create_heart_rate_service(device: &BluetoothDevice, - empty: bool) - -> Result> { +fn create_heart_rate_service( + device: &BluetoothDevice, + empty: bool, +) -> Result> { // Heart Rate Service let heart_rate_service = create_service(device, HEART_RATE_SERVICE_UUID.to_owned())?; if empty { - return Ok(heart_rate_service) + return Ok(heart_rate_service); } // Heart Rate Measurement Characteristic - let heart_rate_measurement_characteristic = - create_characteristic_with_value(&heart_rate_service, - HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(), - vec![0])?; - heart_rate_measurement_characteristic.set_flags(vec![NOTIFY_FLAG.to_string(), - READ_FLAG.to_string(), - WRITE_FLAG.to_string()])?; + let heart_rate_measurement_characteristic = create_characteristic_with_value( + &heart_rate_service, + HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(), + vec![0], + )?; + heart_rate_measurement_characteristic.set_flags(vec![ + NOTIFY_FLAG.to_string(), + READ_FLAG.to_string(), + WRITE_FLAG.to_string(), + ])?; // Body Sensor Location Characteristic 1 - let body_sensor_location_characteristic_1 = - create_characteristic_with_value(&heart_rate_service, - BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), - vec![49])?; - body_sensor_location_characteristic_1.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; + let body_sensor_location_characteristic_1 = create_characteristic_with_value( + &heart_rate_service, + BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), + vec![49], + )?; + body_sensor_location_characteristic_1 + .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; // Body Sensor Location Characteristic 2 - let body_sensor_location_characteristic_2 = - create_characteristic_with_value(&heart_rate_service, - BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), - vec![50])?; - body_sensor_location_characteristic_2.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; + let body_sensor_location_characteristic_2 = create_characteristic_with_value( + &heart_rate_service, + BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), + vec![50], + )?; + body_sensor_location_characteristic_2 + .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; Ok(heart_rate_service) } -fn create_generic_access_service(device: &BluetoothDevice, - empty: bool) - -> Result> { +fn create_generic_access_service( + device: &BluetoothDevice, + empty: bool, +) -> Result> { // Generic Access Service - let generic_access_service = - create_service(device, GENERIC_ACCESS_SERVICE_UUID.to_owned())?; + let generic_access_service = create_service(device, GENERIC_ACCESS_SERVICE_UUID.to_owned())?; if empty { - return Ok(generic_access_service) + return Ok(generic_access_service); } // Device Name Characteristic - let device_name_characteristic = - create_characteristic_with_value(&generic_access_service, - DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(), - HEART_RATE_DEVICE_NAME.as_bytes().to_vec())?; + let device_name_characteristic = create_characteristic_with_value( + &generic_access_service, + DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(), + HEART_RATE_DEVICE_NAME.as_bytes().to_vec(), + )?; device_name_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; // Number of Digitals descriptor - let number_of_digitals_descriptor_1 = - create_descriptor_with_value(&device_name_characteristic, - NUMBER_OF_DIGITALS_UUID.to_owned(), - vec![49])?; + let number_of_digitals_descriptor_1 = create_descriptor_with_value( + &device_name_characteristic, + NUMBER_OF_DIGITALS_UUID.to_owned(), + vec![49], + )?; number_of_digitals_descriptor_1.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; - let number_of_digitals_descriptor_2 = - create_descriptor_with_value(&device_name_characteristic, - NUMBER_OF_DIGITALS_UUID.to_owned(), - vec![50])?; + let number_of_digitals_descriptor_2 = create_descriptor_with_value( + &device_name_characteristic, + NUMBER_OF_DIGITALS_UUID.to_owned(), + vec![50], + )?; number_of_digitals_descriptor_2.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; // Characteristic User Description Descriptor - let _characteristic_user_description = - create_descriptor_with_value(&device_name_characteristic, - CHARACTERISTIC_USER_DESCRIPTION_UUID.to_owned(), - HEART_RATE_DEVICE_NAME_DESCRIPTION.as_bytes().to_vec())?; + let _characteristic_user_description = create_descriptor_with_value( + &device_name_characteristic, + CHARACTERISTIC_USER_DESCRIPTION_UUID.to_owned(), + HEART_RATE_DEVICE_NAME_DESCRIPTION.as_bytes().to_vec(), + )?; // Client Characteristic Configuration descriptor - let _client_characteristic_configuration = - create_descriptor_with_value(&device_name_characteristic, - CLIENT_CHARACTERISTIC_CONFIGURATION_UUID.to_owned(), - vec![0])?; + let _client_characteristic_configuration = create_descriptor_with_value( + &device_name_characteristic, + CLIENT_CHARACTERISTIC_CONFIGURATION_UUID.to_owned(), + vec![0], + )?; // Peripheral Privacy Flag Characteristic - let peripheral_privacy_flag_characteristic = - create_characteristic(&generic_access_service, PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned())?; + let peripheral_privacy_flag_characteristic = create_characteristic( + &generic_access_service, + PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned(), + )?; peripheral_privacy_flag_characteristic - .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; + .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; Ok(generic_access_service) } // Create Heart Rate Device -fn create_heart_rate_device(adapter: &BluetoothAdapter, - empty: bool) - -> Result> { +fn create_heart_rate_device( + adapter: &BluetoothAdapter, + empty: bool, +) -> Result> { // Heart Rate Device - let heart_rate_device = - create_device_with_uuids(adapter, - HEART_RATE_DEVICE_NAME.to_owned(), - HEART_RATE_DEVICE_ADDRESS.to_owned(), - vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(), - HEART_RATE_SERVICE_UUID.to_owned()])?; + let heart_rate_device = create_device_with_uuids( + adapter, + HEART_RATE_DEVICE_NAME.to_owned(), + HEART_RATE_DEVICE_ADDRESS.to_owned(), + vec![ + GENERIC_ACCESS_SERVICE_UUID.to_owned(), + HEART_RATE_SERVICE_UUID.to_owned(), + ], + )?; if empty { return Ok(heart_rate_device); @@ -318,30 +356,39 @@ fn create_heart_rate_device(adapter: &BluetoothAdapter, Ok(heart_rate_device) } -fn create_missing_characterisitc_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box> { +fn create_missing_characterisitc_heart_rate_device( + adapter: &BluetoothAdapter, +) -> Result<(), Box> { let heart_rate_device_empty = create_heart_rate_device(adapter, true)?; - let _generic_access_service_empty = create_generic_access_service(&heart_rate_device_empty, true)?; + let _generic_access_service_empty = + create_generic_access_service(&heart_rate_device_empty, true)?; let _heart_rate_service_empty = create_heart_rate_service(&heart_rate_device_empty, true)?; Ok(()) } -fn create_missing_descriptor_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box> { +fn create_missing_descriptor_heart_rate_device( + adapter: &BluetoothAdapter, +) -> Result<(), Box> { let heart_rate_device_empty = create_heart_rate_device(adapter, true)?; - let generic_access_service_empty = create_generic_access_service(&heart_rate_device_empty, true)?; + let generic_access_service_empty = + create_generic_access_service(&heart_rate_device_empty, true)?; - let _device_name_characteristic = - create_characteristic_with_value(&generic_access_service_empty, - DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(), - HEART_RATE_DEVICE_NAME.as_bytes().to_vec())?; + let _device_name_characteristic = create_characteristic_with_value( + &generic_access_service_empty, + DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(), + HEART_RATE_DEVICE_NAME.as_bytes().to_vec(), + )?; - let peripheral_privacy_flag_characteristic = - create_characteristic(&generic_access_service_empty, - PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned())?; - peripheral_privacy_flag_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; + let peripheral_privacy_flag_characteristic = create_characteristic( + &generic_access_service_empty, + PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned(), + )?; + peripheral_privacy_flag_characteristic + .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; let _heart_rate_service = create_heart_rate_service(&heart_rate_device_empty, false)?; @@ -351,9 +398,11 @@ fn create_missing_descriptor_heart_rate_device(adapter: &BluetoothAdapter) -> Re fn create_two_heart_rate_services_device(adapter: &BluetoothAdapter) -> Result<(), Box> { let heart_rate_device_empty = create_heart_rate_device(adapter, true)?; - heart_rate_device_empty.set_uuids(vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(), - HEART_RATE_SERVICE_UUID.to_owned(), - HEART_RATE_SERVICE_UUID.to_owned()])?; + heart_rate_device_empty.set_uuids(vec![ + GENERIC_ACCESS_SERVICE_UUID.to_owned(), + HEART_RATE_SERVICE_UUID.to_owned(), + HEART_RATE_SERVICE_UUID.to_owned(), + ])?; let _generic_access_service = create_generic_access_service(&heart_rate_device_empty, false)?; @@ -361,73 +410,92 @@ fn create_two_heart_rate_services_device(adapter: &BluetoothAdapter) -> Result<( let heart_rate_service_empty_2 = create_heart_rate_service(&heart_rate_device_empty, true)?; - let heart_rate_measurement_characteristic = - create_characteristic_with_value(&heart_rate_service_empty_1, - HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(), - vec![0])?; + let heart_rate_measurement_characteristic = create_characteristic_with_value( + &heart_rate_service_empty_1, + HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(), + vec![0], + )?; heart_rate_measurement_characteristic.set_flags(vec![NOTIFY_FLAG.to_string()])?; - let _body_sensor_location_characteristic_1 = - create_characteristic_with_value(&heart_rate_service_empty_1, - BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), - vec![49])?; - - let _body_sensor_location_characteristic_2 = - create_characteristic_with_value(&heart_rate_service_empty_2, - BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), - vec![50])?; + let _body_sensor_location_characteristic_1 = create_characteristic_with_value( + &heart_rate_service_empty_1, + BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), + vec![49], + )?; + + let _body_sensor_location_characteristic_2 = create_characteristic_with_value( + &heart_rate_service_empty_2, + BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), + vec![50], + )?; Ok(()) } fn create_blocklisted_device(adapter: &BluetoothAdapter) -> Result<(), Box> { - let connectable_device = - create_device_with_uuids(adapter, - CONNECTABLE_DEVICE_NAME.to_owned(), - CONNECTABLE_DEVICE_ADDRESS.to_owned(), - vec![BLOCKLIST_TEST_SERVICE_UUID.to_owned(), - DEVICE_INFORMATION_UUID.to_owned(), - GENERIC_ACCESS_SERVICE_UUID.to_owned(), - HEART_RATE_SERVICE_UUID.to_owned(), - HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned()])?; - - let blocklist_test_service = create_service(&connectable_device, BLOCKLIST_TEST_SERVICE_UUID.to_owned())?; - - let blocklist_exclude_reads_characteristic = - create_characteristic(&blocklist_test_service, - BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID.to_owned())?; + let connectable_device = create_device_with_uuids( + adapter, + CONNECTABLE_DEVICE_NAME.to_owned(), + CONNECTABLE_DEVICE_ADDRESS.to_owned(), + vec![ + BLOCKLIST_TEST_SERVICE_UUID.to_owned(), + DEVICE_INFORMATION_UUID.to_owned(), + GENERIC_ACCESS_SERVICE_UUID.to_owned(), + HEART_RATE_SERVICE_UUID.to_owned(), + HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned(), + ], + )?; + + let blocklist_test_service = + create_service(&connectable_device, BLOCKLIST_TEST_SERVICE_UUID.to_owned())?; + + let blocklist_exclude_reads_characteristic = create_characteristic( + &blocklist_test_service, + BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID.to_owned(), + )?; blocklist_exclude_reads_characteristic - .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; + .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?; - let _blocklist_exclude_reads_descriptor = - create_descriptor_with_value(&blocklist_exclude_reads_characteristic, - BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID.to_owned(), - vec![54; 3])?; + let _blocklist_exclude_reads_descriptor = create_descriptor_with_value( + &blocklist_exclude_reads_characteristic, + BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID.to_owned(), + vec![54; 3], + )?; - let _blocklist_descriptor = - create_descriptor_with_value(&blocklist_exclude_reads_characteristic, - BLOCKLIST_DESCRIPTOR_UUID.to_owned(), - vec![54; 3])?; + let _blocklist_descriptor = create_descriptor_with_value( + &blocklist_exclude_reads_characteristic, + BLOCKLIST_DESCRIPTOR_UUID.to_owned(), + vec![54; 3], + )?; - let device_information_service = create_service(&connectable_device, DEVICE_INFORMATION_UUID.to_owned())?; + let device_information_service = + create_service(&connectable_device, DEVICE_INFORMATION_UUID.to_owned())?; - let _serial_number_string_characteristic = - create_characteristic(&device_information_service, SERIAL_NUMBER_STRING_UUID.to_owned())?; + let _serial_number_string_characteristic = create_characteristic( + &device_information_service, + SERIAL_NUMBER_STRING_UUID.to_owned(), + )?; let _generic_access_service = create_generic_access_service(&connectable_device, false)?; let _heart_rate_service = create_heart_rate_service(&connectable_device, false)?; - let _human_interface_device_service = - create_service(&connectable_device, HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned())?; + let _human_interface_device_service = create_service( + &connectable_device, + HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned(), + )?; Ok(()) } fn create_glucose_heart_rate_devices(adapter: &BluetoothAdapter) -> Result<(), Box> { - let glucose_devie = create_device_with_uuids(adapter, - GLUCOSE_DEVICE_NAME.to_owned(), - GLUCOSE_DEVICE_ADDRESS.to_owned(), - vec![GLUCOSE_SERVICE_UUID.to_owned(), - TX_POWER_SERVICE_UUID.to_owned()])?; + let glucose_devie = create_device_with_uuids( + adapter, + GLUCOSE_DEVICE_NAME.to_owned(), + GLUCOSE_DEVICE_ADDRESS.to_owned(), + vec![ + GLUCOSE_SERVICE_UUID.to_owned(), + TX_POWER_SERVICE_UUID.to_owned(), + ], + )?; let heart_rate_device_empty = create_heart_rate_device(adapter, true)?; @@ -470,9 +538,11 @@ pub fn test(manager: &mut BluetoothManager, data_set_name: String) -> Result<(), UNICODE_DEVICE_ADAPTER => { set_adapter(adapter, UNICODE_DEVICE_ADAPTER.to_owned())?; - let _unicode_device = create_device(adapter, - UNICODE_DEVICE_NAME.to_owned(), - UNICODE_DEVICE_ADDRESS.to_owned())?; + let _unicode_device = create_device( + adapter, + UNICODE_DEVICE_NAME.to_owned(), + UNICODE_DEVICE_ADDRESS.to_owned(), + )?; }, MISSING_SERVICE_HEART_RATE_ADAPTER => { set_adapter(adapter, MISSING_SERVICE_HEART_RATE_ADAPTER.to_owned())?; @@ -480,7 +550,10 @@ pub fn test(manager: &mut BluetoothManager, data_set_name: String) -> Result<(), let _heart_rate_device_empty = create_heart_rate_device(adapter, true)?; }, MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER => { - set_adapter(adapter, MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER.to_owned())?; + set_adapter( + adapter, + MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER.to_owned(), + )?; let _ = create_missing_characterisitc_heart_rate_device(adapter)?; },