1use std::collections::HashMap;
6use std::error::Error;
7use std::sync::Arc;
8
9#[cfg(all(target_os = "android", feature = "native-bluetooth"))]
10use blurdroid::bluetooth_device::Device as BluetoothDeviceAndroid;
11#[cfg(all(target_os = "android", feature = "native-bluetooth"))]
12use blurdroid::bluetooth_discovery_session::DiscoverySession as BluetoothDiscoverySessionAndroid;
13#[cfg(all(target_os = "android", feature = "native-bluetooth"))]
14use blurdroid::bluetooth_gatt_characteristic::Characteristic as BluetoothGATTCharacteristicAndroid;
15#[cfg(all(target_os = "android", feature = "native-bluetooth"))]
16use blurdroid::bluetooth_gatt_descriptor::Descriptor as BluetoothGATTDescriptorAndroid;
17#[cfg(all(target_os = "android", feature = "native-bluetooth"))]
18use blurdroid::bluetooth_gatt_service::Service as BluetoothGATTServiceAndroid;
19#[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
20use blurmac::BluetoothDevice as BluetoothDeviceMac;
21#[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
22use blurmac::BluetoothDiscoverySession as BluetoothDiscoverySessionMac;
23#[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
24use blurmac::BluetoothGATTCharacteristic as BluetoothGATTCharacteristicMac;
25#[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
26use blurmac::BluetoothGATTDescriptor as BluetoothGATTDescriptorMac;
27#[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
28use blurmac::BluetoothGATTService as BluetoothGATTServiceMac;
29#[cfg(feature = "bluetooth-test")]
30use blurmock::fake_characteristic::FakeBluetoothGATTCharacteristic;
31#[cfg(feature = "bluetooth-test")]
32use blurmock::fake_descriptor::FakeBluetoothGATTDescriptor;
33#[cfg(feature = "bluetooth-test")]
34use blurmock::fake_device::FakeBluetoothDevice;
35#[cfg(feature = "bluetooth-test")]
36use blurmock::fake_discovery_session::FakeBluetoothDiscoverySession;
37#[cfg(feature = "bluetooth-test")]
38use blurmock::fake_service::FakeBluetoothGATTService;
39#[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
40use blurz::bluetooth_device::BluetoothDevice as BluetoothDeviceBluez;
41#[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
42use blurz::bluetooth_discovery_session::BluetoothDiscoverySession as BluetoothDiscoverySessionBluez;
43#[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
44use blurz::bluetooth_gatt_characteristic::BluetoothGATTCharacteristic as BluetoothGATTCharacteristicBluez;
45#[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
46use blurz::bluetooth_gatt_descriptor::BluetoothGATTDescriptor as BluetoothGATTDescriptorBluez;
47#[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
48use blurz::bluetooth_gatt_service::BluetoothGATTService as BluetoothGATTServiceBluez;
49
50pub use super::adapter::BluetoothAdapter;
51#[cfg(not(any(
52 all(target_os = "linux", feature = "native-bluetooth"),
53 all(target_os = "android", feature = "native-bluetooth"),
54 all(target_os = "macos", feature = "native-bluetooth")
55)))]
56use super::empty::BluetoothDevice as BluetoothDeviceEmpty;
57#[cfg(not(any(
58 all(target_os = "linux", feature = "native-bluetooth"),
59 all(target_os = "android", feature = "native-bluetooth"),
60 all(target_os = "macos", feature = "native-bluetooth")
61)))]
62use super::empty::BluetoothDiscoverySession as BluetoothDiscoverySessionEmpty;
63#[cfg(not(any(
64 all(target_os = "linux", feature = "native-bluetooth"),
65 all(target_os = "android", feature = "native-bluetooth"),
66 all(target_os = "macos", feature = "native-bluetooth")
67)))]
68use super::empty::BluetoothGATTCharacteristic as BluetoothGATTCharacteristicEmpty;
69#[cfg(not(any(
70 all(target_os = "linux", feature = "native-bluetooth"),
71 all(target_os = "android", feature = "native-bluetooth"),
72 all(target_os = "macos", feature = "native-bluetooth")
73)))]
74use super::empty::BluetoothGATTDescriptor as BluetoothGATTDescriptorEmpty;
75#[cfg(not(any(
76 all(target_os = "linux", feature = "native-bluetooth"),
77 all(target_os = "android", feature = "native-bluetooth"),
78 all(target_os = "macos", feature = "native-bluetooth")
79)))]
80use super::empty::BluetoothGATTService as BluetoothGATTServiceEmpty;
81use super::macros::get_inner_and_call;
82#[cfg(feature = "bluetooth-test")]
83use super::macros::get_inner_and_call_test_func;
84
85#[cfg(feature = "bluetooth-test")]
86const NOT_SUPPORTED_ON_MOCK_ERROR: &str = "Error! The first parameter must be a mock structure!";
87
88#[derive(Debug)]
89pub enum BluetoothDiscoverySession {
90 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
91 Bluez(Arc<BluetoothDiscoverySessionBluez>),
92 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
93 Android(Arc<BluetoothDiscoverySessionAndroid>),
94 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
95 Mac(Arc<BluetoothDiscoverySessionMac>),
96 #[cfg(not(any(
97 all(target_os = "linux", feature = "native-bluetooth"),
98 all(target_os = "android", feature = "native-bluetooth"),
99 all(target_os = "macos", feature = "native-bluetooth")
100 )))]
101 Empty(Arc<BluetoothDiscoverySessionEmpty>),
102 #[cfg(feature = "bluetooth-test")]
103 Mock(Arc<FakeBluetoothDiscoverySession>),
104}
105
106#[derive(Clone, Debug)]
107pub enum BluetoothDevice {
108 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
109 Bluez(Arc<BluetoothDeviceBluez>),
110 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
111 Android(Arc<BluetoothDeviceAndroid>),
112 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
113 Mac(Arc<BluetoothDeviceMac>),
114 #[cfg(not(any(
115 all(target_os = "linux", feature = "native-bluetooth"),
116 all(target_os = "android", feature = "native-bluetooth"),
117 all(target_os = "macos", feature = "native-bluetooth")
118 )))]
119 Empty(Arc<BluetoothDeviceEmpty>),
120 #[cfg(feature = "bluetooth-test")]
121 Mock(Arc<FakeBluetoothDevice>),
122}
123
124#[derive(Clone, Debug)]
125pub enum BluetoothGATTService {
126 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
127 Bluez(Arc<BluetoothGATTServiceBluez>),
128 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
129 Android(Arc<BluetoothGATTServiceAndroid>),
130 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
131 Mac(Arc<BluetoothGATTServiceMac>),
132 #[cfg(not(any(
133 all(target_os = "linux", feature = "native-bluetooth"),
134 all(target_os = "android", feature = "native-bluetooth"),
135 all(target_os = "macos", feature = "native-bluetooth")
136 )))]
137 Empty(Arc<BluetoothGATTServiceEmpty>),
138 #[cfg(feature = "bluetooth-test")]
139 Mock(Arc<FakeBluetoothGATTService>),
140}
141
142#[derive(Clone, Debug)]
143pub enum BluetoothGATTCharacteristic {
144 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
145 Bluez(Arc<BluetoothGATTCharacteristicBluez>),
146 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
147 Android(Arc<BluetoothGATTCharacteristicAndroid>),
148 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
149 Mac(Arc<BluetoothGATTCharacteristicMac>),
150 #[cfg(not(any(
151 all(target_os = "linux", feature = "native-bluetooth"),
152 all(target_os = "android", feature = "native-bluetooth"),
153 all(target_os = "macos", feature = "native-bluetooth")
154 )))]
155 Empty(Arc<BluetoothGATTCharacteristicEmpty>),
156 #[cfg(feature = "bluetooth-test")]
157 Mock(Arc<FakeBluetoothGATTCharacteristic>),
158}
159
160#[derive(Clone, Debug)]
161pub enum BluetoothGATTDescriptor {
162 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
163 Bluez(Arc<BluetoothGATTDescriptorBluez>),
164 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
165 Android(Arc<BluetoothGATTDescriptorAndroid>),
166 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
167 Mac(Arc<BluetoothGATTDescriptorMac>),
168 #[cfg(not(any(
169 all(target_os = "linux", feature = "native-bluetooth"),
170 all(target_os = "android", feature = "native-bluetooth"),
171 all(target_os = "macos", feature = "native-bluetooth")
172 )))]
173 Empty(Arc<BluetoothGATTDescriptorEmpty>),
174 #[cfg(feature = "bluetooth-test")]
175 Mock(Arc<FakeBluetoothGATTDescriptor>),
176}
177
178impl BluetoothDiscoverySession {
179 pub fn start_discovery(&self) -> Result<(), Box<dyn Error>> {
180 get_inner_and_call!(self, BluetoothDiscoverySession, start_discovery)
181 }
182
183 pub fn stop_discovery(&self) -> Result<(), Box<dyn Error>> {
184 get_inner_and_call!(self, BluetoothDiscoverySession, stop_discovery)
185 }
186}
187
188impl BluetoothDevice {
189 pub fn get_id(&self) -> String {
190 get_inner_and_call!(self, BluetoothDevice, get_id)
191 }
192
193 #[cfg(feature = "bluetooth-test")]
194 pub fn set_id(&self, id: String) {
195 if let BluetoothDevice::Mock(fake_adapter) = self {
196 fake_adapter.set_id(id)
197 }
198 }
199
200 pub fn get_address(&self) -> Result<String, Box<dyn Error>> {
201 get_inner_and_call!(self, BluetoothDevice, get_address)
202 }
203
204 #[cfg(feature = "bluetooth-test")]
205 pub fn set_address(&self, address: String) -> Result<(), Box<dyn Error>> {
206 get_inner_and_call_test_func!(self, BluetoothDevice, set_address, address)
207 }
208
209 pub fn get_name(&self) -> Result<String, Box<dyn Error>> {
210 get_inner_and_call!(self, BluetoothDevice, get_name)
211 }
212
213 #[cfg(feature = "bluetooth-test")]
214 pub fn set_name(&self, name: Option<String>) -> Result<(), Box<dyn Error>> {
215 get_inner_and_call_test_func!(self, BluetoothDevice, set_name, name)
216 }
217
218 pub fn get_icon(&self) -> Result<String, Box<dyn Error>> {
219 get_inner_and_call!(self, BluetoothDevice, get_icon)
220 }
221
222 #[cfg(feature = "bluetooth-test")]
223 pub fn set_icon(&self, icon: String) -> Result<(), Box<dyn Error>> {
224 get_inner_and_call_test_func!(self, BluetoothDevice, set_icon, icon)
225 }
226
227 pub fn get_class(&self) -> Result<u32, Box<dyn Error>> {
228 get_inner_and_call!(self, BluetoothDevice, get_class)
229 }
230
231 #[cfg(feature = "bluetooth-test")]
232 pub fn set_class(&self, class: u32) -> Result<(), Box<dyn Error>> {
233 get_inner_and_call_test_func!(self, BluetoothDevice, set_class, class)
234 }
235
236 pub fn get_appearance(&self) -> Result<u16, Box<dyn Error>> {
237 get_inner_and_call!(self, BluetoothDevice, get_appearance)
238 }
239
240 #[cfg(feature = "bluetooth-test")]
241 pub fn set_appearance(&self, appearance: u16) -> Result<(), Box<dyn Error>> {
242 get_inner_and_call_test_func!(self, BluetoothDevice, set_appearance, Some(appearance))
243 }
244
245 pub fn get_uuids(&self) -> Result<Vec<String>, Box<dyn Error>> {
246 get_inner_and_call!(self, BluetoothDevice, get_uuids)
247 }
248
249 #[cfg(feature = "bluetooth-test")]
250 pub fn set_uuids(&self, uuids: Vec<String>) -> Result<(), Box<dyn Error>> {
251 get_inner_and_call_test_func!(self, BluetoothDevice, set_uuids, uuids)
252 }
253
254 pub fn is_paired(&self) -> Result<bool, Box<dyn Error>> {
255 get_inner_and_call!(self, BluetoothDevice, is_paired)
256 }
257
258 #[cfg(feature = "bluetooth-test")]
259 pub fn set_paired(&self, paired: bool) -> Result<(), Box<dyn Error>> {
260 get_inner_and_call_test_func!(self, BluetoothDevice, set_paired, paired)
261 }
262
263 pub fn is_connected(&self) -> Result<bool, Box<dyn Error>> {
264 get_inner_and_call!(self, BluetoothDevice, is_connected)
265 }
266
267 #[cfg(feature = "bluetooth-test")]
268 pub fn set_connected(&self, connected: bool) -> Result<(), Box<dyn Error>> {
269 get_inner_and_call_test_func!(self, BluetoothDevice, set_connected, connected)
270 }
271
272 #[cfg(feature = "bluetooth-test")]
273 pub fn is_connectable(&self) -> Result<bool, Box<dyn Error>> {
274 get_inner_and_call_test_func!(self, BluetoothDevice, is_connectable)
275 }
276
277 #[cfg(feature = "bluetooth-test")]
278 pub fn set_connectable(&self, connectable: bool) -> Result<(), Box<dyn Error>> {
279 get_inner_and_call_test_func!(self, BluetoothDevice, set_connectable, connectable)
280 }
281
282 pub fn is_trusted(&self) -> Result<bool, Box<dyn Error>> {
283 get_inner_and_call!(self, BluetoothDevice, is_trusted)
284 }
285
286 #[cfg(feature = "bluetooth-test")]
287 pub fn set_trusted(&self, trusted: bool) -> Result<(), Box<dyn Error>> {
288 get_inner_and_call_test_func!(self, BluetoothDevice, set_trusted, trusted)
289 }
290
291 pub fn is_blocked(&self) -> Result<bool, Box<dyn Error>> {
292 get_inner_and_call!(self, BluetoothDevice, is_blocked)
293 }
294
295 #[cfg(feature = "bluetooth-test")]
296 pub fn set_blocked(&self, blocked: bool) -> Result<(), Box<dyn Error>> {
297 get_inner_and_call_test_func!(self, BluetoothDevice, set_blocked, blocked)
298 }
299
300 pub fn get_alias(&self) -> Result<String, Box<dyn Error>> {
301 get_inner_and_call!(self, BluetoothDevice, get_alias)
302 }
303
304 #[cfg(feature = "bluetooth-test")]
305 pub fn set_alias(&self, alias: String) -> Result<(), Box<dyn Error>> {
306 get_inner_and_call_test_func!(self, BluetoothDevice, set_alias, alias)
307 }
308
309 pub fn is_legacy_pairing(&self) -> Result<bool, Box<dyn Error>> {
310 get_inner_and_call!(self, BluetoothDevice, is_legacy_pairing)
311 }
312
313 #[cfg(feature = "bluetooth-test")]
314 pub fn set_legacy_pairing(&self, legacy_pairing: bool) -> Result<(), Box<dyn Error>> {
315 get_inner_and_call_test_func!(self, BluetoothDevice, set_legacy_pairing, legacy_pairing)
316 }
317
318 pub fn get_vendor_id_source(&self) -> Result<String, Box<dyn Error>> {
319 get_inner_and_call!(self, BluetoothDevice, get_vendor_id_source)
320 }
321
322 pub fn get_vendor_id(&self) -> Result<u32, Box<dyn Error>> {
323 get_inner_and_call!(self, BluetoothDevice, get_vendor_id)
324 }
325
326 pub fn get_product_id(&self) -> Result<u32, Box<dyn Error>> {
327 get_inner_and_call!(self, BluetoothDevice, get_product_id)
328 }
329
330 pub fn get_device_id(&self) -> Result<u32, Box<dyn Error>> {
331 get_inner_and_call!(self, BluetoothDevice, get_device_id)
332 }
333
334 pub fn get_modalias(&self) -> Result<(String, u32, u32, u32), Box<dyn Error>> {
335 get_inner_and_call!(self, BluetoothDevice, get_modalias)
336 }
337
338 #[cfg(feature = "bluetooth-test")]
339 pub fn set_modalias(&self, modalias: String) -> Result<(), Box<dyn Error>> {
340 get_inner_and_call_test_func!(self, BluetoothDevice, set_modalias, modalias)
341 }
342
343 pub fn get_rssi(&self) -> Result<i16, Box<dyn Error>> {
344 get_inner_and_call!(self, BluetoothDevice, get_rssi)
345 }
346
347 #[cfg(feature = "bluetooth-test")]
348 pub fn set_rssi(&self, rssi: i16) -> Result<(), Box<dyn Error>> {
349 get_inner_and_call_test_func!(self, BluetoothDevice, set_rssi, Some(rssi))
350 }
351
352 pub fn get_tx_power(&self) -> Result<i16, Box<dyn Error>> {
353 get_inner_and_call!(self, BluetoothDevice, get_tx_power)
354 }
355
356 #[cfg(feature = "bluetooth-test")]
357 pub fn set_tx_power(&self, tx_power: i16) -> Result<(), Box<dyn Error>> {
358 get_inner_and_call_test_func!(self, BluetoothDevice, set_tx_power, Some(tx_power))
359 }
360
361 pub fn get_manufacturer_data(&self) -> Result<HashMap<u16, Vec<u8>>, Box<dyn Error>> {
362 get_inner_and_call!(self, BluetoothDevice, get_manufacturer_data)
363 }
364
365 #[cfg(feature = "bluetooth-test")]
366 pub fn set_manufacturer_data(
367 &self,
368 manufacturer_data: HashMap<u16, Vec<u8>>,
369 ) -> Result<(), Box<dyn Error>> {
370 get_inner_and_call_test_func!(
371 self,
372 BluetoothDevice,
373 set_manufacturer_data,
374 Some(manufacturer_data)
375 )
376 }
377
378 pub fn get_service_data(&self) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>> {
379 get_inner_and_call!(self, BluetoothDevice, get_service_data)
380 }
381
382 #[cfg(feature = "bluetooth-test")]
383 pub fn set_service_data(
384 &self,
385 service_data: HashMap<String, Vec<u8>>,
386 ) -> Result<(), Box<dyn Error>> {
387 get_inner_and_call_test_func!(self, BluetoothDevice, set_service_data, Some(service_data))
388 }
389
390 pub fn get_gatt_services(&self) -> Result<Vec<BluetoothGATTService>, Box<dyn Error>> {
391 let services = get_inner_and_call!(self, BluetoothDevice, get_gatt_services)?;
392 Ok(services
393 .into_iter()
394 .map(|service| BluetoothGATTService::create_service(self.clone(), service))
395 .collect())
396 }
397
398 pub fn connect(&self) -> Result<(), Box<dyn Error>> {
399 get_inner_and_call!(self, BluetoothDevice, connect)
400 }
401
402 pub fn disconnect(&self) -> Result<(), Box<dyn Error>> {
403 get_inner_and_call!(self, BluetoothDevice, disconnect)
404 }
405
406 pub fn connect_profile(&self, uuid: String) -> Result<(), Box<dyn Error>> {
407 get_inner_and_call!(self, BluetoothDevice, connect_profile, uuid)
408 }
409
410 pub fn disconnect_profile(&self, uuid: String) -> Result<(), Box<dyn Error>> {
411 get_inner_and_call!(self, BluetoothDevice, disconnect_profile, uuid)
412 }
413
414 pub fn pair(&self) -> Result<(), Box<dyn Error>> {
415 get_inner_and_call!(self, BluetoothDevice, pair)
416 }
417
418 pub fn cancel_pairing(&self) -> Result<(), Box<dyn Error>> {
419 get_inner_and_call!(self, BluetoothDevice, cancel_pairing)
420 }
421}
422
423impl BluetoothGATTService {
424 fn create_service(device: BluetoothDevice, service: String) -> BluetoothGATTService {
425 match device {
426 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
427 BluetoothDevice::Bluez(_bluez_device) => {
428 BluetoothGATTService::Bluez(Arc::new(BluetoothGATTServiceBluez::new(service)))
429 },
430 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
431 BluetoothDevice::Android(android_device) => BluetoothGATTService::Android(Arc::new(
432 BluetoothGATTServiceAndroid::new(android_device, service),
433 )),
434 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
435 BluetoothDevice::Mac(mac_device) => BluetoothGATTService::Mac(Arc::new(
436 BluetoothGATTServiceMac::new(mac_device, service),
437 )),
438 #[cfg(not(any(
439 all(target_os = "linux", feature = "native-bluetooth"),
440 all(target_os = "android", feature = "native-bluetooth"),
441 all(target_os = "macos", feature = "native-bluetooth")
442 )))]
443 BluetoothDevice::Empty(_device) => {
444 BluetoothGATTService::Empty(Arc::new(BluetoothGATTServiceEmpty::new(service)))
445 },
446 #[cfg(feature = "bluetooth-test")]
447 BluetoothDevice::Mock(fake_device) => BluetoothGATTService::Mock(
448 FakeBluetoothGATTService::new_empty(fake_device, service),
449 ),
450 }
451 }
452
453 #[cfg(feature = "bluetooth-test")]
454 pub fn create_mock_service(
455 device: BluetoothDevice,
456 service: String,
457 ) -> Result<BluetoothGATTService, Box<dyn Error>> {
458 match device {
459 BluetoothDevice::Mock(fake_device) => Ok(BluetoothGATTService::Mock(
460 FakeBluetoothGATTService::new_empty(fake_device, service),
461 )),
462 _ => Err(Box::from(
463 "Error! The first parameter must be a mock structure!",
464 )),
465 }
466 }
467
468 pub fn get_id(&self) -> String {
469 get_inner_and_call!(self, BluetoothGATTService, get_id)
470 }
471
472 #[cfg(feature = "bluetooth-test")]
473 pub fn set_id(&self, id: String) {
474 if let BluetoothGATTService::Mock(fake_service) = self {
475 fake_service.set_id(id)
476 }
477 }
478
479 pub fn get_uuid(&self) -> Result<String, Box<dyn Error>> {
480 get_inner_and_call!(self, BluetoothGATTService, get_uuid)
481 }
482
483 #[cfg(feature = "bluetooth-test")]
484 pub fn set_uuid(&self, uuid: String) -> Result<(), Box<dyn Error>> {
485 get_inner_and_call_test_func!(self, BluetoothGATTService, set_uuid, uuid)
486 }
487
488 pub fn is_primary(&self) -> Result<bool, Box<dyn Error>> {
489 get_inner_and_call!(self, BluetoothGATTService, is_primary)
490 }
491
492 #[cfg(feature = "bluetooth-test")]
493 pub fn set_primary(&self, primary: bool) -> Result<(), Box<dyn Error>> {
494 get_inner_and_call_test_func!(self, BluetoothGATTService, set_is_primary, primary)
495 }
496
497 pub fn get_includes(
498 &self,
499 device: BluetoothDevice,
500 ) -> Result<Vec<BluetoothGATTService>, Box<dyn Error>> {
501 let services = get_inner_and_call!(self, BluetoothGATTService, get_includes)?;
502 Ok(services
503 .into_iter()
504 .map(|service| BluetoothGATTService::create_service(device.clone(), service))
505 .collect())
506 }
507
508 pub fn get_gatt_characteristics(
509 &self,
510 ) -> Result<Vec<BluetoothGATTCharacteristic>, Box<dyn Error>> {
511 let characteristics =
512 get_inner_and_call!(self, BluetoothGATTService, get_gatt_characteristics)?;
513 Ok(characteristics
514 .into_iter()
515 .map(|characteristic| {
516 BluetoothGATTCharacteristic::create_characteristic(self.clone(), characteristic)
517 })
518 .collect())
519 }
520}
521
522impl BluetoothGATTCharacteristic {
523 fn create_characteristic(
524 service: BluetoothGATTService,
525 characteristic: String,
526 ) -> BluetoothGATTCharacteristic {
527 match service {
528 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
529 BluetoothGATTService::Bluez(_bluez_service) => BluetoothGATTCharacteristic::Bluez(
530 Arc::new(BluetoothGATTCharacteristicBluez::new(characteristic)),
531 ),
532 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
533 BluetoothGATTService::Android(android_service) => {
534 BluetoothGATTCharacteristic::Android(Arc::new(
535 BluetoothGATTCharacteristicAndroid::new(android_service, characteristic),
536 ))
537 },
538 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
539 BluetoothGATTService::Mac(mac_service) => BluetoothGATTCharacteristic::Mac(Arc::new(
540 BluetoothGATTCharacteristicMac::new(mac_service, characteristic),
541 )),
542 #[cfg(not(any(
543 all(target_os = "linux", feature = "native-bluetooth"),
544 all(target_os = "android", feature = "native-bluetooth"),
545 all(target_os = "macos", feature = "native-bluetooth")
546 )))]
547 BluetoothGATTService::Empty(_service) => BluetoothGATTCharacteristic::Empty(Arc::new(
548 BluetoothGATTCharacteristicEmpty::new(characteristic),
549 )),
550 #[cfg(feature = "bluetooth-test")]
551 BluetoothGATTService::Mock(fake_service) => BluetoothGATTCharacteristic::Mock(
552 FakeBluetoothGATTCharacteristic::new_empty(fake_service, characteristic),
553 ),
554 }
555 }
556
557 #[cfg(feature = "bluetooth-test")]
558 pub fn create_mock_characteristic(
559 service: BluetoothGATTService,
560 characteristic: String,
561 ) -> Result<BluetoothGATTCharacteristic, Box<dyn Error>> {
562 match service {
563 BluetoothGATTService::Mock(fake_service) => Ok(BluetoothGATTCharacteristic::Mock(
564 FakeBluetoothGATTCharacteristic::new_empty(fake_service, characteristic),
565 )),
566 _ => Err(Box::from(
567 "Error! The first parameter must be a mock structure!",
568 )),
569 }
570 }
571
572 pub fn get_id(&self) -> String {
573 get_inner_and_call!(self, BluetoothGATTCharacteristic, get_id)
574 }
575
576 #[cfg(feature = "bluetooth-test")]
577 pub fn set_id(&self, id: String) {
578 if let BluetoothGATTCharacteristic::Mock(fake_characteristic) = self {
579 fake_characteristic.set_id(id)
580 }
581 }
582
583 pub fn get_uuid(&self) -> Result<String, Box<dyn Error>> {
584 get_inner_and_call!(self, BluetoothGATTCharacteristic, get_uuid)
585 }
586
587 #[cfg(feature = "bluetooth-test")]
588 pub fn set_uuid(&self, uuid: String) -> Result<(), Box<dyn Error>> {
589 get_inner_and_call_test_func!(self, BluetoothGATTCharacteristic, set_uuid, uuid)
590 }
591
592 pub fn get_value(&self) -> Result<Vec<u8>, Box<dyn Error>> {
593 get_inner_and_call!(self, BluetoothGATTCharacteristic, get_value)
594 }
595
596 #[cfg(feature = "bluetooth-test")]
597 pub fn set_value(&self, value: Vec<u8>) -> Result<(), Box<dyn Error>> {
598 get_inner_and_call_test_func!(self, BluetoothGATTCharacteristic, set_value, Some(value))
599 }
600
601 pub fn is_notifying(&self) -> Result<bool, Box<dyn Error>> {
602 get_inner_and_call!(self, BluetoothGATTCharacteristic, is_notifying)
603 }
604
605 #[cfg(feature = "bluetooth-test")]
606 pub fn set_notifying(&self, notifying: bool) -> Result<(), Box<dyn Error>> {
607 get_inner_and_call_test_func!(self, BluetoothGATTCharacteristic, set_notifying, notifying)
608 }
609
610 pub fn get_flags(&self) -> Result<Vec<String>, Box<dyn Error>> {
611 get_inner_and_call!(self, BluetoothGATTCharacteristic, get_flags)
612 }
613
614 #[cfg(feature = "bluetooth-test")]
615 pub fn set_flags(&self, flags: Vec<String>) -> Result<(), Box<dyn Error>> {
616 get_inner_and_call_test_func!(self, BluetoothGATTCharacteristic, set_flags, flags)
617 }
618
619 pub fn get_gatt_descriptors(&self) -> Result<Vec<BluetoothGATTDescriptor>, Box<dyn Error>> {
620 let descriptors =
621 get_inner_and_call!(self, BluetoothGATTCharacteristic, get_gatt_descriptors)?;
622 Ok(descriptors
623 .into_iter()
624 .map(|descriptor| BluetoothGATTDescriptor::create_descriptor(self.clone(), descriptor))
625 .collect())
626 }
627
628 pub fn read_value(&self) -> Result<Vec<u8>, Box<dyn Error>> {
629 get_inner_and_call!(@with_bluez_offset, self, BluetoothGATTCharacteristic, read_value)
630 }
631
632 pub fn write_value(&self, values: Vec<u8>) -> Result<(), Box<dyn Error>> {
633 get_inner_and_call!(@with_bluez_offset, self, BluetoothGATTCharacteristic, write_value, values)
634 }
635
636 pub fn start_notify(&self) -> Result<(), Box<dyn Error>> {
637 get_inner_and_call!(self, BluetoothGATTCharacteristic, start_notify)
638 }
639
640 pub fn stop_notify(&self) -> Result<(), Box<dyn Error>> {
641 get_inner_and_call!(self, BluetoothGATTCharacteristic, stop_notify)
642 }
643}
644
645impl BluetoothGATTDescriptor {
646 fn create_descriptor(
647 characteristic: BluetoothGATTCharacteristic,
648 descriptor: String,
649 ) -> BluetoothGATTDescriptor {
650 match characteristic {
651 #[cfg(all(target_os = "linux", feature = "native-bluetooth"))]
652 BluetoothGATTCharacteristic::Bluez(_bluez_characteristic) => {
653 BluetoothGATTDescriptor::Bluez(Arc::new(BluetoothGATTDescriptorBluez::new(
654 descriptor,
655 )))
656 },
657 #[cfg(all(target_os = "android", feature = "native-bluetooth"))]
658 BluetoothGATTCharacteristic::Android(android_characteristic) => {
659 BluetoothGATTDescriptor::Android(Arc::new(BluetoothGATTDescriptorAndroid::new(
660 android_characteristic,
661 descriptor,
662 )))
663 },
664 #[cfg(all(target_os = "macos", feature = "native-bluetooth"))]
665 BluetoothGATTCharacteristic::Mac(_mac_characteristic) => {
666 BluetoothGATTDescriptor::Mac(Arc::new(BluetoothGATTDescriptorMac::new(descriptor)))
667 },
668 #[cfg(not(any(
669 all(target_os = "linux", feature = "native-bluetooth"),
670 all(target_os = "android", feature = "native-bluetooth"),
671 all(target_os = "macos", feature = "native-bluetooth")
672 )))]
673 BluetoothGATTCharacteristic::Empty(_characteristic) => BluetoothGATTDescriptor::Empty(
674 Arc::new(BluetoothGATTDescriptorEmpty::new(descriptor)),
675 ),
676 #[cfg(feature = "bluetooth-test")]
677 BluetoothGATTCharacteristic::Mock(fake_characteristic) => {
678 BluetoothGATTDescriptor::Mock(FakeBluetoothGATTDescriptor::new_empty(
679 fake_characteristic,
680 descriptor,
681 ))
682 },
683 }
684 }
685
686 #[cfg(feature = "bluetooth-test")]
687 pub fn create_mock_descriptor(
688 characteristic: BluetoothGATTCharacteristic,
689 descriptor: String,
690 ) -> Result<BluetoothGATTDescriptor, Box<dyn Error>> {
691 match characteristic {
692 BluetoothGATTCharacteristic::Mock(fake_characteristic) => {
693 Ok(BluetoothGATTDescriptor::Mock(
694 FakeBluetoothGATTDescriptor::new_empty(fake_characteristic, descriptor),
695 ))
696 },
697 _ => Err(Box::from(NOT_SUPPORTED_ON_MOCK_ERROR)),
698 }
699 }
700
701 pub fn get_id(&self) -> String {
702 get_inner_and_call!(self, BluetoothGATTDescriptor, get_id)
703 }
704
705 #[cfg(feature = "bluetooth-test")]
706 pub fn set_id(&self, id: String) {
707 if let BluetoothGATTDescriptor::Mock(fake_descriptor) = self {
708 fake_descriptor.set_id(id)
709 }
710 }
711
712 pub fn get_uuid(&self) -> Result<String, Box<dyn Error>> {
713 get_inner_and_call!(self, BluetoothGATTDescriptor, get_uuid)
714 }
715
716 #[cfg(feature = "bluetooth-test")]
717 pub fn set_uuid(&self, uuid: String) -> Result<(), Box<dyn Error>> {
718 get_inner_and_call_test_func!(self, BluetoothGATTDescriptor, set_uuid, uuid)
719 }
720
721 pub fn get_value(&self) -> Result<Vec<u8>, Box<dyn Error>> {
722 get_inner_and_call!(self, BluetoothGATTDescriptor, get_value)
723 }
724
725 #[cfg(feature = "bluetooth-test")]
726 pub fn set_value(&self, value: Vec<u8>) -> Result<(), Box<dyn Error>> {
727 get_inner_and_call_test_func!(self, BluetoothGATTDescriptor, set_value, Some(value))
728 }
729
730 pub fn get_flags(&self) -> Result<Vec<String>, Box<dyn Error>> {
731 get_inner_and_call!(self, BluetoothGATTDescriptor, get_flags)
732 }
733
734 #[cfg(feature = "bluetooth-test")]
735 pub fn set_flags(&self, flags: Vec<String>) -> Result<(), Box<dyn Error>> {
736 get_inner_and_call_test_func!(self, BluetoothGATTDescriptor, set_flags, flags)
737 }
738
739 pub fn read_value(&self) -> Result<Vec<u8>, Box<dyn Error>> {
740 get_inner_and_call!(@with_bluez_offset, self, BluetoothGATTDescriptor, read_value)
741 }
742
743 pub fn write_value(&self, values: Vec<u8>) -> Result<(), Box<dyn Error>> {
744 get_inner_and_call!(@with_bluez_offset, self, BluetoothGATTDescriptor, write_value, values)
745 }
746}