pub struct Adapter { /* private fields */ }
bluetoothd
only.Expand description
Interface to a Bluetooth adapter.
Implementations
sourceimpl Adapter
impl Adapter
sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
The Bluetooth adapter name.
For example hci0
.
Examples found in repository
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
advertisement_type: bluer::adv::Type::Peripheral,
service_uuids: vec!["123e4567-e89b-12d3-a456-426614174000".parse().unwrap()].into_iter().collect(),
discoverable: Some(true),
local_name: Some("le_advertise".to_string()),
..Default::default()
};
println!("{:?}", &le_advertisement);
let handle = adapter.advertise(le_advertisement).await?;
println!("Press enter to quit");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing advertisement");
drop(handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
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
fn main() -> bluer::Result<()> {
let with_changes = env::args().any(|arg| arg == "--changes");
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);
if let Err(err) = query_device(&adapter, addr).await {
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(())
}
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
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(())
}
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
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(())
}
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let adapter_addr = adapter.address().await?;
let adapter_addr_type = adapter.address_type().await?;
// Advertising is necessary for device to be connectable.
println!(
"Advertising on Bluetooth adapter {} with {} address {}",
adapter.name(),
&adapter_addr_type,
&adapter_addr
);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("l2cap_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
let listener = StreamListener::bind(local_sa).await?;
println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
let recv_mtu = stream.as_ref().recv_mtu()?;
println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
let mut n = 0;
loop {
n += 1;
// Vary buffer size between MTU and smaller value to test
// partial reads.
let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
continue;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
println!("Removing advertisement");
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("gatt_echo_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT echo service on Bluetooth adapter {}", adapter.name());
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Echo service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write request event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
},
read_res = async {
match &mut reader_opt {
Some(reader) if writer_opt.is_some() => reader.read(&mut read_buf).await,
_ => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Read stream ended");
reader_opt = None;
}
Ok(n) => {
let value = read_buf[..n].to_vec();
println!("Echoing {} bytes: {:x?} ... {:x?}", value.len(), &value[0..4.min(value.len())], &value[value.len().saturating_sub(4) ..]);
if value.len() < 512 {
println!();
}
if let Err(err) = writer_opt.as_mut().unwrap().write_all(&value).await {
println!("Write failed: {}", &err);
writer_opt = None;
}
}
Err(err) => {
println!("Read stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn device_addresses(&self) -> Result<Vec<Address>>
pub async fn device_addresses(&self) -> Result<Vec<Address>>
Bluetooth addresses of discovered Bluetooth devices.
sourcepub fn device(&self, address: Address) -> Result<Device>
pub fn device(&self, address: Address) -> Result<Device>
Get interface to Bluetooth device of specified address.
Examples found in repository
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
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(())
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> bluer::Result<()> {
let with_changes = env::args().any(|arg| arg == "--changes");
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);
if let Err(err) = query_device(&adapter, addr).await {
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(())
}
More examples
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
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(())
}
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
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 discover_devices(&self) -> Result<impl Stream<Item = AdapterEvent>>
pub async fn discover_devices(&self) -> Result<impl Stream<Item = AdapterEvent>>
This method starts the device discovery session.
This includes an inquiry procedure and remote device name resolving.
This process will start streaming device addresses as new devices are discovered. A device may be discovered multiple times.
All already known devices are also included in the device stream. This may include devices that are currently not in range. Check the Device::rssi property to see if the device is currently present.
Device properties are queried asynchronously and may not be available yet when a DeviceAdded event occurs. Use discover_devices_with_changes when you want to be notified when the device properties change.
Examples found in repository
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
fn main() -> bluer::Result<()> {
let with_changes = env::args().any(|arg| arg == "--changes");
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);
if let Err(err) = query_device(&adapter, addr).await {
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(())
}
More examples
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
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(())
}
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
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 discover_devices_with_changes(
&self
) -> Result<impl Stream<Item = AdapterEvent>>
pub async fn discover_devices_with_changes(
&self
) -> Result<impl Stream<Item = AdapterEvent>>
This method starts the device discovery session and notifies of device property changes.
This includes an inquiry procedure and remote device name resolving.
This process will start streaming device addresses as new devices are discovered. Each time device properties change you will receive an additional DeviceAdded event for that device.
All already known devices are also included in the device stream. This may include devices that are currently not in range. Check the Device::rssi property to see if the device is currently present.
sourcepub async fn events(&self) -> Result<impl Stream<Item = AdapterEvent>>
pub async fn events(&self) -> Result<impl Stream<Item = AdapterEvent>>
Streams adapter property and device changes.
The stream ends when the adapter is removed.
sourcepub async fn advertise(
&self,
le_advertisement: Advertisement
) -> Result<AdvertisementHandle>
pub async fn advertise(
&self,
le_advertisement: Advertisement
) -> Result<AdvertisementHandle>
Registers an advertisement object to be sent over the LE Advertising channel.
InvalidArguments error indicates that the object has invalid or conflicting properties.
InvalidLength error indicates that the data provided generates a data packet which is too long.
The properties of this object are parsed when it is registered, and any changes are ignored.
If the same object is registered twice it will result in an AlreadyExists error.
If the maximum number of advertisement instances is reached it will result in NotPermitted error.
Drop the returned AdvertisementHandle to unregister the advertisement.
Examples found in repository
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
advertisement_type: bluer::adv::Type::Peripheral,
service_uuids: vec!["123e4567-e89b-12d3-a456-426614174000".parse().unwrap()].into_iter().collect(),
discoverable: Some(true),
local_name: Some("le_advertise".to_string()),
..Default::default()
};
println!("{:?}", &le_advertisement);
let handle = adapter.advertise(le_advertisement).await?;
println!("Press enter to quit");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing advertisement");
drop(handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let adapter_addr = adapter.address().await?;
let adapter_addr_type = adapter.address_type().await?;
// Advertising is necessary for device to be connectable.
println!(
"Advertising on Bluetooth adapter {} with {} address {}",
adapter.name(),
&adapter_addr_type,
&adapter_addr
);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("l2cap_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
let listener = StreamListener::bind(local_sa).await?;
println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
let recv_mtu = stream.as_ref().recv_mtu()?;
println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
let mut n = 0;
loop {
n += 1;
// Vary buffer size between MTU and smaller value to test
// partial reads.
let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
continue;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
println!("Removing advertisement");
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("gatt_echo_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT echo service on Bluetooth adapter {}", adapter.name());
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Echo service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write request event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
},
read_res = async {
match &mut reader_opt {
Some(reader) if writer_opt.is_some() => reader.read(&mut read_buf).await,
_ => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Read stream ended");
reader_opt = None;
}
Ok(n) => {
let value = read_buf[..n].to_vec();
println!("Echoing {} bytes: {:x?} ... {:x?}", value.len(), &value[0..4.min(value.len())], &value[value.len().saturating_sub(4) ..]);
if value.len() < 512 {
println!();
}
if let Err(err) = writer_opt.as_mut().unwrap().write_all(&value).await {
println!("Write failed: {}", &err);
writer_opt = None;
}
}
Err(err) => {
println!("Read stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let mut manufacturer_data = BTreeMap::new();
manufacturer_data.insert(MANUFACTURER_ID, vec![0x21, 0x22, 0x23, 0x24]);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
manufacturer_data,
discoverable: Some(true),
local_name: Some("gatt_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT service on Bluetooth adapter {}", adapter.name());
let value = Arc::new(Mutex::new(vec![0x10, 0x01, 0x01, 0x10]));
let value_read = value.clone();
let value_write = value.clone();
let value_notify = value.clone();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
read: Some(CharacteristicRead {
read: true,
fun: Box::new(move |req| {
let value = value_read.clone();
async move {
let value = value.lock().await.clone();
println!("Read request {:?} with value {:x?}", &req, &value);
Ok(value)
}
.boxed()
}),
..Default::default()
}),
write: Some(CharacteristicWrite {
write: true,
write_without_response: true,
method: CharacteristicWriteMethod::Fun(Box::new(move |new_value, req| {
let value = value_write.clone();
async move {
println!("Write request {:?} with value {:x?}", &req, &new_value);
let mut value = value.lock().await;
*value = new_value;
Ok(())
}
.boxed()
})),
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Fun(Box::new(move |mut notifier| {
let value = value_notify.clone();
async move {
tokio::spawn(async move {
println!(
"Notification session start with confirming={:?}",
notifier.confirming()
);
loop {
{
let mut value = value.lock().await;
println!("Notifying with value {:x?}", &*value);
if let Err(err) = notifier.notify(value.to_vec()).await {
println!("Notification error: {}", &err);
break;
}
println!("Decrementing each element by one");
for v in &mut *value {
*v = v.saturating_sub(1);
}
}
sleep(Duration::from_secs(5)).await;
}
println!("Notification session stop");
});
}
.boxed()
})),
..Default::default()
}),
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let mut manufacturer_data = BTreeMap::new();
manufacturer_data.insert(MANUFACTURER_ID, vec![0x21, 0x22, 0x23, 0x24]);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
manufacturer_data,
discoverable: Some(true),
local_name: Some("gatt_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT service on Bluetooth adapter {}", adapter.name());
let (service_control, service_handle) = service_control();
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write: true,
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
control_handle: service_handle,
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Service handle is 0x{:x}", service_control.handle()?);
println!("Characteristic handle is 0x{:x}", char_control.handle()?);
println!("Service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut value: Vec<u8> = vec![0x10, 0x01, 0x01, 0x10];
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
let mut interval = interval(Duration::from_secs(1));
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
}
_ = interval.tick() => {
println!("Decrementing each element by one");
for v in &mut *value {
*v = v.saturating_sub(1);
}
println!("Value is {:x?}", &value);
if let Some(writer) = writer_opt.as_mut() {
println!("Notifying with value {:x?}", &value);
if let Err(err) = writer.write(&value).await {
println!("Notification stream error: {}", &err);
writer_opt = None;
}
}
}
read_res = async {
match &mut reader_opt {
Some(reader) => reader.read(&mut read_buf).await,
None => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Write stream ended");
reader_opt = None;
}
Ok(n) => {
value = read_buf[0..n].to_vec();
println!("Write request with {} bytes: {:x?}", n, &value);
}
Err(err) => {
println!("Write stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn serve_gatt_application(
&self,
gatt_application: Application
) -> Result<ApplicationHandle>
pub async fn serve_gatt_application(
&self,
gatt_application: Application
) -> Result<ApplicationHandle>
Registers a local GATT services hierarchy (GATT Server).
Registering a service allows applications to publish a local GATT service, which then becomes available to remote devices.
Drop the returned ApplicationHandle to unregister the application.
Examples found in repository
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("gatt_echo_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT echo service on Bluetooth adapter {}", adapter.name());
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Echo service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write request event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
},
read_res = async {
match &mut reader_opt {
Some(reader) if writer_opt.is_some() => reader.read(&mut read_buf).await,
_ => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Read stream ended");
reader_opt = None;
}
Ok(n) => {
let value = read_buf[..n].to_vec();
println!("Echoing {} bytes: {:x?} ... {:x?}", value.len(), &value[0..4.min(value.len())], &value[value.len().saturating_sub(4) ..]);
if value.len() < 512 {
println!();
}
if let Err(err) = writer_opt.as_mut().unwrap().write_all(&value).await {
println!("Write failed: {}", &err);
writer_opt = None;
}
}
Err(err) => {
println!("Read stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let mut manufacturer_data = BTreeMap::new();
manufacturer_data.insert(MANUFACTURER_ID, vec![0x21, 0x22, 0x23, 0x24]);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
manufacturer_data,
discoverable: Some(true),
local_name: Some("gatt_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT service on Bluetooth adapter {}", adapter.name());
let value = Arc::new(Mutex::new(vec![0x10, 0x01, 0x01, 0x10]));
let value_read = value.clone();
let value_write = value.clone();
let value_notify = value.clone();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
read: Some(CharacteristicRead {
read: true,
fun: Box::new(move |req| {
let value = value_read.clone();
async move {
let value = value.lock().await.clone();
println!("Read request {:?} with value {:x?}", &req, &value);
Ok(value)
}
.boxed()
}),
..Default::default()
}),
write: Some(CharacteristicWrite {
write: true,
write_without_response: true,
method: CharacteristicWriteMethod::Fun(Box::new(move |new_value, req| {
let value = value_write.clone();
async move {
println!("Write request {:?} with value {:x?}", &req, &new_value);
let mut value = value.lock().await;
*value = new_value;
Ok(())
}
.boxed()
})),
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Fun(Box::new(move |mut notifier| {
let value = value_notify.clone();
async move {
tokio::spawn(async move {
println!(
"Notification session start with confirming={:?}",
notifier.confirming()
);
loop {
{
let mut value = value.lock().await;
println!("Notifying with value {:x?}", &*value);
if let Err(err) = notifier.notify(value.to_vec()).await {
println!("Notification error: {}", &err);
break;
}
println!("Decrementing each element by one");
for v in &mut *value {
*v = v.saturating_sub(1);
}
}
sleep(Duration::from_secs(5)).await;
}
println!("Notification session stop");
});
}
.boxed()
})),
..Default::default()
}),
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let mut manufacturer_data = BTreeMap::new();
manufacturer_data.insert(MANUFACTURER_ID, vec![0x21, 0x22, 0x23, 0x24]);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
manufacturer_data,
discoverable: Some(true),
local_name: Some("gatt_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT service on Bluetooth adapter {}", adapter.name());
let (service_control, service_handle) = service_control();
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write: true,
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
control_handle: service_handle,
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Service handle is 0x{:x}", service_control.handle()?);
println!("Characteristic handle is 0x{:x}", char_control.handle()?);
println!("Service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut value: Vec<u8> = vec![0x10, 0x01, 0x01, 0x10];
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
let mut interval = interval(Duration::from_secs(1));
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
}
_ = interval.tick() => {
println!("Decrementing each element by one");
for v in &mut *value {
*v = v.saturating_sub(1);
}
println!("Value is {:x?}", &value);
if let Some(writer) = writer_opt.as_mut() {
println!("Notifying with value {:x?}", &value);
if let Err(err) = writer.write(&value).await {
println!("Notification stream error: {}", &err);
writer_opt = None;
}
}
}
read_res = async {
match &mut reader_opt {
Some(reader) => reader.read(&mut read_buf).await,
None => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Write stream ended");
reader_opt = None;
}
Ok(n) => {
value = read_buf[0..n].to_vec();
println!("Write request with {} bytes: {:x?}", n, &value);
}
Err(err) => {
println!("Write stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn register_gatt_profile(
&self,
gatt_profile: Profile
) -> Result<ProfileHandle>
pub async fn register_gatt_profile(
&self,
gatt_profile: Profile
) -> Result<ProfileHandle>
Registers local GATT profiles (GATT Client).
By registering this type of object an application effectively indicates support for a specific GATT profile and requests automatic connections to be established to devices supporting it.
Drop the returned ProfileHandle to unregister the application.
sourcepub async fn remove_device(&self, address: Address) -> Result<()>
pub async fn remove_device(&self, address: Address) -> Result<()>
This removes the remote device object for the given device address.
It will remove also the pairing information.
Examples found in repository
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
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
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_device(
&self,
address: Address,
address_type: AddressType
) -> Result<Device>
pub async fn connect_device(
&self,
address: Address,
address_type: AddressType
) -> Result<Device>
This method connects to device without need of performing General Discovery.
Connection mechanism is similar to Connect method from Device1 interface with exception that this method returns success when physical connection is established. After this method returns, services discovery will continue and any supported profile will be connected. There is no need for calling Connect on Device1 after this call. If connection was successful this method returns the created device object.
Parameters are the following:
address
- The Bluetooth device address of the remote device.address_type
- The Bluetooth device Address Type. This is address type that should be used for initial connection.
This method is experimental.
sourceimpl Adapter
impl Adapter
sourcepub async fn address(&self) -> Result<Address>
pub async fn address(&self) -> Result<Address>
The Bluetooth adapter address.
Examples found in repository
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
advertisement_type: bluer::adv::Type::Peripheral,
service_uuids: vec!["123e4567-e89b-12d3-a456-426614174000".parse().unwrap()].into_iter().collect(),
discoverable: Some(true),
local_name: Some("le_advertise".to_string()),
..Default::default()
};
println!("{:?}", &le_advertisement);
let handle = adapter.advertise(le_advertisement).await?;
println!("Press enter to quit");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing advertisement");
drop(handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
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
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(())
}
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
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(())
}
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let adapter_addr = adapter.address().await?;
let adapter_addr_type = adapter.address_type().await?;
// Advertising is necessary for device to be connectable.
println!(
"Advertising on Bluetooth adapter {} with {} address {}",
adapter.name(),
&adapter_addr_type,
&adapter_addr
);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("l2cap_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
let listener = StreamListener::bind(local_sa).await?;
println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
let recv_mtu = stream.as_ref().recv_mtu()?;
println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
let mut n = 0;
loop {
n += 1;
// Vary buffer size between MTU and smaller value to test
// partial reads.
let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
continue;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
println!("Removing advertisement");
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("gatt_echo_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
println!("Serving GATT echo service on Bluetooth adapter {}", adapter.name());
let (char_control, char_handle) = characteristic_control();
let app = Application {
services: vec![Service {
uuid: SERVICE_UUID,
primary: true,
characteristics: vec![Characteristic {
uuid: CHARACTERISTIC_UUID,
write: Some(CharacteristicWrite {
write_without_response: true,
method: CharacteristicWriteMethod::Io,
..Default::default()
}),
notify: Some(CharacteristicNotify {
notify: true,
method: CharacteristicNotifyMethod::Io,
..Default::default()
}),
control_handle: char_handle,
..Default::default()
}],
..Default::default()
}],
..Default::default()
};
let app_handle = adapter.serve_gatt_application(app).await?;
println!("Echo service ready. Press enter to quit.");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let mut read_buf = Vec::new();
let mut reader_opt: Option<CharacteristicReader> = None;
let mut writer_opt: Option<CharacteristicWriter> = None;
pin_mut!(char_control);
loop {
tokio::select! {
_ = lines.next_line() => break,
evt = char_control.next() => {
match evt {
Some(CharacteristicControlEvent::Write(req)) => {
println!("Accepting write request event with MTU {}", req.mtu());
read_buf = vec![0; req.mtu()];
reader_opt = Some(req.accept()?);
},
Some(CharacteristicControlEvent::Notify(notifier)) => {
println!("Accepting notify request event with MTU {}", notifier.mtu());
writer_opt = Some(notifier);
},
None => break,
}
},
read_res = async {
match &mut reader_opt {
Some(reader) if writer_opt.is_some() => reader.read(&mut read_buf).await,
_ => future::pending().await,
}
} => {
match read_res {
Ok(0) => {
println!("Read stream ended");
reader_opt = None;
}
Ok(n) => {
let value = read_buf[..n].to_vec();
println!("Echoing {} bytes: {:x?} ... {:x?}", value.len(), &value[0..4.min(value.len())], &value[value.len().saturating_sub(4) ..]);
if value.len() < 512 {
println!();
}
if let Err(err) = writer_opt.as_mut().unwrap().write_all(&value).await {
println!("Write failed: {}", &err);
writer_opt = None;
}
}
Err(err) => {
println!("Read stream error: {}", &err);
reader_opt = None;
}
}
}
}
}
println!("Removing service and advertisement");
drop(app_handle);
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn address_type(&self) -> Result<AddressType>
pub async fn address_type(&self) -> Result<AddressType>
The Bluetooth adapter address type.
For dual-mode and BR/EDR only adapter this defaults to “public”. Single mode LE adapters may have either value. With privacy enabled this contains type of Identity Address and not type of address used for connection.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
More examples
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let adapter_addr = adapter.address().await?;
let adapter_addr_type = adapter.address_type().await?;
// Advertising is necessary for device to be connectable.
println!(
"Advertising on Bluetooth adapter {} with {} address {}",
adapter.name(),
&adapter_addr_type,
&adapter_addr
);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("l2cap_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
let listener = StreamListener::bind(local_sa).await?;
println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
let recv_mtu = stream.as_ref().recv_mtu()?;
println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
let mut n = 0;
loop {
n += 1;
// Vary buffer size between MTU and smaller value to test
// partial reads.
let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
continue;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
println!("Removing advertisement");
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn system_name(&self) -> Result<String>
pub async fn system_name(&self) -> Result<String>
The Bluetooth system name (pretty hostname).
This property is either a static system default or controlled by an external daemon providing access to the pretty hostname configuration.
sourcepub async fn alias(&self) -> Result<String>
pub async fn alias(&self) -> Result<String>
The Bluetooth friendly name.
This value can be changed.
In case no alias is set, it will return the system provided name. Setting an empty string as alias will convert it back to the system provided name.
When resetting the alias with an empty string, the property will default back to system name.
On a well configured system, this property never needs to be changed since it defaults to the system name and provides the pretty hostname. Only if the local name needs to be different from the pretty hostname, this property should be used as last resort.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn set_alias(&self, v: String) -> Result<()>
pub async fn set_alias(&self, v: String) -> Result<()>
The Bluetooth friendly name.
This value can be changed.
In case no alias is set, it will return the system provided name. Setting an empty string as alias will convert it back to the system provided name.
When resetting the alias with an empty string, the property will default back to system name.
On a well configured system, this property never needs to be changed since it defaults to the system name and provides the pretty hostname. Only if the local name needs to be different from the pretty hostname, this property should be used as last resort.
sourcepub async fn class(&self) -> Result<u32>
pub async fn class(&self) -> Result<u32>
The Bluetooth class of device.
This property represents the value that is either automatically configured by DMI/ACPI information or provided as static configuration.
sourcepub async fn is_powered(&self) -> Result<bool>
pub async fn is_powered(&self) -> Result<bool>
Switch an adapter on or off. This will also set the appropriate connectable state of the controller.
The value of this property is not persistent. After restart or unplugging of the adapter it will reset back to false.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn set_powered(&self, v: bool) -> Result<()>
pub async fn set_powered(&self, v: bool) -> Result<()>
Switch an adapter on or off. This will also set the appropriate connectable state of the controller.
The value of this property is not persistent. After restart or unplugging of the adapter it will reset back to false.
Examples found in repository
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
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!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
let le_advertisement = Advertisement {
advertisement_type: bluer::adv::Type::Peripheral,
service_uuids: vec!["123e4567-e89b-12d3-a456-426614174000".parse().unwrap()].into_iter().collect(),
discoverable: Some(true),
local_name: Some("le_advertise".to_string()),
..Default::default()
};
println!("{:?}", &le_advertisement);
let handle = adapter.advertise(le_advertisement).await?;
println!("Press enter to quit");
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
let _ = lines.next_line().await;
println!("Removing advertisement");
drop(handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
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
fn main() -> bluer::Result<()> {
let with_changes = env::args().any(|arg| arg == "--changes");
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);
if let Err(err) = query_device(&adapter, addr).await {
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(())
}
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
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(())
}
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
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(())
}
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let args: Vec<_> = env::args().collect();
if args.len() != 2 {
eprintln!("Specify target Bluetooth address as argment");
exit(1);
}
let target_addr: Address = args[1].parse().expect("invalid address");
let target_sa = SocketAddr::new(target_addr, AddressType::LePublic, PSM);
println!("Connecting to {:?}", &target_sa);
let mut stream = Stream::connect(target_sa).await.expect("connection failed");
println!("Local address: {:?}", stream.as_ref().local_addr()?);
println!("Remote address: {:?}", stream.peer_addr()?);
println!("Send MTU: {:?}", stream.as_ref().send_mtu());
println!("Recv MTU: {}", stream.as_ref().recv_mtu()?);
println!("Security: {:?}", stream.as_ref().security()?);
println!("Flow control: {:?}", stream.as_ref().flow_control());
println!("\nReceiving hello");
let mut hello_buf = [0u8; HELLO_MSG.len()];
stream.read_exact(&mut hello_buf).await.expect("read failed");
println!("Received: {}", String::from_utf8_lossy(&hello_buf));
if hello_buf != HELLO_MSG {
panic!("Wrong hello message");
}
let (mut rh, mut wh) = stream.into_split();
let mut rng = rand::thread_rng();
for i in 0..15 {
let len = rng.gen_range(0..50000);
let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
println!("\nTest iteration {} with data size {}", i, len);
// 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 rh.read_exact(&mut echo_buf).await {
Ok(_) => Ok(echo_buf),
Err(err) => Err(err),
};
(rh, res)
});
// Note that write_all will automatically split the buffer into
// multiple writes of MTU size.
wh.write_all(&data).await.expect("write failed");
println!("Waiting for echo");
let (rh_back, res) = read_task.await.unwrap();
rh = rh_back;
let echo_buf = res.expect("read failed");
if echo_buf != data {
panic!("Echoed data does not match sent data");
}
println!("Data matches");
}
println!("Done");
Ok(())
}
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
fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let adapter_addr = adapter.address().await?;
let adapter_addr_type = adapter.address_type().await?;
// Advertising is necessary for device to be connectable.
println!(
"Advertising on Bluetooth adapter {} with {} address {}",
adapter.name(),
&adapter_addr_type,
&adapter_addr
);
let le_advertisement = Advertisement {
service_uuids: vec![SERVICE_UUID].into_iter().collect(),
discoverable: Some(true),
local_name: Some("l2cap_server".to_string()),
..Default::default()
};
let adv_handle = adapter.advertise(le_advertisement).await?;
let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
let listener = StreamListener::bind(local_sa).await?;
println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
let recv_mtu = stream.as_ref().recv_mtu()?;
println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
let mut n = 0;
loop {
n += 1;
// Vary buffer size between MTU and smaller value to test
// partial reads.
let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
continue;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
println!("Removing advertisement");
drop(adv_handle);
sleep(Duration::from_secs(1)).await;
Ok(())
}
sourcepub async fn is_discoverable(&self) -> Result<bool>
pub async fn is_discoverable(&self) -> Result<bool>
Switch an adapter to discoverable or non-discoverable to either make it visible or hide it.
This is a global setting and should only be used by the settings application.
If the DiscoverableTimeout is set to a non-zero value then the system will set this value back to false after the timer expired.
In case the adapter is switched off, setting this value will fail.
When changing the Powered property the new state of this property will be updated via a PropertiesChanged signal.
For any new adapter this settings defaults to false.
To send Bluetooth LE advertisements use the advertise method instead.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn set_discoverable(&self, v: bool) -> Result<()>
pub async fn set_discoverable(&self, v: bool) -> Result<()>
Switch an adapter to discoverable or non-discoverable to either make it visible or hide it.
This is a global setting and should only be used by the settings application.
If the DiscoverableTimeout is set to a non-zero value then the system will set this value back to false after the timer expired.
In case the adapter is switched off, setting this value will fail.
When changing the Powered property the new state of this property will be updated via a PropertiesChanged signal.
For any new adapter this settings defaults to false.
To send Bluetooth LE advertisements use the advertise method instead.
sourcepub async fn is_pairable(&self) -> Result<bool>
pub async fn is_pairable(&self) -> Result<bool>
Switch an adapter to pairable or non-pairable.
This is a global setting and should only be used by the settings application.
Note that this property only affects incoming pairing requests.
For any new adapter this settings defaults to true.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn set_pairable(&self, v: bool) -> Result<()>
pub async fn set_pairable(&self, v: bool) -> Result<()>
Switch an adapter to pairable or non-pairable.
This is a global setting and should only be used by the settings application.
Note that this property only affects incoming pairing requests.
For any new adapter this settings defaults to true.
sourcepub async fn pairable_timeout(&self) -> Result<u32>
pub async fn pairable_timeout(&self) -> Result<u32>
The pairable timeout in seconds.
A value of zero means that the timeout is disabled and it will stay in pairable mode forever.
The default value for pairable timeout should be disabled (value 0).
sourcepub async fn set_pairable_timeout(&self, v: u32) -> Result<()>
pub async fn set_pairable_timeout(&self, v: u32) -> Result<()>
The pairable timeout in seconds.
A value of zero means that the timeout is disabled and it will stay in pairable mode forever.
The default value for pairable timeout should be disabled (value 0).
sourcepub async fn discoverable_timeout(&self) -> Result<u32>
pub async fn discoverable_timeout(&self) -> Result<u32>
The discoverable timeout in seconds.
A value of zero means that the timeout is disabled and it will stay in discoverable/limited mode forever.
The default value for the discoverable timeout should be 180 seconds (3 minutes).
sourcepub async fn set_discoverable_timeout(&self, v: u32) -> Result<()>
pub async fn set_discoverable_timeout(&self, v: u32) -> Result<()>
The discoverable timeout in seconds.
A value of zero means that the timeout is disabled and it will stay in discoverable/limited mode forever.
The default value for the discoverable timeout should be 180 seconds (3 minutes).
sourcepub async fn is_discovering(&self) -> Result<bool>
pub async fn is_discovering(&self) -> Result<bool>
Indicates that a device discovery procedure is active.
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 local services.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn modalias(&self) -> Result<Option<Modalias>>
pub async fn modalias(&self) -> Result<Option<Modalias>>
Local Device ID information in modalias format used by the kernel and udev.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn active_advertising_instances(&self) -> Result<u8>
pub async fn active_advertising_instances(&self) -> Result<u8>
Number of active advertising instances.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn supported_advertising_instances(&self) -> Result<u8>
pub async fn supported_advertising_instances(&self) -> Result<u8>
Number of available advertising instances.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn supported_advertising_system_includes(
&self
) -> Result<BTreeSet<Feature>>
pub async fn supported_advertising_system_includes(
&self
) -> Result<BTreeSet<Feature>>
List of supported system includes.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn supported_advertising_secondary_channels(
&self
) -> Result<BTreeSet<SecondaryChannel>>
pub async fn supported_advertising_secondary_channels(
&self
) -> Result<BTreeSet<SecondaryChannel>>
List of supported Secondary channels.
Secondary channels can be used to advertise with the corresponding PHY.
sourcepub async fn supported_advertising_capabilities(
&self
) -> Result<Option<Capabilities>>
pub async fn supported_advertising_capabilities(
&self
) -> Result<Option<Capabilities>>
Enumerates Advertising-related controller capabilities useful to the client.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
sourcepub async fn supported_advertising_features(
&self
) -> Result<Option<BTreeSet<PlatformFeature>>>
pub async fn supported_advertising_features(
&self
) -> Result<Option<BTreeSet<PlatformFeature>>>
List of supported platform features.
If no features are available on the platform, the SupportedFeatures array will be empty.
Examples found in repository
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
fn main() -> bluer::Result<()> {
let session = bluer::Session::new().await?;
let adapter_names = session.adapter_names().await?;
for adapter_name in adapter_names {
println!("Bluetooth adapater {}:", &adapter_name);
let adapter = session.adapter(&adapter_name)?;
println!(" Address: {}", adapter.address().await?);
println!(" Address type: {}", adapter.address_type().await?);
println!(" Friendly name: {}", adapter.alias().await?);
println!(" Modalias: {:?}", adapter.modalias().await?);
println!(" Powered: {:?}", adapter.is_powered().await?);
println!(" Discoverabe: {:?}", adapter.is_discoverable().await?);
println!(" Pairable: {:?}", adapter.is_pairable().await?);
println!(" UUIDs: {:?}", adapter.uuids().await?);
println!();
println!(" Active adv. instances: {}", adapter.active_advertising_instances().await?);
println!(" Supp. adv. instances: {}", adapter.supported_advertising_instances().await?);
println!(" Supp. adv. includes: {:?}", adapter.supported_advertising_system_includes().await?);
println!(" Adv. capabilites: {:?}", adapter.supported_advertising_capabilities().await?);
println!(" Adv. features: {:?}", adapter.supported_advertising_features().await?);
println!();
}
Ok(())
}
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for Adapter
impl Send for Adapter
impl Sync for Adapter
impl Unpin for Adapter
impl !UnwindSafe for Adapter
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub 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.
sourcepub fn to_owned(&self) -> T
pub fn to_owned(&self) -> T
Creates owned data from borrowed data, usually by cloning. Read more
sourcepub fn clone_into(&self, target: &mut T)
pub fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more