Struct bluer::Session

source ·
pub struct Session { /* private fields */ }
Available on crate feature bluetoothd only.
Expand description

Bluetooth session.

Encapsulates a connection to the system Bluetooth daemon.

Implementations§

source§

impl Session

source

pub async fn new() -> Result<Self>

Create a new Bluetooth session.

This establishes a connection to the system Bluetooth daemon over D-Bus.

Examples found in repository?
examples/list_adapters.rs (line 34)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
async fn main() -> bluer::Result<()> {
    let all_properties = env::args().any(|arg| arg == "--all-properties");

    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)?;
        if all_properties {
            query_all_adapter_properties(&adapter).await?;
        } else {
            query_adapter(&adapter).await?;
        }
        println!();
    }
    Ok(())
}
More examples
Hide additional examples
examples/le_advertise.rs (line 13)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    println!("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(())
}
examples/rfcomm_server.rs (line 11)
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 main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;
    adapter.set_discoverable(true).await?;
    let adapter_addr = adapter.address().await?;

    let local_sa = SocketAddr::new(adapter_addr, CHANNEL);
    let listener = Listener::bind(local_sa).await?;

    println!(
        "Listening on {} channel {}. Press enter to quit.",
        listener.as_ref().local_addr()?.addr,
        listener.as_ref().local_addr()?.channel
    );
    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,
        };

        println!("Accepted connection from {:?}", &sa);

        println!("Sending hello");
        if let Err(err) = stream.write_all(HELLO_MSG).await {
            println!("Write failed: {}", &err);
            continue;
        }

        loop {
            let buf_size = 1024;
            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);
                    break;
                }
            };
            let buf = &buf[..n];

            println!("Echoing {} bytes", buf.len());
            if let Err(err) = stream.write_all(buf).await {
                println!("Write failed: {}", &err);
                continue;
            }
        }
    }

    Ok(())
}
examples/gatt_client.rs (line 148)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    {
        println!(
            "Discovering on Bluetooth adapter {} with address {}\n",
            adapter.name(),
            adapter.address().await?
        );
        let discover = adapter.discover_devices().await?;
        pin_mut!(discover);
        let mut done = false;
        while let Some(evt) = discover.next().await {
            match evt {
                AdapterEvent::DeviceAdded(addr) => {
                    let device = adapter.device(addr)?;
                    match find_our_characteristic(&device).await {
                        Ok(Some(char)) => match exercise_characteristic(&char).await {
                            Ok(()) => {
                                println!("    Characteristic exercise completed");
                                done = true;
                            }
                            Err(err) => {
                                println!("    Characteristic exercise failed: {}", &err);
                            }
                        },
                        Ok(None) => (),
                        Err(err) => {
                            println!("    Device failed: {}", &err);
                            let _ = adapter.remove_device(device.address()).await;
                        }
                    }
                    match device.disconnect().await {
                        Ok(()) => println!("    Device disconnected"),
                        Err(err) => println!("    Device disconnection failed: {}", &err),
                    }
                    println!();
                }
                AdapterEvent::DeviceRemoved(addr) => {
                    println!("Device removed {addr}");
                }
                _ => (),
            }
            if done {
                break;
            }
        }
        println!("Stopping discovery");
    }

    sleep(Duration::from_secs(1)).await;
    Ok(())
}
examples/gatt_echo_client.rs (line 148)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    {
        println!(
            "Discovering on Bluetooth adapter {} with address {}\n",
            adapter.name(),
            adapter.address().await?
        );
        let discover = adapter.discover_devices().await?;
        pin_mut!(discover);
        let mut done = false;
        while let Some(evt) = discover.next().await {
            match evt {
                AdapterEvent::DeviceAdded(addr) => {
                    let device = adapter.device(addr)?;
                    match find_our_characteristic(&device).await {
                        Ok(Some(char)) => match exercise_characteristic(&char).await {
                            Ok(()) => {
                                println!("    Characteristic exercise completed");
                                done = true;
                            }
                            Err(err) => {
                                println!("    Characteristic exercise failed: {}", &err);
                            }
                        },
                        Ok(None) => (),
                        Err(err) => {
                            println!("    Device failed: {}", &err);
                            let _ = adapter.remove_device(device.address()).await;
                        }
                    }
                    match device.disconnect().await {
                        Ok(()) => println!("    Device disconnected"),
                        Err(err) => println!("    Device disconnection failed: {}", &err),
                    }
                    println!();
                }
                AdapterEvent::DeviceRemoved(addr) => {
                    println!("Device removed {addr}");
                }
                _ => (),
            }
            if done {
                break;
            }
        }
        println!("Stopping discovery");
    }

    sleep(Duration::from_secs(1)).await;
    Ok(())
}
examples/le_passive_scan.rs (line 43)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();

    let adapter_name = std::env::args().nth(1);
    let data_type: u8 = match std::env::args().nth(2) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse AD type"),
        None => 0xff,
    };
    let start_position: u8 = match std::env::args().nth(3) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse or-pattern start position"),
        None => 0x00,
    };
    let filter_string: Vec<String> = std::env::args().skip(4).collect();
    let content: Vec<u8> = if !filter_string.is_empty() {
        filter_string.iter().map(|s| parse_u8_maybe_hex(s).expect("Failed to parse or-pattern data")).collect()
    } else {
        vec![0xff, 0xff]
    };

    if content.is_empty() {
        panic!("No filter bytes provided");
    }

    let pattern = Pattern { data_type, start_position, content };

    let session = bluer::Session::new().await?;

    let adapter = match adapter_name {
        Some(name) => session.adapter(&name)?,
        None => session.default_adapter().await?,
    };
    println!("Running le_passive_scan on adapter {} with or-pattern {:?}", adapter.name(), pattern);

    adapter.set_powered(true).await?;

    let mm = adapter.monitor().await?;
    let mut monitor_handle = mm
        .register(Monitor {
            monitor_type: bluer::monitor::Type::OrPatterns,
            rssi_low_threshold: None,
            rssi_high_threshold: None,
            rssi_low_timeout: None,
            rssi_high_timeout: None,
            rssi_sampling_period: Some(RssiSamplingPeriod::First),
            patterns: Some(vec![pattern]),
            ..Default::default()
        })
        .await?;

    while let Some(mevt) = &monitor_handle.next().await {
        if let MonitorEvent::DeviceFound(devid) = mevt {
            println!("Discovered device {:?}", devid);
            let dev = adapter.device(devid.device)?;
            tokio::spawn(async move {
                let mut events = dev.events().await.unwrap();
                while let Some(ev) = events.next().await {
                    println!("On device {:?}, received event {:?}", dev, ev);
                }
            });
        }
    }

    Ok(())
}
source

pub async fn default_adapter(&self) -> Result<Adapter>

Create an interface to the default Bluetooth adapter.

If hci0 is present it is used as the default adapter. Otherwise the adapter that is first by lexicographic sorting is used as default.

If the system has no Bluetooth adapter an error with ErrorKind::NotFound is returned.

Examples found in repository?
examples/le_advertise.rs (line 14)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    println!("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
Hide additional examples
examples/rfcomm_server.rs (line 12)
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 main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;
    adapter.set_discoverable(true).await?;
    let adapter_addr = adapter.address().await?;

    let local_sa = SocketAddr::new(adapter_addr, CHANNEL);
    let listener = Listener::bind(local_sa).await?;

    println!(
        "Listening on {} channel {}. Press enter to quit.",
        listener.as_ref().local_addr()?.addr,
        listener.as_ref().local_addr()?.channel
    );
    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,
        };

        println!("Accepted connection from {:?}", &sa);

        println!("Sending hello");
        if let Err(err) = stream.write_all(HELLO_MSG).await {
            println!("Write failed: {}", &err);
            continue;
        }

        loop {
            let buf_size = 1024;
            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);
                    break;
                }
            };
            let buf = &buf[..n];

            println!("Echoing {} bytes", buf.len());
            if let Err(err) = stream.write_all(buf).await {
                println!("Write failed: {}", &err);
                continue;
            }
        }
    }

    Ok(())
}
examples/gatt_client.rs (line 149)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    {
        println!(
            "Discovering on Bluetooth adapter {} with address {}\n",
            adapter.name(),
            adapter.address().await?
        );
        let discover = adapter.discover_devices().await?;
        pin_mut!(discover);
        let mut done = false;
        while let Some(evt) = discover.next().await {
            match evt {
                AdapterEvent::DeviceAdded(addr) => {
                    let device = adapter.device(addr)?;
                    match find_our_characteristic(&device).await {
                        Ok(Some(char)) => match exercise_characteristic(&char).await {
                            Ok(()) => {
                                println!("    Characteristic exercise completed");
                                done = true;
                            }
                            Err(err) => {
                                println!("    Characteristic exercise failed: {}", &err);
                            }
                        },
                        Ok(None) => (),
                        Err(err) => {
                            println!("    Device failed: {}", &err);
                            let _ = adapter.remove_device(device.address()).await;
                        }
                    }
                    match device.disconnect().await {
                        Ok(()) => println!("    Device disconnected"),
                        Err(err) => println!("    Device disconnection failed: {}", &err),
                    }
                    println!();
                }
                AdapterEvent::DeviceRemoved(addr) => {
                    println!("Device removed {addr}");
                }
                _ => (),
            }
            if done {
                break;
            }
        }
        println!("Stopping discovery");
    }

    sleep(Duration::from_secs(1)).await;
    Ok(())
}
examples/gatt_echo_client.rs (line 149)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    {
        println!(
            "Discovering on Bluetooth adapter {} with address {}\n",
            adapter.name(),
            adapter.address().await?
        );
        let discover = adapter.discover_devices().await?;
        pin_mut!(discover);
        let mut done = false;
        while let Some(evt) = discover.next().await {
            match evt {
                AdapterEvent::DeviceAdded(addr) => {
                    let device = adapter.device(addr)?;
                    match find_our_characteristic(&device).await {
                        Ok(Some(char)) => match exercise_characteristic(&char).await {
                            Ok(()) => {
                                println!("    Characteristic exercise completed");
                                done = true;
                            }
                            Err(err) => {
                                println!("    Characteristic exercise failed: {}", &err);
                            }
                        },
                        Ok(None) => (),
                        Err(err) => {
                            println!("    Device failed: {}", &err);
                            let _ = adapter.remove_device(device.address()).await;
                        }
                    }
                    match device.disconnect().await {
                        Ok(()) => println!("    Device disconnected"),
                        Err(err) => println!("    Device disconnection failed: {}", &err),
                    }
                    println!();
                }
                AdapterEvent::DeviceRemoved(addr) => {
                    println!("Device removed {addr}");
                }
                _ => (),
            }
            if done {
                break;
            }
        }
        println!("Stopping discovery");
    }

    sleep(Duration::from_secs(1)).await;
    Ok(())
}
examples/le_passive_scan.rs (line 47)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();

    let adapter_name = std::env::args().nth(1);
    let data_type: u8 = match std::env::args().nth(2) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse AD type"),
        None => 0xff,
    };
    let start_position: u8 = match std::env::args().nth(3) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse or-pattern start position"),
        None => 0x00,
    };
    let filter_string: Vec<String> = std::env::args().skip(4).collect();
    let content: Vec<u8> = if !filter_string.is_empty() {
        filter_string.iter().map(|s| parse_u8_maybe_hex(s).expect("Failed to parse or-pattern data")).collect()
    } else {
        vec![0xff, 0xff]
    };

    if content.is_empty() {
        panic!("No filter bytes provided");
    }

    let pattern = Pattern { data_type, start_position, content };

    let session = bluer::Session::new().await?;

    let adapter = match adapter_name {
        Some(name) => session.adapter(&name)?,
        None => session.default_adapter().await?,
    };
    println!("Running le_passive_scan on adapter {} with or-pattern {:?}", adapter.name(), pattern);

    adapter.set_powered(true).await?;

    let mm = adapter.monitor().await?;
    let mut monitor_handle = mm
        .register(Monitor {
            monitor_type: bluer::monitor::Type::OrPatterns,
            rssi_low_threshold: None,
            rssi_high_threshold: None,
            rssi_low_timeout: None,
            rssi_high_timeout: None,
            rssi_sampling_period: Some(RssiSamplingPeriod::First),
            patterns: Some(vec![pattern]),
            ..Default::default()
        })
        .await?;

    while let Some(mevt) = &monitor_handle.next().await {
        if let MonitorEvent::DeviceFound(devid) = mevt {
            println!("Discovered device {:?}", devid);
            let dev = adapter.device(devid.device)?;
            tokio::spawn(async move {
                let mut events = dev.events().await.unwrap();
                while let Some(ev) = events.next().await {
                    println!("On device {:?}, received event {:?}", dev, ev);
                }
            });
        }
    }

    Ok(())
}
examples/rfcomm_client.rs (line 17)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();
    let session = bluer::Session::new().await?;
    let adapter = session.default_adapter().await?;
    adapter.set_powered(true).await?;

    let args: Vec<_> = env::args().collect();
    if args.len() != 2 {
        eprintln!("Specify target Bluetooth address as argument");
        exit(1);
    }

    let target_addr: Address = args[1].parse().expect("invalid address");
    let target_sa = SocketAddr::new(target_addr, CHANNEL);

    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!("Security: {:?}", stream.as_ref().security()?);

    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 {i} with data size {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(())
}
source

pub async fn adapter_names(&self) -> Result<Vec<String>>

Enumerate connected Bluetooth adapters and return their names.

Examples found in repository?
examples/list_adapters.rs (line 35)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
async fn main() -> bluer::Result<()> {
    let all_properties = env::args().any(|arg| arg == "--all-properties");

    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)?;
        if all_properties {
            query_all_adapter_properties(&adapter).await?;
        } else {
            query_adapter(&adapter).await?;
        }
        println!();
    }
    Ok(())
}
source

pub fn adapter(&self, adapter_name: &str) -> Result<Adapter>

Create an interface to the Bluetooth adapter with the specified name.

Examples found in repository?
examples/list_adapters.rs (line 38)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
async fn main() -> bluer::Result<()> {
    let all_properties = env::args().any(|arg| arg == "--all-properties");

    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)?;
        if all_properties {
            query_all_adapter_properties(&adapter).await?;
        } else {
            query_adapter(&adapter).await?;
        }
        println!();
    }
    Ok(())
}
More examples
Hide additional examples
examples/le_passive_scan.rs (line 46)
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
async fn main() -> bluer::Result<()> {
    env_logger::init();

    let adapter_name = std::env::args().nth(1);
    let data_type: u8 = match std::env::args().nth(2) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse AD type"),
        None => 0xff,
    };
    let start_position: u8 = match std::env::args().nth(3) {
        Some(s) => parse_u8_maybe_hex(&s).expect("Failed to parse or-pattern start position"),
        None => 0x00,
    };
    let filter_string: Vec<String> = std::env::args().skip(4).collect();
    let content: Vec<u8> = if !filter_string.is_empty() {
        filter_string.iter().map(|s| parse_u8_maybe_hex(s).expect("Failed to parse or-pattern data")).collect()
    } else {
        vec![0xff, 0xff]
    };

    if content.is_empty() {
        panic!("No filter bytes provided");
    }

    let pattern = Pattern { data_type, start_position, content };

    let session = bluer::Session::new().await?;

    let adapter = match adapter_name {
        Some(name) => session.adapter(&name)?,
        None => session.default_adapter().await?,
    };
    println!("Running le_passive_scan on adapter {} with or-pattern {:?}", adapter.name(), pattern);

    adapter.set_powered(true).await?;

    let mm = adapter.monitor().await?;
    let mut monitor_handle = mm
        .register(Monitor {
            monitor_type: bluer::monitor::Type::OrPatterns,
            rssi_low_threshold: None,
            rssi_high_threshold: None,
            rssi_low_timeout: None,
            rssi_high_timeout: None,
            rssi_sampling_period: Some(RssiSamplingPeriod::First),
            patterns: Some(vec![pattern]),
            ..Default::default()
        })
        .await?;

    while let Some(mevt) = &monitor_handle.next().await {
        if let MonitorEvent::DeviceFound(devid) = mevt {
            println!("Discovered device {:?}", devid);
            let dev = adapter.device(devid.device)?;
            tokio::spawn(async move {
                let mut events = dev.events().await.unwrap();
                while let Some(ev) = events.next().await {
                    println!("On device {:?}, received event {:?}", dev, ev);
                }
            });
        }
    }

    Ok(())
}
source

pub async fn mesh(&self) -> Result<Network>

Available on crate feature mesh only.

Create an interface for the Bluetooth mesh network.

source

pub async fn register_agent(&self, agent: Agent) -> Result<AgentHandle>

Registers a Bluetooth authorization agent handler.

Every application can register its own agent to use that agent for all actions triggered by that application.

It is not required by an application to register an agent. If an application chooses not to register an agent, the default agent is used. This is in most cases a good idea. Only applications like a pairing wizard should register their own agent.

An application can only register one agent. Multiple agents per application are not supported.

Drop the returned AgentHandle to unregister the agent.

source

pub async fn register_profile(&self, profile: Profile) -> Result<ProfileHandle>

Available on crate feature rfcomm only.

This registers a Bluetooth profile implementation for RFCOMM connections.

The returned ProfileHandle provides a stream of connection requests.

Drop the handle to unregister the profile.

source

pub async fn events(&self) -> Result<impl Stream<Item = SessionEvent>>

Stream adapter added and removed events.

Trait Implementations§

source§

impl Clone for Session

source§

fn clone(&self) -> Session

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Session

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.