pub struct Device { /* private fields */ }
bluetoothd
only.Expand description
Interface to a Bluetooth device.
Implementations
sourceimpl Device
impl Device
sourcepub fn adapter_name(&self) -> &str
pub fn adapter_name(&self) -> &str
The Bluetooth adapter name.
sourcepub fn address(&self) -> Address
pub fn address(&self) -> Address
The Bluetooth device address of the remote device.
Examples found in repository?
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
async fn exercise_characteristic(char: &Characteristic) -> Result<()> {
let mut write_io = char.write_io().await?;
println!(" Obtained write IO with MTU {} bytes", write_io.mtu());
let mut notify_io = char.notify_io().await?;
println!(" Obtained notification IO with MTU {} bytes", notify_io.mtu());
// Flush notify buffer.
let mut buf = [0; 1024];
while let Ok(Ok(_)) = timeout(Duration::from_secs(1), notify_io.read(&mut buf)).await {}
let mut rng = rand::thread_rng();
for i in 0..1024 {
let mut len = rng.gen_range(0..20000);
// Try to trigger packet reordering over EATT.
if i % 10 == 0 {
// Big packet is split into multiple small packets.
// (by L2CAP layer, because GATT MTU is bigger than L2CAP MTU)
len = write_io.mtu(); // 512
}
if i % 10 == 1 {
// Small packet can use different L2CAP channel when EATT is enabled.
len = 20;
}
// Thus small packet can arrive before big packet.
// The solution is to disable EATT in /etc/bluetooth/main.conf.
println!(" Test iteration {} with data size {}", i, len);
let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
// We must read back the data while sending, otherwise the connection
// buffer will overrun and we will lose data.
let read_task = tokio::spawn(async move {
let mut echo_buf = vec![0u8; len];
let res = match notify_io.read_exact(&mut echo_buf).await {
Ok(_) => Ok(echo_buf),
Err(err) => Err(err),
};
(notify_io, res)
});
// Note that write_all will automatically split the buffer into
// multiple writes of MTU size.
write_io.write_all(&data).await.expect("write failed");
println!(" Waiting for echo");
let (notify_io_back, res) = read_task.await.unwrap();
notify_io = notify_io_back;
let echo_buf = res.expect("read failed");
if echo_buf != data {
println!();
println!("Echo data mismatch!");
println!("Send data: {:x?}", &data);
println!("Received data: {:x?}", &echo_buf);
println!();
println!("By 512 blocks:");
for (sent, recv) in data.chunks(512).zip(echo_buf.chunks(512)) {
println!();
println!(
"Send: {:x?} ... {:x?}",
&sent[0..4.min(sent.len())],
&sent[sent.len().saturating_sub(4)..]
);
println!(
"Recv: {:x?} ... {:x?}",
&recv[0..4.min(recv.len())],
&recv[recv.len().saturating_sub(4)..]
);
}
println!();
panic!("echoed data does not match sent data");
}
println!(" Data matches");
}
println!(" Test okay");
Ok(())
}
#[tokio::main]
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
{
println!(
"Discovering on Bluetooth adapter {} with address {}\n",
adapter.name(),
adapter.address().await?
);
let discover = adapter.discover_devices().await?;
pin_mut!(discover);
let mut done = false;
while let Some(evt) = discover.next().await {
match evt {
AdapterEvent::DeviceAdded(addr) => {
let device = adapter.device(addr)?;
match find_our_characteristic(&device).await {
Ok(Some(char)) => match exercise_characteristic(&char).await {
Ok(()) => {
println!(" Characteristic exercise completed");
done = true;
}
Err(err) => {
println!(" Characteristic exercise failed: {}", &err);
}
},
Ok(None) => (),
Err(err) => {
println!(" Device failed: {}", &err);
let _ = adapter.remove_device(device.address()).await;
}
}
match device.disconnect().await {
Ok(()) => println!(" Device disconnected"),
Err(err) => println!(" Device disconnection failed: {}", &err),
}
println!();
}
AdapterEvent::DeviceRemoved(addr) => {
println!("Device removed {}", addr);
}
_ => (),
}
if done {
break;
}
}
println!("Stopping discovery");
}
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
async fn exercise_characteristic(char: &Characteristic) -> Result<()> {
println!(" Characteristic flags: {:?}", char.flags().await?);
sleep(Duration::from_secs(1)).await;
if char.flags().await?.read {
println!(" Reading characteristic value");
let value = char.read().await?;
println!(" Read value: {:x?}", &value);
sleep(Duration::from_secs(1)).await;
}
let data = vec![0xee, 0x11, 0x11, 0x0];
println!(" Writing characteristic value {:x?} using function call", &data);
char.write(&data).await?;
sleep(Duration::from_secs(1)).await;
if char.flags().await?.read {
let value = char.read().await?;
println!(" Read value back: {:x?}", &value);
sleep(Duration::from_secs(1)).await;
}
println!(" Obtaining write IO");
let mut write_io = char.write_io().await?;
println!(" Write IO obtained");
println!(" Writing characteristic value {:x?} five times using IO", &data);
for _ in 0..5u8 {
let written = write_io.write(&data).await?;
println!(" {} bytes written", written);
}
println!(" Closing write IO");
drop(write_io);
sleep(Duration::from_secs(1)).await;
println!(" Starting notification session");
{
let notify = char.notify().await?;
pin_mut!(notify);
for _ in 0..5u8 {
match notify.next().await {
Some(value) => {
println!(" Notification value: {:x?}", &value);
}
None => {
println!(" Notification session was terminated");
}
}
}
println!(" Stopping notification session");
}
sleep(Duration::from_secs(1)).await;
println!(" Obtaining notification IO");
let mut notify_io = char.notify_io().await?;
println!(" Obtained notification IO with MTU={}", notify_io.mtu());
for _ in 0..5u8 {
let mut buf = vec![0; notify_io.mtu()];
match notify_io.read(&mut buf).await {
Ok(0) => {
println!(" Notification IO end of stream");
break;
}
Ok(read) => {
println!(" Notified with {} bytes: {:x?}", read, &buf[0..read]);
}
Err(err) => {
println!(" Notification IO failed: {}", &err);
break;
}
}
}
println!(" Stopping notification IO");
drop(notify_io);
sleep(Duration::from_secs(1)).await;
Ok(())
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
{
println!(
"Discovering on Bluetooth adapter {} with address {}\n",
adapter.name(),
adapter.address().await?
);
let discover = adapter.discover_devices().await?;
pin_mut!(discover);
let mut done = false;
while let Some(evt) = discover.next().await {
match evt {
AdapterEvent::DeviceAdded(addr) => {
let device = adapter.device(addr)?;
match find_our_characteristic(&device).await {
Ok(Some(char)) => match exercise_characteristic(&char).await {
Ok(()) => {
println!(" Characteristic exercise completed");
done = true;
}
Err(err) => {
println!(" Characteristic exercise failed: {}", &err);
}
},
Ok(None) => (),
Err(err) => {
println!(" Device failed: {}", &err);
let _ = adapter.remove_device(device.address()).await;
}
}
match device.disconnect().await {
Ok(()) => println!(" Device disconnected"),
Err(err) => println!(" Device disconnection failed: {}", &err),
}
println!();
}
AdapterEvent::DeviceRemoved(addr) => {
println!("Device removed {}", addr);
}
_ => (),
}
if done {
break;
}
}
println!("Stopping discovery");
}
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn events(&self) -> Result<impl Stream<Item = DeviceEvent>>
pub async fn events(&self) -> Result<impl Stream<Item = DeviceEvent>>
Streams device property changes.
The stream ends when the device is removed.
Examples found in repository?
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
async fn main() -> bluer::Result<()> {
let with_changes = env::args().any(|arg| arg == "--changes");
let all_properties = env::args().any(|arg| arg == "--all-properties");
let filter_addr: HashSet<_> = env::args().filter_map(|arg| arg.parse::<Address>().ok()).collect();
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
println!("Discovering devices using Bluetooth adapater {}\n", adapter.name());
adapter.set_powered(true).await?;
let device_events = adapter.discover_devices().await?;
pin_mut!(device_events);
let mut all_change_events = SelectAll::new();
loop {
tokio::select! {
Some(device_event) = device_events.next() => {
match device_event {
AdapterEvent::DeviceAdded(addr) => {
if !filter_addr.is_empty() && !filter_addr.contains(&addr) {
continue;
}
println!("Device added: {}", addr);
let res = if all_properties {
query_all_device_properties(&adapter, addr).await
} else {
query_device(&adapter, addr).await
};
if let Err(err) = res {
println!(" Error: {}", &err);
}
if with_changes {
let device = adapter.device(addr)?;
let change_events = device.events().await?.map(move |evt| (addr, evt));
all_change_events.push(change_events);
}
}
AdapterEvent::DeviceRemoved(addr) => {
println!("Device removed: {}", addr);
}
_ => (),
}
println!();
}
Some((addr, DeviceEvent::PropertyChanged(property))) = all_change_events.next() => {
println!("Device changed: {}", addr);
println!(" {:?}", property);
}
else => break
}
}
Ok(())
}
sourcepub async fn services(&self) -> Result<Vec<Service>>
pub async fn services(&self) -> Result<Vec<Service>>
Remote GATT services.
The device must be connected for GATT services to be resolved.
Examples found in repository?
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
More examples
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
sourcepub async fn service(&self, service_id: u16) -> Result<Service>
pub async fn service(&self, service_id: u16) -> Result<Service>
Remote GATT service with specified id.
sourcepub async fn connect(&self) -> Result<()>
pub async fn connect(&self) -> Result<()>
This is a generic method to connect any profiles the remote device supports that can be connected to and have been flagged as auto-connectable on our side.
If only subset of profiles is already connected it will try to connect currently disconnected ones.
If at least one profile was connected successfully this method will indicate success.
For dual-mode devices only one bearer is connected at time, the conditions are in the following order:
-
Connect the disconnected bearer if already connected.
-
Connect first the bonded bearer. If no bearers are bonded or both are skip and check latest seen bearer.
-
Connect last seen bearer, in case the timestamps are the same BR/EDR takes precedence.
Examples found in repository?
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
More examples
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
sourcepub async fn disconnect(&self) -> Result<()>
pub async fn disconnect(&self) -> Result<()>
This method gracefully disconnects all connected profiles and then terminates low-level ACL connection.
ACL connection will be terminated even if some profiles were not disconnected properly e.g. due to misbehaving device.
This method can be also used to cancel a preceding Connect call before a reply to it has been received.
For non-trusted devices connected over LE bearer calling this method will disable incoming connections until Connect method is called again.
Examples found in repository?
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
{
println!(
"Discovering on Bluetooth adapter {} with address {}\n",
adapter.name(),
adapter.address().await?
);
let discover = adapter.discover_devices().await?;
pin_mut!(discover);
let mut done = false;
while let Some(evt) = discover.next().await {
match evt {
AdapterEvent::DeviceAdded(addr) => {
let device = adapter.device(addr)?;
match find_our_characteristic(&device).await {
Ok(Some(char)) => match exercise_characteristic(&char).await {
Ok(()) => {
println!(" Characteristic exercise completed");
done = true;
}
Err(err) => {
println!(" Characteristic exercise failed: {}", &err);
}
},
Ok(None) => (),
Err(err) => {
println!(" Device failed: {}", &err);
let _ = adapter.remove_device(device.address()).await;
}
}
match device.disconnect().await {
Ok(()) => println!(" Device disconnected"),
Err(err) => println!(" Device disconnection failed: {}", &err),
}
println!();
}
AdapterEvent::DeviceRemoved(addr) => {
println!("Device removed {}", addr);
}
_ => (),
}
if done {
break;
}
}
println!("Stopping discovery");
}
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
{
println!(
"Discovering on Bluetooth adapter {} with address {}\n",
adapter.name(),
adapter.address().await?
);
let discover = adapter.discover_devices().await?;
pin_mut!(discover);
let mut done = false;
while let Some(evt) = discover.next().await {
match evt {
AdapterEvent::DeviceAdded(addr) => {
let device = adapter.device(addr)?;
match find_our_characteristic(&device).await {
Ok(Some(char)) => match exercise_characteristic(&char).await {
Ok(()) => {
println!(" Characteristic exercise completed");
done = true;
}
Err(err) => {
println!(" Characteristic exercise failed: {}", &err);
}
},
Ok(None) => (),
Err(err) => {
println!(" Device failed: {}", &err);
let _ = adapter.remove_device(device.address()).await;
}
}
match device.disconnect().await {
Ok(()) => println!(" Device disconnected"),
Err(err) => println!(" Device disconnection failed: {}", &err),
}
println!();
}
AdapterEvent::DeviceRemoved(addr) => {
println!("Device removed {}", addr);
}
_ => (),
}
if done {
break;
}
}
println!("Stopping discovery");
}
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn connect_profile(&self, uuid: &Uuid) -> Result<()>
pub async fn connect_profile(&self, uuid: &Uuid) -> Result<()>
This method connects a specific profile of this device. The UUID provided is the remote service UUID for the profile.
sourcepub async fn disconnect_profile(&self, uuid: &Uuid) -> Result<()>
pub async fn disconnect_profile(&self, uuid: &Uuid) -> Result<()>
This method disconnects a specific profile of this device.
The profile needs to be registered client profile.
There is no connection tracking for a profile, so as long as the profile is registered this will always succeed.
sourcepub async fn pair(&self) -> Result<()>
pub async fn pair(&self) -> Result<()>
This method will connect to the remote device, initiate pairing and then retrieve all SDP records (or GATT primary services).
If the application has registered its own agent, then that specific agent will be used. Otherwise it will use the default agent.
Only for applications like a pairing wizard it would make sense to have its own agent. In almost all other cases the default agent will handle this just fine.
In case there is no application agent and also no default agent present, this method will fail.
Drop the returned future to cancel pairing.
sourceimpl Device
impl Device
sourcepub async fn name(&self) -> Result<Option<String>>
pub async fn name(&self) -> Result<Option<String>>
The Bluetooth remote name.
This value can not be changed. Use the Alias property instead.
This value is only present for completeness. It is better to always use the Alias property when displaying the devices name.
If the Alias property is unset, it will reflect this value which makes it more convenient.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn address_type(&self) -> Result<AddressType>
pub async fn address_type(&self) -> Result<AddressType>
The Bluetooth device address type.
For dual-mode and BR/EDR only devices this defaults to “public”. Single mode LE devices may have either value. If remote device uses privacy than before pairing this represents address type used for connection and Identity Address after pairing.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn icon(&self) -> Result<Option<String>>
pub async fn icon(&self) -> Result<Option<String>>
Proposed icon name according to the freedesktop.org icon naming specification.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn class(&self) -> Result<Option<u32>>
pub async fn class(&self) -> Result<Option<u32>>
The Bluetooth class of device of the remote device.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn appearance(&self) -> Result<Option<u16>>
pub async fn appearance(&self) -> Result<Option<u16>>
External appearance of device, as found on GAP service.
sourcepub async fn uuids(&self) -> Result<Option<HashSet<Uuid>>>
pub async fn uuids(&self) -> Result<Option<HashSet<Uuid>>>
List of 128-bit UUIDs that represents the available remote services.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
More examples
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
sourcepub async fn is_paired(&self) -> Result<bool>
pub async fn is_paired(&self) -> Result<bool>
Indicates if the remote device is paired.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn is_connected(&self) -> Result<bool>
pub async fn is_connected(&self) -> Result<bool>
Indicates if the remote device is paired.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
More examples
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
sourcepub async fn is_trusted(&self) -> Result<bool>
pub async fn is_trusted(&self) -> Result<bool>
Indicates if the remote is seen as trusted. This setting can be changed by the application.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn set_trusted(&self, v: bool) -> Result<()>
pub async fn set_trusted(&self, v: bool) -> Result<()>
Indicates if the remote is seen as trusted. This setting can be changed by the application.
sourcepub async fn is_blocked(&self) -> Result<bool>
pub async fn is_blocked(&self) -> Result<bool>
If set to true any incoming connections from the device will be immediately rejected.
Any device drivers will also be removed and no new ones will be probed as long as the device is blocked.
sourcepub async fn set_blocked(&self, v: bool) -> Result<()>
pub async fn set_blocked(&self, v: bool) -> Result<()>
If set to true any incoming connections from the device will be immediately rejected.
Any device drivers will also be removed and no new ones will be probed as long as the device is blocked.
sourcepub async fn is_wake_allowed(&self) -> Result<Option<bool>>
pub async fn is_wake_allowed(&self) -> Result<Option<bool>>
If set to true this device will be allowed to wake the host from system suspend.
sourcepub async fn set_wake_allowed(&self, v: bool) -> Result<()>
pub async fn set_wake_allowed(&self, v: bool) -> Result<()>
If set to true this device will be allowed to wake the host from system suspend.
sourcepub async fn alias(&self) -> Result<String>
pub async fn alias(&self) -> Result<String>
The name alias for the remote device.
The alias can be used to have a different friendly name for the remote device.
In case no alias is set, it will return the remote device name. Setting an empty string as alias will convert it back to the remote device name.
When resetting the alias with an empty string, the property will default back to the remote name.
sourcepub async fn set_alias(&self, v: String) -> Result<()>
pub async fn set_alias(&self, v: String) -> Result<()>
The name alias for the remote device.
The alias can be used to have a different friendly name for the remote device.
In case no alias is set, it will return the remote device name. Setting an empty string as alias will convert it back to the remote device name.
When resetting the alias with an empty string, the property will default back to the remote name.
sourcepub async fn is_legacy_pairing(&self) -> Result<bool>
pub async fn is_legacy_pairing(&self) -> Result<bool>
Set to true if the device only supports the pre-2.1 pairing mechanism.
This property is useful during device discovery to anticipate whether legacy or simple pairing will occur if pairing is initiated.
Note that this property can exhibit false-positives in the case of Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry Response support.
sourcepub async fn modalias(&self) -> Result<Option<Modalias>>
pub async fn modalias(&self) -> Result<Option<Modalias>>
Remote Device ID information in modalias format used by the kernel and udev.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn rssi(&self) -> Result<Option<i16>>
pub async fn rssi(&self) -> Result<Option<i16>>
Received Signal Strength Indicator of the remote device (inquiry or advertising).
None
if the device is known, but not currently present.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn tx_power(&self) -> Result<Option<i16>>
pub async fn tx_power(&self) -> Result<Option<i16>>
Advertised transmitted power level (inquiry or advertising).
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn manufacturer_data(&self) -> Result<Option<HashMap<u16, Vec<u8>>>>
pub async fn manufacturer_data(&self) -> Result<Option<HashMap<u16, Vec<u8>>>>
Manufacturer specific advertisement data.
Keys are 16 bits Manufacturer ID followed by its byte array value.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
More examples
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
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
async fn find_our_characteristic(device: &Device) -> Result<Option<Characteristic>> {
let addr = device.address();
let uuids = device.uuids().await?.unwrap_or_default();
println!("Discovered device {} with service UUIDs {:?}", addr, &uuids);
let md = device.manufacturer_data().await?;
println!(" Manufacturer data: {:x?}", &md);
if uuids.contains(&SERVICE_UUID) {
println!(" Device provides our service!");
sleep(Duration::from_secs(2)).await;
if !device.is_connected().await? {
println!(" Connecting...");
let mut retries = 2;
loop {
match device.connect().await {
Ok(()) => break,
Err(err) if retries > 0 => {
println!(" Connect error: {}", &err);
retries -= 1;
}
Err(err) => return Err(err),
}
}
println!(" Connected");
} else {
println!(" Already connected");
}
println!(" Enumerating services...");
for service in device.services().await? {
let uuid = service.uuid().await?;
println!(" Service UUID: {}", &uuid);
println!(" Service data: {:?}", service.all_properties().await?);
if uuid == SERVICE_UUID {
println!(" Found our service!");
for char in service.characteristics().await? {
let uuid = char.uuid().await?;
println!(" Characteristic UUID: {}", &uuid);
println!(" Characteristic data: {:?}", char.all_properties().await?);
if uuid == CHARACTERISTIC_UUID {
println!(" Found our characteristic!");
return Ok(Some(char));
}
}
}
}
println!(" Not found!");
}
Ok(None)
}
sourcepub async fn service_data(&self) -> Result<Option<HashMap<Uuid, Vec<u8>>>>
pub async fn service_data(&self) -> Result<Option<HashMap<Uuid, Vec<u8>>>>
Service advertisement data.
Keys are the UUIDs followed by its byte array value.
Examples found in repository?
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
async fn query_device(adapter: &Adapter, addr: Address) -> bluer::Result<()> {
let device = adapter.device(addr)?;
println!(" Address type: {}", device.address_type().await?);
println!(" Name: {:?}", device.name().await?);
println!(" Icon: {:?}", device.icon().await?);
println!(" Class: {:?}", device.class().await?);
println!(" UUIDs: {:?}", device.uuids().await?.unwrap_or_default());
println!(" Paried: {:?}", device.is_paired().await?);
println!(" Connected: {:?}", device.is_connected().await?);
println!(" Trusted: {:?}", device.is_trusted().await?);
println!(" Modalias: {:?}", device.modalias().await?);
println!(" RSSI: {:?}", device.rssi().await?);
println!(" TX power: {:?}", device.tx_power().await?);
println!(" Manufacturer data: {:?}", device.manufacturer_data().await?);
println!(" Service data: {:?}", device.service_data().await?);
Ok(())
}
sourcepub async fn is_services_resolved(&self) -> Result<bool>
pub async fn is_services_resolved(&self) -> Result<bool>
Indicate whether or not service discovery has been resolved.
sourcepub async fn advertising_flags(&self) -> Result<Option<Vec<u8>>>
pub async fn advertising_flags(&self) -> Result<Option<Vec<u8>>>
The Advertising Data Flags of the remote device.
sourcepub async fn advertising_data(&self) -> Result<Option<HashMap<u8, Vec<u8>>>>
pub async fn advertising_data(&self) -> Result<Option<HashMap<u8, Vec<u8>>>>
The Advertising Data of the remote device.
Note: Only types considered safe to be handled by application are exposed.
sourcepub async fn all_properties(&self) -> Result<Vec<DeviceProperty>>
pub async fn all_properties(&self) -> Result<Vec<DeviceProperty>>
Queries and returns all properties.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for Device
impl Send for Device
impl Sync for Device
impl Unpin for Device
impl !UnwindSafe for Device
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more