1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#![allow(clippy::let_unit_value)]
use crate::pairing::PairingAgent;
use crate::{sys, DeviceId, Result, Service, Uuid};
/// A Bluetooth LE device
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Device(pub(crate) sys::device::DeviceImpl);
impl std::fmt::Display for Device {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
impl Device {
/// This device's unique identifier
#[inline]
pub fn id(&self) -> DeviceId {
self.0.id()
}
/// The local name for this device, if available
///
/// This can either be a name advertised or read from the device, or a name assigned to the device by the OS.
///
/// # Panics
///
/// On Linux, this method will panic if there is a current Tokio runtime and it is single-threaded or if there is
/// no current Tokio runtime and creating one fails.
#[inline]
pub fn name(&self) -> Result<String> {
self.0.name()
}
/// The local name for this device, if available
///
/// This can either be a name advertised or read from the device, or a name assigned to the device by the OS.
#[inline]
pub async fn name_async(&self) -> Result<String> {
self.0.name_async().await
}
/// The connection status for this device
#[inline]
pub async fn is_connected(&self) -> bool {
self.0.is_connected().await
}
/// The pairing status for this device
#[inline]
pub async fn is_paired(&self) -> Result<bool> {
self.0.is_paired().await
}
/// Attempt to pair this device using the system default pairing UI
///
/// # Platform specific
///
/// ## MacOS/iOS
///
/// Device pairing is performed automatically by the OS when a characteristic requiring security is accessed. This
/// method is a no-op.
///
/// ## Windows
///
/// This will fail unless it is called from a UWP application.
#[inline]
pub async fn pair(&self) -> Result<()> {
self.0.pair().await
}
/// Attempt to pair this device using the system default pairing UI
///
/// # Platform specific
///
/// On MacOS/iOS, device pairing is performed automatically by the OS when a characteristic requiring security is
/// accessed. This method is a no-op.
#[inline]
pub async fn pair_with_agent<T: PairingAgent + 'static>(&self, agent: &T) -> Result<()> {
self.0.pair_with_agent(agent).await
}
/// Disconnect and unpair this device from the system
///
/// # Platform specific
///
/// Not supported on MacOS/iOS.
#[inline]
pub async fn unpair(&self) -> Result<()> {
self.0.unpair().await
}
/// Discover the primary services of this device.
#[inline]
pub async fn discover_services(&self) -> Result<Vec<Service>> {
self.0.discover_services().await
}
/// Discover the primary service(s) of this device with the given [`Uuid`].
#[inline]
pub async fn discover_services_with_uuid(&self, uuid: Uuid) -> Result<Vec<Service>> {
self.0.discover_services_with_uuid(uuid).await
}
/// Get previously discovered services.
///
/// If no services have been discovered yet, this method may either perform service discovery or return an error.
#[inline]
pub async fn services(&self) -> Result<Vec<Service>> {
self.0.services().await
}
/// Asynchronously blocks until a GATT services changed packet is received
#[inline]
pub async fn services_changed(&self) -> Result<()> {
self.0.services_changed().await
}
/// Get the current signal strength from the device in dBm.
///
/// # Platform specific
///
/// Returns [ErrorKind::NotSupported] on Windows and Linux.
#[inline]
pub async fn rssi(&self) -> Result<i16> {
self.0.rssi().await
}
}