bluetooth/
test.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::borrow::ToOwned;
6use std::cell::RefCell;
7use std::collections::{HashMap, HashSet};
8use std::error::Error;
9use std::string::String;
10
11use uuid::Uuid;
12
13use crate::BluetoothManager;
14use crate::bluetooth::{
15    BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic, BluetoothGATTDescriptor,
16    BluetoothGATTService,
17};
18
19thread_local!(pub static CACHED_IDS: RefCell<HashSet<Uuid>> = RefCell::new(HashSet::new()));
20
21const ADAPTER_ERROR: &str = "No adapter found";
22const WRONG_DATA_SET_ERROR: &str = "Wrong data set name was provided";
23const READ_FLAG: &str = "read";
24const WRITE_FLAG: &str = "write";
25const NOTIFY_FLAG: &str = "notify";
26
27// Adapter names
28// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=65
29const NOT_PRESENT_ADAPTER: &str = "NotPresentAdapter";
30// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=83
31const NOT_POWERED_ADAPTER: &str = "NotPoweredAdapter";
32// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=118
33const EMPTY_ADAPTER: &str = "EmptyAdapter";
34// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=126
35const GLUCOSE_HEART_RATE_ADAPTER: &str = "GlucoseHeartRateAdapter";
36// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=135
37const UNICODE_DEVICE_ADAPTER: &str = "UnicodeDeviceAdapter";
38// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=205
39const MISSING_SERVICE_HEART_RATE_ADAPTER: &str = "MissingServiceHeartRateAdapter";
40// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=219
41const MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER: &str = "MissingCharacteristicHeartRateAdapter";
42const MISSING_DESCRIPTOR_HEART_RATE_ADAPTER: &str = "MissingDescriptorHeartRateAdapter";
43// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=234
44const HEART_RATE_ADAPTER: &str = "HeartRateAdapter";
45// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=250
46const EMPTY_NAME_HEART_RATE_ADAPTER: &str = "EmptyNameHeartRateAdapter";
47// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=267
48const NO_NAME_HEART_RATE_ADAPTER: &str = "NoNameHeartRateAdapter";
49// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=284
50const TWO_HEART_RATE_SERVICES_ADAPTER: &str = "TwoHeartRateServicesAdapter";
51const BLOCKLIST_TEST_ADAPTER: &str = "BlocklistTestAdapter";
52
53// Device names
54const CONNECTABLE_DEVICE_NAME: &str = "Connectable Device";
55const EMPTY_DEVICE_NAME: &str = "";
56// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
57const GLUCOSE_DEVICE_NAME: &str = "Glucose Device";
58// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
59const HEART_RATE_DEVICE_NAME: &str = "Heart Rate Device";
60const UNICODE_DEVICE_NAME: &str = "❤❤❤❤❤❤❤❤❤";
61
62// Device addresses
63const CONNECTABLE_DEVICE_ADDRESS: &str = "00:00:00:00:00:04";
64// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
65const GLUCOSE_DEVICE_ADDRESS: &str = "00:00:00:00:00:02";
66// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
67const HEART_RATE_DEVICE_ADDRESS: &str = "00:00:00:00:00:03";
68const UNICODE_DEVICE_ADDRESS: &str = "00:00:00:00:00:01";
69
70// Service UUIDs
71const BLOCKLIST_TEST_SERVICE_UUID: &str = "611c954a-263b-4f4a-aab6-01ddb953f985";
72// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.device_information.xml
73const DEVICE_INFORMATION_UUID: &str = "0000180a-0000-1000-8000-00805f9b34fb";
74// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.generic_access.xml
75const GENERIC_ACCESS_SERVICE_UUID: &str = "00001800-0000-1000-8000-00805f9b34fb";
76// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.glucose.xml
77const GLUCOSE_SERVICE_UUID: &str = "00001808-0000-1000-8000-00805f9b34fb";
78// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
79const HEART_RATE_SERVICE_UUID: &str = "0000180d-0000-1000-8000-00805f9b34fb";
80// https://www.bluetooth.com/specifications/gatt/
81// viewer?attributeXmlFile=org.bluetooth.service.human_interface_device.xml
82const HUMAN_INTERFACE_DEVICE_SERVICE_UUID: &str = "00001812-0000-1000-8000-00805f9b34fb";
83// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.tx_power.xml
84const TX_POWER_SERVICE_UUID: &str = "00001804-0000-1000-8000-00805f9b34fb";
85
86// Characteristic UUIDs
87const BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID: &str = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
88// https://www.bluetooth.com/specifications/gatt/
89// viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml
90const BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID: &str = "00002a38-0000-1000-8000-00805f9b34fb";
91// https://www.bluetooth.com/specifications/gatt/
92// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.device_name.xml
93const DEVICE_NAME_CHARACTERISTIC_UUID: &str = "00002a00-0000-1000-8000-00805f9b34fb";
94// https://www.bluetooth.com/specifications/gatt/
95// viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml
96const HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID: &str = "00002a37-0000-1000-8000-00805f9b34fb";
97// https://www.bluetooth.com/specifications/gatt/
98// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.peripheral_privacy_flag.xml
99const PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID: &str = "00002a02-0000-1000-8000-00805f9b34fb";
100// https://www.bluetooth.com/specifications/gatt/
101// viewer?attributeXmlFile=org.bluetooth.characteristic.serial_number_string.xml
102const SERIAL_NUMBER_STRING_UUID: &str = "00002a25-0000-1000-8000-00805f9b34fb";
103
104// Descriptor UUIDs
105const BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID: &str = "aaaaaaaa-aaaa-1181-0510-810819516110";
106const BLOCKLIST_DESCRIPTOR_UUID: &str = "07711111-6104-0970-7011-1107105110aa";
107// https://www.bluetooth.com/specifications/gatt/
108// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml
109const CHARACTERISTIC_USER_DESCRIPTION_UUID: &str = "00002901-0000-1000-8000-00805f9b34fb";
110// https://www.bluetooth.com/specifications/gatt/
111// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
112const CLIENT_CHARACTERISTIC_CONFIGURATION_UUID: &str = "00002902-0000-1000-8000-00805f9b34fb";
113// https://www.bluetooth.com/specifications/gatt/
114// viewer?attributeXmlFile=org.bluetooth.descriptor.number_of_digitals.xml
115const NUMBER_OF_DIGITALS_UUID: &str = "00002909-0000-1000-8000-00805f9b34fb";
116
117const HEART_RATE_DEVICE_NAME_DESCRIPTION: &str = "The name of this device.";
118
119fn generate_id() -> Uuid {
120    let mut id = Uuid::nil();
121    let mut generated = false;
122    while !generated {
123        id = Uuid::new_v4();
124        CACHED_IDS.with(|cache| {
125            if !cache.borrow().contains(&id) {
126                cache.borrow_mut().insert(id);
127                generated = true;
128            }
129        });
130    }
131    id
132}
133
134// Set the adapter's name, is_powered and is_discoverable attributes
135fn set_adapter(adapter: &BluetoothAdapter, adapter_name: String) -> Result<(), Box<dyn Error>> {
136    adapter.set_name(adapter_name)?;
137    adapter.set_powered(true)?;
138    adapter.set_discoverable(true)?;
139    Ok(())
140}
141
142// Create Device
143fn create_device(
144    adapter: &BluetoothAdapter,
145    name: String,
146    address: String,
147) -> Result<BluetoothDevice, Box<dyn Error>> {
148    let device = adapter.create_mock_device(generate_id().to_string())?;
149    device.set_name(Some(name))?;
150    device.set_address(address)?;
151    device.set_connectable(true)?;
152    Ok(device)
153}
154
155// Create Device with UUIDs
156fn create_device_with_uuids(
157    adapter: &BluetoothAdapter,
158    name: String,
159    address: String,
160    uuids: Vec<String>,
161) -> Result<BluetoothDevice, Box<dyn Error>> {
162    let device = create_device(adapter, name, address)?;
163    device.set_uuids(uuids)?;
164    Ok(device)
165}
166
167// Create Service
168fn create_service(
169    device: &BluetoothDevice,
170    uuid: String,
171) -> Result<BluetoothGATTService, Box<dyn Error>> {
172    let service =
173        BluetoothGATTService::create_mock_service(device.clone(), generate_id().to_string())?;
174    service.set_uuid(uuid)?;
175    Ok(service)
176}
177
178// Create Characteristic
179fn create_characteristic(
180    service: &BluetoothGATTService,
181    uuid: String,
182) -> Result<BluetoothGATTCharacteristic, Box<dyn Error>> {
183    let characteristic = BluetoothGATTCharacteristic::create_mock_characteristic(
184        service.clone(),
185        generate_id().to_string(),
186    )?;
187    characteristic.set_uuid(uuid)?;
188    Ok(characteristic)
189}
190
191// Create Characteristic with value
192fn create_characteristic_with_value(
193    service: &BluetoothGATTService,
194    uuid: String,
195    value: Vec<u8>,
196) -> Result<BluetoothGATTCharacteristic, Box<dyn Error>> {
197    let characteristic = create_characteristic(service, uuid)?;
198    characteristic.set_value(value)?;
199    Ok(characteristic)
200}
201
202// Create Descriptor
203fn create_descriptor(
204    characteristic: &BluetoothGATTCharacteristic,
205    uuid: String,
206) -> Result<BluetoothGATTDescriptor, Box<dyn Error>> {
207    let descriptor = BluetoothGATTDescriptor::create_mock_descriptor(
208        characteristic.clone(),
209        generate_id().to_string(),
210    )?;
211    descriptor.set_uuid(uuid)?;
212    Ok(descriptor)
213}
214
215// Create Descriptor with value
216fn create_descriptor_with_value(
217    characteristic: &BluetoothGATTCharacteristic,
218    uuid: String,
219    value: Vec<u8>,
220) -> Result<BluetoothGATTDescriptor, Box<dyn Error>> {
221    let descriptor = create_descriptor(characteristic, uuid)?;
222    descriptor.set_value(value)?;
223    Ok(descriptor)
224}
225
226fn create_heart_rate_service(
227    device: &BluetoothDevice,
228    empty: bool,
229) -> Result<BluetoothGATTService, Box<dyn Error>> {
230    // Heart Rate Service
231    let heart_rate_service = create_service(device, HEART_RATE_SERVICE_UUID.to_owned())?;
232
233    if empty {
234        return Ok(heart_rate_service);
235    }
236
237    // Heart Rate Measurement Characteristic
238    let heart_rate_measurement_characteristic = create_characteristic_with_value(
239        &heart_rate_service,
240        HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
241        vec![0],
242    )?;
243    heart_rate_measurement_characteristic.set_flags(vec![
244        NOTIFY_FLAG.to_string(),
245        READ_FLAG.to_string(),
246        WRITE_FLAG.to_string(),
247    ])?;
248
249    // Body Sensor Location Characteristic 1
250    let body_sensor_location_characteristic_1 = create_characteristic_with_value(
251        &heart_rate_service,
252        BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
253        vec![49],
254    )?;
255    body_sensor_location_characteristic_1
256        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
257
258    // Body Sensor Location Characteristic 2
259    let body_sensor_location_characteristic_2 = create_characteristic_with_value(
260        &heart_rate_service,
261        BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
262        vec![50],
263    )?;
264    body_sensor_location_characteristic_2
265        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
266    Ok(heart_rate_service)
267}
268
269fn create_generic_access_service(
270    device: &BluetoothDevice,
271    empty: bool,
272) -> Result<BluetoothGATTService, Box<dyn Error>> {
273    // Generic Access Service
274    let generic_access_service = create_service(device, GENERIC_ACCESS_SERVICE_UUID.to_owned())?;
275
276    if empty {
277        return Ok(generic_access_service);
278    }
279
280    // Device Name Characteristic
281    let device_name_characteristic = create_characteristic_with_value(
282        &generic_access_service,
283        DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
284        HEART_RATE_DEVICE_NAME.as_bytes().to_vec(),
285    )?;
286    device_name_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
287
288    // Number of Digitals descriptor
289    let number_of_digitals_descriptor_1 = create_descriptor_with_value(
290        &device_name_characteristic,
291        NUMBER_OF_DIGITALS_UUID.to_owned(),
292        vec![49],
293    )?;
294    number_of_digitals_descriptor_1
295        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
296
297    let number_of_digitals_descriptor_2 = create_descriptor_with_value(
298        &device_name_characteristic,
299        NUMBER_OF_DIGITALS_UUID.to_owned(),
300        vec![50],
301    )?;
302    number_of_digitals_descriptor_2
303        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
304
305    // Characteristic User Description Descriptor
306    let _characteristic_user_description = create_descriptor_with_value(
307        &device_name_characteristic,
308        CHARACTERISTIC_USER_DESCRIPTION_UUID.to_owned(),
309        HEART_RATE_DEVICE_NAME_DESCRIPTION.as_bytes().to_vec(),
310    )?;
311
312    // Client Characteristic Configuration descriptor
313    let _client_characteristic_configuration = create_descriptor_with_value(
314        &device_name_characteristic,
315        CLIENT_CHARACTERISTIC_CONFIGURATION_UUID.to_owned(),
316        vec![0],
317    )?;
318
319    // Peripheral Privacy Flag Characteristic
320    let peripheral_privacy_flag_characteristic = create_characteristic(
321        &generic_access_service,
322        PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned(),
323    )?;
324    peripheral_privacy_flag_characteristic
325        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
326    Ok(generic_access_service)
327}
328
329// Create Heart Rate Device
330fn create_heart_rate_device(
331    adapter: &BluetoothAdapter,
332    empty: bool,
333) -> Result<BluetoothDevice, Box<dyn Error>> {
334    // Heart Rate Device
335    let heart_rate_device = create_device_with_uuids(
336        adapter,
337        HEART_RATE_DEVICE_NAME.to_owned(),
338        HEART_RATE_DEVICE_ADDRESS.to_owned(),
339        vec![
340            GENERIC_ACCESS_SERVICE_UUID.to_owned(),
341            HEART_RATE_SERVICE_UUID.to_owned(),
342        ],
343    )?;
344
345    if empty {
346        return Ok(heart_rate_device);
347    }
348
349    // Generic Access Service
350    let _generic_access_service = create_generic_access_service(&heart_rate_device, false)?;
351
352    // Heart Rate Service
353    let _heart_rate_service = create_heart_rate_service(&heart_rate_device, false)?;
354
355    Ok(heart_rate_device)
356}
357
358fn create_missing_characterisitc_heart_rate_device(
359    adapter: &BluetoothAdapter,
360) -> Result<(), Box<dyn Error>> {
361    let heart_rate_device_empty = create_heart_rate_device(adapter, true)?;
362
363    let _generic_access_service_empty =
364        create_generic_access_service(&heart_rate_device_empty, true)?;
365
366    let _heart_rate_service_empty = create_heart_rate_service(&heart_rate_device_empty, true)?;
367
368    Ok(())
369}
370
371fn create_missing_descriptor_heart_rate_device(
372    adapter: &BluetoothAdapter,
373) -> Result<(), Box<dyn Error>> {
374    let heart_rate_device_empty = create_heart_rate_device(adapter, true)?;
375
376    let generic_access_service_empty =
377        create_generic_access_service(&heart_rate_device_empty, true)?;
378
379    let _device_name_characteristic = create_characteristic_with_value(
380        &generic_access_service_empty,
381        DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
382        HEART_RATE_DEVICE_NAME.as_bytes().to_vec(),
383    )?;
384
385    let peripheral_privacy_flag_characteristic = create_characteristic(
386        &generic_access_service_empty,
387        PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned(),
388    )?;
389    peripheral_privacy_flag_characteristic
390        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
391
392    let _heart_rate_service = create_heart_rate_service(&heart_rate_device_empty, false)?;
393
394    Ok(())
395}
396
397fn create_two_heart_rate_services_device(adapter: &BluetoothAdapter) -> Result<(), Box<dyn Error>> {
398    let heart_rate_device_empty = create_heart_rate_device(adapter, true)?;
399
400    heart_rate_device_empty.set_uuids(vec![
401        GENERIC_ACCESS_SERVICE_UUID.to_owned(),
402        HEART_RATE_SERVICE_UUID.to_owned(),
403        HEART_RATE_SERVICE_UUID.to_owned(),
404    ])?;
405
406    let _generic_access_service = create_generic_access_service(&heart_rate_device_empty, false)?;
407
408    let heart_rate_service_empty_1 = create_heart_rate_service(&heart_rate_device_empty, true)?;
409
410    let heart_rate_service_empty_2 = create_heart_rate_service(&heart_rate_device_empty, true)?;
411
412    let heart_rate_measurement_characteristic = create_characteristic_with_value(
413        &heart_rate_service_empty_1,
414        HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
415        vec![0],
416    )?;
417    heart_rate_measurement_characteristic.set_flags(vec![NOTIFY_FLAG.to_string()])?;
418
419    let _body_sensor_location_characteristic_1 = create_characteristic_with_value(
420        &heart_rate_service_empty_1,
421        BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
422        vec![49],
423    )?;
424
425    let _body_sensor_location_characteristic_2 = create_characteristic_with_value(
426        &heart_rate_service_empty_2,
427        BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
428        vec![50],
429    )?;
430    Ok(())
431}
432
433fn create_blocklisted_device(adapter: &BluetoothAdapter) -> Result<(), Box<dyn Error>> {
434    let connectable_device = create_device_with_uuids(
435        adapter,
436        CONNECTABLE_DEVICE_NAME.to_owned(),
437        CONNECTABLE_DEVICE_ADDRESS.to_owned(),
438        vec![
439            BLOCKLIST_TEST_SERVICE_UUID.to_owned(),
440            DEVICE_INFORMATION_UUID.to_owned(),
441            GENERIC_ACCESS_SERVICE_UUID.to_owned(),
442            HEART_RATE_SERVICE_UUID.to_owned(),
443            HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned(),
444        ],
445    )?;
446
447    let blocklist_test_service =
448        create_service(&connectable_device, BLOCKLIST_TEST_SERVICE_UUID.to_owned())?;
449
450    let blocklist_exclude_reads_characteristic = create_characteristic(
451        &blocklist_test_service,
452        BLOCKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID.to_owned(),
453    )?;
454    blocklist_exclude_reads_characteristic
455        .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])?;
456
457    let _blocklist_exclude_reads_descriptor = create_descriptor_with_value(
458        &blocklist_exclude_reads_characteristic,
459        BLOCKLIST_EXCLUDE_READS_DESCRIPTOR_UUID.to_owned(),
460        vec![54; 3],
461    )?;
462
463    let _blocklist_descriptor = create_descriptor_with_value(
464        &blocklist_exclude_reads_characteristic,
465        BLOCKLIST_DESCRIPTOR_UUID.to_owned(),
466        vec![54; 3],
467    )?;
468
469    let device_information_service =
470        create_service(&connectable_device, DEVICE_INFORMATION_UUID.to_owned())?;
471
472    let _serial_number_string_characteristic = create_characteristic(
473        &device_information_service,
474        SERIAL_NUMBER_STRING_UUID.to_owned(),
475    )?;
476
477    let _generic_access_service = create_generic_access_service(&connectable_device, false)?;
478
479    let _heart_rate_service = create_heart_rate_service(&connectable_device, false)?;
480
481    let _human_interface_device_service = create_service(
482        &connectable_device,
483        HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned(),
484    )?;
485    Ok(())
486}
487
488fn create_glucose_heart_rate_devices(adapter: &BluetoothAdapter) -> Result<(), Box<dyn Error>> {
489    let glucose_devie = create_device_with_uuids(
490        adapter,
491        GLUCOSE_DEVICE_NAME.to_owned(),
492        GLUCOSE_DEVICE_ADDRESS.to_owned(),
493        vec![
494            GLUCOSE_SERVICE_UUID.to_owned(),
495            TX_POWER_SERVICE_UUID.to_owned(),
496        ],
497    )?;
498
499    let heart_rate_device_empty = create_heart_rate_device(adapter, true)?;
500
501    let mut manufacturer_dta = HashMap::new();
502    manufacturer_dta.insert(17, vec![1, 2, 3]);
503    glucose_devie.set_manufacturer_data(manufacturer_dta)?;
504
505    let mut service_data = HashMap::new();
506    service_data.insert(GLUCOSE_SERVICE_UUID.to_owned(), vec![1, 2, 3]);
507    glucose_devie.set_service_data(service_data)?;
508
509    service_data = HashMap::new();
510    service_data.insert(HEART_RATE_SERVICE_UUID.to_owned(), vec![1, 2, 3]);
511    heart_rate_device_empty.set_service_data(service_data)?;
512    Ok(())
513}
514
515pub fn test(manager: &mut BluetoothManager, data_set_name: String) -> Result<(), Box<dyn Error>> {
516    let may_existing_adapter = manager.get_or_create_adapter();
517    let adapter = match may_existing_adapter.as_ref() {
518        Some(adapter) => adapter,
519        None => return Err(Box::from(ADAPTER_ERROR.to_string())),
520    };
521    match data_set_name.as_str() {
522        NOT_PRESENT_ADAPTER => {
523            set_adapter(adapter, NOT_PRESENT_ADAPTER.to_owned())?;
524            adapter.set_present(false)?;
525        },
526        NOT_POWERED_ADAPTER => {
527            set_adapter(adapter, NOT_POWERED_ADAPTER.to_owned())?;
528            adapter.set_powered(false)?;
529        },
530        EMPTY_ADAPTER => {
531            set_adapter(adapter, EMPTY_ADAPTER.to_owned())?;
532        },
533        GLUCOSE_HEART_RATE_ADAPTER => {
534            set_adapter(adapter, GLUCOSE_HEART_RATE_ADAPTER.to_owned())?;
535            create_glucose_heart_rate_devices(adapter)?;
536        },
537        UNICODE_DEVICE_ADAPTER => {
538            set_adapter(adapter, UNICODE_DEVICE_ADAPTER.to_owned())?;
539
540            let _unicode_device = create_device(
541                adapter,
542                UNICODE_DEVICE_NAME.to_owned(),
543                UNICODE_DEVICE_ADDRESS.to_owned(),
544            )?;
545        },
546        MISSING_SERVICE_HEART_RATE_ADAPTER => {
547            set_adapter(adapter, MISSING_SERVICE_HEART_RATE_ADAPTER.to_owned())?;
548
549            let _heart_rate_device_empty = create_heart_rate_device(adapter, true)?;
550        },
551        MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER => {
552            set_adapter(
553                adapter,
554                MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER.to_owned(),
555            )?;
556
557            create_missing_characterisitc_heart_rate_device(adapter)?;
558        },
559        MISSING_DESCRIPTOR_HEART_RATE_ADAPTER => {
560            set_adapter(adapter, MISSING_DESCRIPTOR_HEART_RATE_ADAPTER.to_owned())?;
561
562            create_missing_descriptor_heart_rate_device(adapter)?;
563        },
564        HEART_RATE_ADAPTER => {
565            set_adapter(adapter, HEART_RATE_ADAPTER.to_owned())?;
566
567            let _heart_rate_device = create_heart_rate_device(adapter, false)?;
568        },
569        EMPTY_NAME_HEART_RATE_ADAPTER => {
570            set_adapter(adapter, EMPTY_NAME_HEART_RATE_ADAPTER.to_owned())?;
571
572            let heart_rate_device = create_heart_rate_device(adapter, false)?;
573            heart_rate_device.set_name(Some(EMPTY_DEVICE_NAME.to_owned()))?;
574        },
575        NO_NAME_HEART_RATE_ADAPTER => {
576            set_adapter(adapter, NO_NAME_HEART_RATE_ADAPTER.to_owned())?;
577
578            let heart_rate_device = create_heart_rate_device(adapter, false)?;
579            heart_rate_device.set_name(None)?;
580        },
581        TWO_HEART_RATE_SERVICES_ADAPTER => {
582            set_adapter(adapter, TWO_HEART_RATE_SERVICES_ADAPTER.to_owned())?;
583
584            create_two_heart_rate_services_device(adapter)?;
585        },
586        BLOCKLIST_TEST_ADAPTER => {
587            set_adapter(adapter, BLOCKLIST_TEST_ADAPTER.to_owned())?;
588
589            create_blocklisted_device(adapter)?;
590        },
591        _ => return Err(Box::from(WRONG_DATA_SET_ERROR.to_string())),
592    }
593    Ok(())
594}