laptou / bluez-rs Goto Github PK
View Code? Open in Web Editor NEWControl Bluetooth on Linux.
License: MIT License
Control Bluetooth on Linux.
License: MIT License
I notice that blueman-manager
can discover devices with bluez without being root. Why does bluez-rs need sudo
permissions for discovering?
I'm new to rust, but want to try it with bluez. From
cargo new test-bluez
I added:
bluez = "0.3.0"
to Cargo.toml
, but when I try to compile, it fails with:
...
error: aborting due to 43 previous errors
Some errors have detailed explanations: E0034, E0308.
For more information about an error, try `rustc --explain E0034`.
error: could not compile `bitvec`
To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed
I know that this is not a bluez problem, but I am hoping that there is something I can change with the way I import bluez into my project in order to make this compile.
After confirming a connection request, I'm getting a panic happening at the following line:
bluez-rs/src/interface/response.rs
Line 75 in 02ec3fc
This apparently comes up when processing the NewLongTermKey
event.
buf.get_u8()
gives a 3
. The FromPrimitive
helper can't parse this into a LongTermKeyType
which is why it panics.
Any idea what is going on?
I'm looking for a way to continually discover beacons that use simple advertising packets to emit telemetry data (among others). Is there a way to run discovery in a way that would allow me to capture and process all these packets, even if multiple packets are sent from the same device?
I'm attempting to set the publicly visible name for my bluetooth controller using set_local_name
. This function panics though. Calling other functions such as set_discoverable
works fine.
For example, this panics:
block_on(client.set_local_name(controller, "PokoeBox", None));
Here's a trace:
thread 'main' panicked at 'assertion failed: self.remaining() >= dst.len()', /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-0.5.4/src/buf/buf_impl.rs:245:9
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:77
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1028
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1412
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:188
9: std::panicking::default_hook
at src/libstd/panicking.rs:205
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:464
11: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:373
12: rust_begin_unwind
at src/libstd/panicking.rs:302
13: core::panicking::panic_fmt
at src/libcore/panicking.rs:139
14: core::panicking::panic
at src/libcore/panicking.rs:70
15: bytes::buf::buf_impl::Buf::copy_to_slice
at ./<::core::macros::panic macros>:5
16: bluez::client::settings::<impl bluez::client::BlueZClient>::set_local_name::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/bluez-0.1.1/src/client/settings.rs:57
17: <std::future::GenFuture<T> as core::future::future::Future>::poll::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
18: std::future::set_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:79
19: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
20: std::future::poll_with_tls_context::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
21: std::future::get_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:111
22: std::future::poll_with_tls_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
23: async_std::task::block_on::block_on::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:68
24: <std::future::GenFuture<T> as core::future::future::Future>::poll::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
25: std::future::set_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:79
26: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
27: async_std::task::block_on::run::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:128
28: std::thread::local::LocalKey<T>::try_with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:262
29: std::thread::local::LocalKey<T>::with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:239
30: async_std::task::block_on::run
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:118
31: async_std::task::block_on::block_on::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:72
32: async_std::task::task::Task::set_current::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/task.rs:129
33: std::thread::local::LocalKey<T>::try_with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:262
34: std::thread::local::LocalKey<T>::with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:239
35: async_std::task::task::Task::set_current
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/task.rs:124
36: async_std::task::block_on::block_on
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:72
37: pokoebox_bluetooth::main::main::{{closure}}
at src/main.rs:38
38: <std::future::GenFuture<T> as core::future::future::Future>::poll::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
39: std::future::set_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:79
40: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
41: std::future::poll_with_tls_context::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
42: std::future::get_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:111
43: std::future::poll_with_tls_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
44: pokoebox_bluetooth::main::{{closure}}
at src/main.rs:10
45: <std::future::GenFuture<T> as core::future::future::Future>::poll::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
46: std::future::set_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:79
47: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
48: std::future::poll_with_tls_context::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
49: std::future::get_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:111
50: std::future::poll_with_tls_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:121
51: async_std::task::block_on::block_on::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:68
52: <std::future::GenFuture<T> as core::future::future::Future>::poll::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
53: std::future::set_task_context
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:79
54: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/future.rs:43
55: async_std::task::block_on::run::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:128
56: std::thread::local::LocalKey<T>::try_with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:262
57: std::thread::local::LocalKey<T>::with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:239
58: async_std::task::block_on::run
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:118
59: async_std::task::block_on::block_on::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:72
60: async_std::task::task::Task::set_current::{{closure}}
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/task.rs:129
61: std::thread::local::LocalKey<T>::try_with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:262
62: std::thread::local::LocalKey<T>::with
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/thread/local.rs:239
63: async_std::task::task::Task::set_current
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/task.rs:124
64: async_std::task::block_on::block_on
at /home/timvisee/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.5.0/src/task/block_on.rs:72
65: pokoebox_bluetooth::main
at src/main.rs:10
66: std::rt::lang_start::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
67: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:48
68: std::panicking::try::do_call
at src/libstd/panicking.rs:287
69: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
70: std::panicking::try
at src/libstd/panicking.rs:265
71: std::panic::catch_unwind
at src/libstd/panic.rs:396
72: std::rt::lang_start_internal
at src/libstd/rt.rs:47
73: std::rt::lang_start
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
74: main
75: __libc_start_main
76: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Line 94 in d0b59ce
As far as I can tell, this library is async
... meaning that execution will pause at the right time when needing to wait for data from file descriptors or socket, but returning right away if there is enough.
If you were polling the bluez API for changes, it would make sense to sleep
to avoid polling too hard. But when doing async, the process pauses when it needs more data from an input...
I think it should be safe to drop the sleeping here. I can try to measure timings to confirm the above.
I know, I know, I'm an idiot, but for the life of me, I cannot figure out how to connect to bluetooth devices using this library. I'm not looking for pairing, and I'm not using BLE devices, I just need the equivalent of bluetoothctl connect <dev>
.
I'm really interested in the repository for a project I'm working on. Is it possible to filter a device "simple name" in the discovery process? I know that's available in the advertisement data. Does anyone have an example how to to pair a device?
Sorry for bothering again, but I'm a bit confused on how this crate sends HCI commands. The bytes generated here:
bluez-rs/src/interface/request.rs
Lines 13 to 24 in 01ee38b
don't seem to line up with the C library here. Would you mind explaining where I can find documentation about the type of data that can be sent to the HCI socket/stream?
The remove_device method sends an AddDevice command, instead of a RemoveDevice.
Once connected how do I interface with the GATT services and characteristics that are supported by the peripheral?
Thank you for this nice crate. When trying to set up my rpi as a bluetooth keyboard I run into the following error, specifically while setting the device class:
Error: Xfer { source: Bluez { source: CommandError { opcode: SetDeviceClass, status: InvalidParams } } }
Where Xfer
is my own Error enum.
This is roughly my program:
pub async fn run() -> Result<(), Error> {
let mut client = BlueZClient::new().unwrap();
let version = client.get_mgmt_version().await?;
trace!(
"management version: {}.{}",
version.version,
version.revision
);
let controllers = client.get_ext_controller_list().await?;
let (controller, type_is, bus) = controllers.first().with_context(|| NoControllers)?;
trace!(
"got controller:\n{:?} ({:?}, {:?})",
controller,
type_is,
bus
);
trace!(
"info:\n{:#?}",
client.get_controller_info(*controller).await?
);
let ctrl_settings = client
.set_powered(
*controller,
true
)
.await?;
trace!("controller settings after power on: {:?}", ctrl_settings);
let ctrl_settings = client
.set_connectable(
*controller,
true
)
.await?;
trace!("controller settings after connectable: {:?}", ctrl_settings);
let ctrl_settings = client
.set_discoverable(
*controller,
DiscoverableMode::Limited,
Some(60)
)
.await?;
trace!("controller settings after discoverable: {:?}", ctrl_settings);
let return_classes = client
.set_device_class(
*controller,
DeviceClass::Peripheral {
keyboard: true,
pointer: false,
class: PeripheralDeviceClass::Uncategorized,
},
)
.await?;
trace!("set device class, got: {:?}", return_classes);
Ok(())
}
It's notable however, that using the command line to set the device class is working:
sudo hciconfig hci0 class 0x002540
After running the cli above, the settings have properly updated:
ControllerInfo {
address: Address {
bytes: [
248,
250,
50,
235,
39,
184,
],
},
bluetooth_version: 7,
manufacturer: 15,
supported_settings: BitFlags<ControllerSetting> {
bits: 0b11011111111111111,
flags: Powered | Connectable | FastConnectable | Discoverable | Pairable | LinkLevelSecurity | SecureSimplePairing | BREDR | HighSpeed | LE | Advertising | SecureConnection | DebugKeys | Privacy | StaticAddress | PhyConfiguration,
},
current_settings: BitFlags<ControllerSetting> {
bits: 0b101011010011,
flags: Powered | Connectable | Pairable | SecureSimplePairing | BREDR | LE | SecureConnection,
},
class_of_device: (
Peripheral {
keyboard: true,
pointer: false,
class: Uncategorized,
},
BitFlags<ServiceClass> {
bits: 0b0,
},
),
name: "raspberrypi",
short_name: "",
}
I'm new to working with bluetooth so I'm not sure what the problem is, but I thought it might be that the DeviceClass
wasn't being converted into the correct u16
- indeed my device class seems to convert to 0x540
, but making exec_command
public and calling it with an explicit class of 0x2540
encounters the same error.
Is there an example of peripheral mode, I am looking for a way to start a BLE server that offers data of CPU/memory usage, runs small shell scripts, etc.
Thanks!
I see that RFCOMM support was added back in August, but no version with it in has been released yet.
I have created a new rust project (cargo init
with cargo version 1.42.0) and added bluez = "0.1.2"
as a dependency as written on the crates.io page. With no other changes to the helloWorld example, I get a build error saying
Updating crates.io index
error: failed to select a version for the requirement `bitvec = "^0.16"`
candidate versions found which didn't match: 0.17.4
location searched: crates.io index
required by package `bluez v0.1.2`
... which is depended on by `tests v0.1.0 (/tmp/tests)`
Cloning this repo and running the examples worked fine.
It looks like all bitvec v0.16 crates have been yanked.
The IoCapability
values seem to be incorrect. I believe their values should start from 0
, not 1
.
Lines 62 to 70 in 02ec3fc
I couldn't really find proper documentation on this. But here's some source that specifies these:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.