Giter VIP home page Giter VIP logo

Comments (12)

dati91 avatar dati91 commented on August 24, 2024

Hi,
Sorry for the late response!
I don't think the start_notify/start_notify will be useful. It should be reworked like the DiscoverySession.
The problem is that we currently drop the session after a call, which is usually fine, but when you try to use something session related, like doing a discovery or in you case using notification, the connection should be kept.
We are planning to do this, but I can't promise that it will be in the near future. Hopefully before the end of this year.

from blurz.

monorkin avatar monorkin commented on August 24, 2024

@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.

from blurz.

dati91 avatar dati91 commented on August 24, 2024

@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).

from blurz.

monorkin avatar monorkin commented on August 24, 2024

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 on_notify which receives a closure as an argument and spawns a detached thread which does something similar to the example from DBus but in a loop.

@dati91 You opinion?

from blurz.

dati91 avatar dati91 commented on August 24, 2024

Sounds promising!
If you need any help with it, just let me know.

from blurz.

jamesmunns avatar jamesmunns commented on August 24, 2024

I have started working on this, and have successfully read from a notify using something like this in bluetooth_characteristic.rs:

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:

Pairing...
"00000001-c001-de30-cabb-785feabcd123"
        "0000c01d-c001-de30-cabb-785feabcd123"
23
OwnedFd { fd: 5 }
PING: ["0E", "00", "00", "00"]
PING: ["0F", "00", "00", "00"]
PING: ["10", "00", "00", "00"]
PING: ["11", "00", "00", "00"]
PING: ["12", "00", "00", "00"]
Ok(())

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.

from blurz.

jamesmunns avatar jamesmunns commented on August 24, 2024

Also as a note, this requires BlueZ 5.46 or above, and at least on 5.46, this requires you to set the --experimental flag for bluetoothd.

from blurz.

denysvitali avatar denysvitali commented on August 24, 2024

@jamesmunns Have you had time to look further into this issue? Do you know another workaround or can you make a PR?

from blurz.

jamesmunns avatar jamesmunns commented on August 24, 2024

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.

from blurz.

bsphere avatar bsphere commented on August 24, 2024

in #21 you could use start_notify, map incoming dbus messages to BluetoothEvent and use BluetoothEvent::Value. (`examples/test5.rs)

from blurz.

visceralfield avatar visceralfield commented on August 24, 2024

Has there been any more work on this? My use case also relies on BLE notifications.

from blurz.

bsphere avatar bsphere commented on August 24, 2024

see #21, GATT notifications work

from blurz.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.