zephyr icon indicating copy to clipboard operation
zephyr copied to clipboard

samples: bluetooth: Add sample demonstrating direct advertising

Open morsisko opened this issue 2 years ago • 6 comments

This sample shows how to run BLE direct advertising towards central with enabled privacy.

On each boot application checks whether any bond exists. If not - it starts casual advertising. After pairing reboot is performed. If bond exists application starts direct advertising towards previously bonded central with enabled privacy.

Additionally the application has got one service with two characteristics, one for reading and another for encrypted writing (and thus it requires devices to be paired)

The sample was tested with EBYTE-TBB board featuring nRF52832 MCU. The central device was modern smartphone with Android >=7.0

morsisko avatar Sep 18 '22 20:09 morsisko

Hi @morsisko I tried the sample again today on my custom nRF52840 board sporting a Raytac MDBT50Q.

The issue I'm reporting may be limited to the fact that I'm testing on iPhone, or the specific board, but for what it is worth here is my experience:

Using my iphone I use the nRF Connect app to locate the device, then I pair to it by writing to the characteristic. Within Ozone it is apparent that the bond is stored and the device reboots.

After reboot, Ozone outputs that there is targeted advertising occurring, however nRF Connect can no longer connect to it nor can it find it again when scanning.

Perhaps this works better with two nRF52 devices rather than an iPhone (maybe iPhone does not support targeted advertisement?). Just some speculation for what it's worth. Anyway if you'd like me to try anything specific on my hardware please let me know and I will gladly try. I do have a few more of these devices that I can try together, and will be getting my hands on an Android device later this week and plan to try this again at that time.

Thanks!

image

kfatehi avatar Sep 20 '22 07:09 kfatehi

Hi @kfatehi

What iPhone is it? Not sure about iOS and BLE privacy. You could try to comment out this line: adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; and check if it works.

It looks like some devices not fully support this feature, for example:

  • On Xiaomi Redmi 4X, once other device starts direct advertising, nRF Connect app no longer can discover other peripherals. However if you press "Connect" in the "Bond" tab, connection will be successful
  • On Xiaomi Mi 9T, device that direct advertise is not visible in "Scanner" tab in nRF Connect app, however if you press "Connect" in the "Bond" tab, connection will be successful.

Unfortunately I don't own modern iPhone. I've got one iPhone 5S somewhere, but I'm afraid it might be too old. It would be nice if you could test other non-zephyr solution with your board. If direct advertising would work in that case, this probably mean that the problem is inside Zephyr itself. In this situation I recommend to file separate issue (unless someone can point what is wrong with this sample), so people with knowledge about Zephyr BLE internals can take a look.

morsisko avatar Sep 20 '22 20:09 morsisko

@morsisko I am using an iPhone 12 Mini. I tried removing BT_LE_ADV_OPT_DIR_ADDR_RPA but it did not make a difference. I tried a few other variations around advertising params, such as those I found in the SDK in other samples, and in other discussions, such as also setting CONFIG_BT_CTLR_PRIVACY=y . As a layman judging the output on the RTT terminal, it makes sense to me that the address being printed saying "public" could indicate some root of the problem as in perhaps there is some translation that is required insofar that it must be resolved to the "real" address. Anyway needless to say I am lost and giving up for now. I am overwhelmed with too much seemingly contradictory and confusing information on the topic, but I will try again after receiving my Android device (Samsung S10e). Notes and links follow:

  • Apple forum posts indicating similar issues https://developer.apple.com/forums/thread/71791 https://developer.apple.com/forums/thread/706889
  • Similar discussions around RPA, but on Espressif's forums https://github.com/espressif/esp-nimble/issues/8 in which they apparently seem to fix the issue in a subsequent patch to their SDK
  • Similar problem (and where I found the other config flag) on Zephyr project https://github.com/zephyrproject-rtos/zephyr/issues/14743 -- if I understand correctly, the problem isn't really solved, instead we see effort going into a workaround (whitelisting the bonded peers?) which leads to a fix in that area. This discussion is interesting in that there is a mention of nRF5 SDK using this workaround:

In nRF5 SDK based HID peripherals we solved this by using undirected advertising with whitelist towards centrals that had privacy enabled (typically iOS and Android) and directed advertsing towards windows centrals. It is a while since then and I am not sure how peripiheral privacy will affect this.

This seems to be consistent with the seemingly arbitrary limitation in Apple's acessory design guidelines (linked in one of the apple forum posts)

image

It's weird to me that Apple says not to use it, doesn't say why, and then says to look at the spec as though the spec will indicate why, but when I look at the spec I don't see any reason why "not to use it" -- now I don't know if this is even relevant or is what the direct advertising in this sample is using, considering how old it is, but the whole situation is confusing.

image

To make matters worse, I borrowed an Android phone from a family member as a hail mary attempt to prove that Apple is broken in some way, but I had the same exact behavior, so I'm throwing my hands up for now.

kfatehi avatar Sep 21 '22 05:09 kfatehi

@kfatehi I had a look, and it seems you're right, this is a limitation only for apple devices, you pretty much can't use directed advertising. @morsisko Could you add a warning for iOS users saying that this sample will not work with their devices and that they should always use undirected (standard) advertising, citing the accessory guidelines?

On my oneplus 5T (stock android 10), I can confirm that it works:

  • flash device
  • a device called "Direct Adv" shows up in nRF connect scanner tab
  • connect & bond
  • logs on UART say "device rebooting in 5 seconds"
  • logs on UART say "Direct advertising to 94:65:2D:39:7C:EA (public)"
  • can't see the device in the scanner tab any more
  • hitting "connect" in the (previously opened) device tab successfully connects to it

jori-nordic avatar Sep 21 '22 05:09 jori-nordic

Just to add some more info:

This sample as-is will indeed not work on some peers that use bt privacy. In that case, one can as you said @kfatehi use normal advertising + accept list to restrict who can connect.

I can confirm that directed adv + BT_LE_ADV_OPT_DIR_ADDR_RPA as used in this sample works with the zephyr bluetooth shell (that has privacy enabled). Caveat is that we should have prior knowledge that the peer supports this, so this is a bit more hit-and-miss.

jori-nordic avatar Sep 21 '22 06:09 jori-nordic

@jori-nordic

Is such warning ok, or do you want to modify something?:

Please note that direct advertising towards iOS based devices is not possible. For more information about designing BLE devices for Apple products refer to "Accessory Design Guidelines for Apple Devices"

morsisko avatar Sep 21 '22 20:09 morsisko

@jori-nordic

Is such warning ok, or do you want to modify something?:

Please note that direct advertising towards iOS based devices is not possible. For more information about designing BLE devices for Apple products refer to "Accessory Design Guidelines for Apple Devices"

s/possible/allowed and I'm ok with it. Thanks for the sample again!

jori-nordic avatar Sep 22 '22 06:09 jori-nordic

Apple recommendations dates back to Bluetooth 4.0/4.1 and it was not possible to properly handle directed advertising and privacy in those spec versions. So it is likely that this sample will have issues reconnecting with any 4.0 devices (if they use privacy).

To handle this, sample should enable directed advertising using RPA as target addr only if remote central indicated support for this (by having Central Address Resolution characteristic with value 1).

This is from spec: "The Peripheral should check if the peer device supports address resolution by reading the Central Address Resolution characteristic before using directed advertisement where the target address is set to a Resolvable Private Address (RPA)."

As you can see this is not requirement but recommendation (should) but it may be confusing to people if it will work only with some devices and won't with others..

sjanc avatar Sep 23 '22 08:09 sjanc

Thanks for the thorough explanation @sjanc !

jori-nordic avatar Sep 23 '22 09:09 jori-nordic

So should I add this check to the code or leave it as is? In case of adding it, what to do when central doesn't support address resolution? Prevent pairing process? Remove the bond after saving it? Something else?

morsisko avatar Sep 23 '22 09:09 morsisko

Do I understand correctly, that Apple devices will resolve RPAs for non-directed advertisement even if Central Address Resolution feature characteristic is not present? Core spec 5.3 says "If the Central Address Resolution characteristic is not present, then it shall be assumed that Central Address Resolution is not supported."

EDIT: I assume yes. Since the remote accepted the IRK key distribution. I think it implies that "Central Address Resolution" concerns only directed advertising.

So should I add this check to the code or leave it as is? In case of adding it, what to do when central doesn't support address resolution? Prevent pairing process? Remove the bond after saving it? Something else?

I am for merging this PR as is now. But I welcome another PR that modifies the sample to be more real-world like / define the best-practice that real world applications should follow.

EDIT: I think if the Central Address Resolution feature is not available, it would make sense to emulate directed advertising using a connectable, non-scannable advertisement with no data and the highest duty cycle allowed.

There is also the question of what a real-world application should do if a peer does not support privacy at all.

alwa-nordic avatar Sep 23 '22 10:09 alwa-nordic

I agree, we should merge this as-is, else it's just scope creep. This sample clearly says it will use directed advertising. A future PR would be nice ofc, in that case what @alwa-nordic suggests for the "real-world" use-case seems reasonable.

jori-nordic avatar Sep 23 '22 10:09 jori-nordic