embassy-rs / nrf-softdevice

Apache License 2.0
256 stars 76 forks source link

Connecting with 2M PHY #202

Closed kext closed 8 months ago

kext commented 8 months ago

As far as I can tell it is currently not implemented to switch the BLE PHY after connecting as a central.

I want to implement this but there are a few different ways this could be made:

  1. Just try upgrading to the 2M PHY after connecting.
  2. Add a new parameter to ConnectConfig to specify the desired PHY.
  3. Use the secondary_phy field from ScanConfig.
  4. Add a new method to Connection to change PHY.

I have currently implemented option 1 as a proof of concept. But this would not make it possible to connect with the coded PHY instead. Also I am not sure if there are downsides to this. The 2M PHY should consume less power due to shorter radio time but I am not sure if the range is affected.

Option 2 would break the current interface.

Option 3 would probably have the lowest impact on existing users. If you are already listening for extended advertisements with a different secondary PHY, it seems likely you would also want to use that for the actual connection. It is likely though that extended advertising uses the 1M PHY and the device can still support the 2M PHY.

Option 4 would be the most flexible.

I have not fully grasped yet how the coded PHY works in terms of advertisements and connecting. There does not seem to be a way for the Softdevice to directly connect using the coded PHY. Is that even possible in general? It feels like it should be possible to directly connect on the coded PHY, otherwise you would need to be close for the start of the connection and could only then increase the distance instead of connecting to a far away device.

Dirbaio commented 8 months ago

You can directly connect on Coded PHY if you set the peripheral to advertise on Coded, and the central to scan on Coded. The established connection "inherits" the phy from the advertisement.

I'm not sure about 2M. If it's possible to advertise on 2M, you can probably do the same. If not, then I'd say the way to go is to change the PHY after connecting...?

kext commented 8 months ago

So according to ble_gap_scan_params_t::scan_phys when you include the 2M PHY it will still use the 1M PHY for the primary advertisements and use the 2M PHY only if the primary advertisement packet indicates an extended advertisement using that PHY on one of the data channels. Also using 2M as primary_phy is not allowed according to ble_gap_adv_params_t::primary_phy.

I also realise now I got mixed up in the ble::peripheral::Config and the ble::central::ScanConfig. While the former has primary_phy: Phy and secondary_phy: Phy, the latter only has phys: PhySet.

In that case it would probably be appropriate to just call sd_ble_gap_phy_update after the connection is established, at least if phys includes the 2M PHY. What do you think?

I will prepare a pull request!

sureshjoshi commented 8 months ago

I had always thought that you can't advertise on the primary channel using 2M. But I'll concede that I have never looked this up in the spec.

From NovelBits: https://novelbits.io/bluetooth-5-speed-maximum-throughput/

Bluetooth 5 speed: 2x speed utilizing the new 2M PHY
It is useful to understand the limitations of using the new LE 2M PHY in Bluetooth 5:

Cannot be used to transmit the primary advertisements (on the primary channels).

Can be used for the secondary “auxiliary packets” sent on the same channels as the data packets (37 channels: 0-36).
To learn more about primary and secondary advertisements, refer to my previous blog post: [Bluetooth 5 Advertisements: Everything you need to know](http://www.novelbits.io/bluetooth-5-advertisements/).

LE 1M is mandatory, whereas LE 2M is optional. So, not all chipsets claiming Bluetooth 5 support can necessarily handle the higher throughput.

Advertisements and discovery can occur on the LE 1M PHY, and then connections occur on the secondary advertisement channel using the LE 2M PHY
kext commented 8 months ago

Implemented in #203.