Skip to content
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

Add possibility to listen to notifications #102

Merged
merged 3 commits into from
Sep 11, 2024
Merged

Conversation

pferreir
Copy link
Contributor

@pferreir pferreir commented Sep 1, 2024

This allows the GattClient to also register to listen to notifications for a Characteristic.

@pferreir pferreir force-pushed the add-notifs branch 3 times, most recently from 885bbc1 to 1e512ab Compare September 1, 2024 19:33
Copy link
Member

@lulf lulf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Looks good in general.

Couple of things:

  • I think maybe it's gonna explode RAM usage storing that Vec<> in the channels. Consider using the PacketPool instead, which should reduce the RAM requirements considerably, because at the moment you risk having a lot of 'unused RAM' from defining the MAX limits.
  • I would also like if you modified the ble_bas_central example to use this.

host/src/gatt.rs Outdated
Comment on lines 162 to 166
const MAX_SERVICES: usize,
const MAX_NOTIF: usize,
const NOTIF_QSIZE: usize,
const L2CAP_MTU: usize = 27,
const ATT_MTU: usize = 23,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are a bit hard to keep in sync. I'd rather just use l2cap_mtu for the vec size to avoid them.

@pferreir
Copy link
Contributor Author

pferreir commented Sep 2, 2024

  • I think maybe it's gonna explode RAM usage storing that Vec<> in the channels. Consider using the PacketPool instead, which should reduce the RAM requirements considerably, because at the moment you risk having a lot of 'unused RAM' from defining the MAX limits.

I think the problem with this is that calls to PacketPool::alloc need to have a static lifetime, and that means I'll have to require &'static self in some of the methods...

@lulf
Copy link
Member

lulf commented Sep 3, 2024

  • I think maybe it's gonna explode RAM usage storing that Vec<> in the channels. Consider using the PacketPool instead, which should reduce the RAM requirements considerably, because at the moment you risk having a lot of 'unused RAM' from defining the MAX limits.

I think the problem with this is that calls to PacketPool::alloc need to have a static lifetime, and that means I'll have to require &'static self in some of the methods...

You'd need to use a StaticCell for the pool, and pass it to the gatt_client when creating, it doesn't mean the gatt client itself must be static, only the Packet, i.e. Packet<'static>. Then it can assume static lifetime of an allocated packet. This is how the l2cap channel manager works (https://github.com/embassy-rs/trouble/blob/main/host/src/channel_manager.rs#L34-L41), where it holds a ref to a 'static pool, but doesn't require itself to be 'static.

There may very well be other pool implementations that is a better fit, but this one is at least already there with no new dependencies needed.

@pferreir
Copy link
Contributor Author

pferreir commented Sep 3, 2024

You'd need to use a StaticCell for the pool, and pass it to the gatt_client when creating

Yeah, I had excluded this because it seemed not very user-friendly. But I've done it and it seems to work.

@pferreir pferreir force-pushed the add-notifs branch 2 times, most recently from 51894f4 to 1a8d8f6 Compare September 4, 2024 13:00
@pferreir
Copy link
Contributor Author

pferreir commented Sep 4, 2024

OK, I think this is more or less what you asked for. I made a design decision which I am not 100% sure of, which is to make the task which handles rx mandatory, so that messages can be triaged and notifications be handled in parallel with regular read/write operations. That also entailed making the service list internally mutable. I created a ble_bas_central example for the rp2040 to demonstrate the concept.
Let me know what you think!

@pferreir pferreir force-pushed the add-notifs branch 3 times, most recently from 8092551 to c7e89c1 Compare September 4, 2024 13:30
@pferreir
Copy link
Contributor Author

pferreir commented Sep 4, 2024

BTW, haven't found anything to test the official example on. I have a device which has a battery service but I don't think it sends any notifications. I know the notification code works because I tested it with a BLE MIDI device I have, but I don't know what to do with the example.

Copy link
Member

@lulf lulf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, let me know if you want to address my inline comment or just go with it as is, I'm fine with either, this should be ready to merge once CI passes.

I agree it's not the ideal user experience having to create the packet pool, but maybe one future improvement would be to utilize the 'config system' (see gen_config.py) and host/src/config.rs to parameterize the pool at build time and keep it 'hidden' rather than having to be passed into the client? It limits how flexible you can configure the options, but otoh maybe that's not needed at this level.

host/src/gatt.rs Outdated
pub(crate) rx: DynamicReceiver<'reference, (ConnHandle, Pdu)>,
pub(crate) ble: &'reference BleHost<'resources, T>,
pub(crate) connection: Connection<'reference>,
pub(crate) request_channel: Channel<NoopRawMutex, (ConnHandle, Pdu), NOTIF_QSIZE>,

pub(crate) notification_pool: &'static PacketPool<NoopRawMutex, L2CAP_MTU, MAX_NOTIF, 1>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to use the &'static dyn GlobalPacketPool to reduce the 'generics hell' 😅 if you want to. This should get rid of L2CAP_MTU and MAX_NOTIF parameters from GattClient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, pushed. But I haven't been able to get rid of those parameters. Otherwise, how do I build the corresponding arrays?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right about the notif const. But the L2CAP_MTU should be removable? I don't see it used anywhere. In any case, I think it's fine to merge.

Just rebase it on latest main and we can merge it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right about the notif const. But the L2CAP_MTU should be removable? I don't see it used anywhere

it's still used in request to build the receive buffer. Anyway, rebased and pushed!

@pferreir pferreir force-pushed the add-notifs branch 2 times, most recently from 197a74b to 2a46e38 Compare September 6, 2024 18:05
@lulf
Copy link
Member

lulf commented Sep 10, 2024

/test

@pferreir
Copy link
Contributor Author

WRT to the test failing, I don't get it how [u8] seems to implement LowerHex in the pico w but not on the desktop?

@lulf
Copy link
Member

lulf commented Sep 10, 2024

This is a defmt vs log issue. You can reproduce by compiling trouble-host with the log feature. Basically the format specifiers that works with defmt doesnt always work with core fmt.

You need to remove that log line or guard it behind a defmt feature gate

@pferreir
Copy link
Contributor Author

Ok, should be fine now!

@lulf
Copy link
Member

lulf commented Sep 10, 2024

/test

@lulf
Copy link
Member

lulf commented Sep 10, 2024

The integration tests fail, you can see the error here https://github.com/embassy-rs/trouble/actions/runs/10798211914/job/29951213402#step:5:153. If you want I can merge it as is and fix the tests after the fact if you're not able to run them yourself (You need 2 HCI dongles). Seems like tests need some increase in the max number of attributes or something.

@pferreir
Copy link
Contributor Author

pferreir commented Sep 10, 2024 via email

@lulf
Copy link
Member

lulf commented Sep 11, 2024

@pferreir Like this: https://github.com/embassy-rs/trouble/blob/main/.github/workflows/tests.yaml#L30-L37

Basically I have a local GHA with 2 HCI dongles attached which run the tests in https://github.com/embassy-rs/trouble/tree/main/host/tests

@lulf lulf merged commit 0e0d942 into embassy-rs:main Sep 11, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants