-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use notifications (start_notify
)
#9
Comments
Hi, |
@dati91 thanks for the response. Do you think that this feature would be difficult to implement? If it isn't too much hassle I'd like to contribute. |
@stankec My main concern is that somehow we need to receive the messages (we can do this with a loop, but i hope there are some callback functions), then store them, and somehow propagate them through an API (maybe register a callback, or a poll mechanism). |
I went through some other libraries that implement this functionality (ble [Python] and ruby-ble [Ruby]) and there doesn't seem to be a consensus on how to do this. The Python library pipes notification to the characteristic's value attribute and encourages the use of a loop to read them (I could be wrong here since my Python knowledge is not the best). While the Ruby library uses lambdas attached to DBus signal callbacks. From snooping around dbus-rs I see that signals are supported (at least it says so in the readme) and there is an example of how to use them. I think it's possible to implement something similar in interface and functionality to the Ruby library using closures in Rust. To be a bit more specific. We could add a function like @dati91 You opinion? |
Sounds promising! |
I have started working on this, and have successfully read from a pub fn acquire_notify<F>(&self, func: F) -> Result<()>
where F: FnOnce(u16, OwnedFd)
{
let c = Connection::get_private(BusType::System)?;
let mut m = Message::new_method_call(
SERVICE_NAME,
&self.object_path,
GATT_CHARACTERISTIC_INTERFACE,
"AcquireNotify"
)?;
let reply = c.send_with_reply_and_block(m, 1000)?;
let (opt_fd, opt_mtu) = reply.get2::<OwnedFd, u16>();
func(opt_mtu.unwrap(), opt_fd.unwrap());
Ok(())
} paired with something like this: // UGLY PROTOTYPE
println!("{:?}", charac.acquire_notify(
|mtu, ofd| {
println!("{:?}", mtu);
println!("{:?}", ofd);
use std::fs::File;
let mut buf = [0u8; 512];
// TODO, don't leak fd
let fd = ofd.into_fd();
for i in 0..5 {
thread::sleep(Duration::from_millis(1500));
if let Ok(num_read) = read(&fd, &mut buf[..]) {
let hbs = buf.iter()
.take(num_read)
.map(|b| format!("{:02X}", b))
.collect::<Vec<_>>();
println!("PING: {:?}", hbs);
} else {
println!(":(");
}
}
}
));
fn read(fd: &RawFd, buf: &mut [u8]) -> Result<usize> {
use libc::c_void;
let ret = unsafe {
libc::read(fd.clone(),
buf.as_mut_ptr() as *mut c_void,
buf.len())
};
if ret < 0 {
println!("{:?}", ret);
bail!("Fail")
} else {
Ok(ret as usize)
}
} which gives me this:
I'm working on some other stuff first, and right now this still requires periodic polling of the file descriptor, but it's a good proof of concept :) Hopefully I can clean this up to a better interface, and contribute it back sooner than later. |
Also as a note, this requires BlueZ 5.46 or above, and at least on 5.46, this requires you to set the |
@jamesmunns Have you had time to look further into this issue? Do you know another workaround or can you make a PR? |
Hey @denysvitali, I didn't end up going further with this project, so the comment I left before is basically as far as I got. |
in #21 you could use |
Has there been any more work on this? My use case also relies on BLE notifications. |
see #21, GATT notifications work |
Hi!
I'm working on a project on the RPi that connects to an Arduino using Bluetooth. I'm using the HM11 BLE chip on the Arduino side. That chip, for some reason, insists on communicating using notifications. When I try to read a value using
read_value
i just get gibberish (always this exact stringÈý� �lÄ
or as bytes[200, 253, 25, 130, 108, 196]
).I went through the source and noticed the
start_notify
andstop_notify
methods. Though I can't figure out how to use them. Any pointers? Are they implemented at all?Also, pardons for asking a question here. I didn't find any guide which outlines the desired method for asking questions about the project.
The text was updated successfully, but these errors were encountered: