ARMmbed / mbed-os-example-ble

BLE demos using mbed OS and mbed cli
Apache License 2.0
133 stars 117 forks source link

BLE_GattServer_AddService does not work on NRF52-DK #351

Open apcurtiss opened 3 years ago

apcurtiss commented 3 years ago

Description of defect

This looks a lot like issue #339, which I'm not sure was resolved. I've updated here with any new details:

The BLE_GattServer_AddService example compiles ok. However when using a BLE scanner and then connecting to the "Heartrate" device it disconnects unexpectedly, immediately after establishing a connection.

I added a disconnect reason printout to the disconnect callback and the error is as was reported in the initial bug report (0x08, timeout).

The nrf connect log says:

Connected.
Discovering Services...
peripheral.discoverServices(nil)
[Callback] centralManager(central, didDisconnectPeripheral: peripheral, error: The connection has timed out unexpectedly.)

Target(s) affected by this defect ?

NRF52_DK

Toolchain(s) (name and version) displaying this defect ?

GCC_ARM

What version of Mbed-os are you using (tag or sha) ?

mbed-os-6.6.0

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli 1.10.4 (macintosh) nrf connect 2.4.6 (iOS) iPhone 11 (iOS 14.3)

How is this defect reproduced ?

compile BLE_GattServer_AddService with mbed-cli and drag resulting .hex file to the NRF52_DK Jlink connection. Use NRF Connect to connect with Heartrate device. Will disconnect immediately.

ciarmcom commented 3 years ago

Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers. Internal Jira reference: https://jira.arm.com/browse/IOTOSM-3156

paul-szczepanek-arm commented 3 years ago

I notice it's also an iphone. Any chance I could have some more logs? Ideally something lower level, from ios or failing that if you could print the connection params from mbed side. From this amount of information it's hard to say what could cause a timeout. Do you have the mbed device connected via serial to make sure the application is running OK there?

apcurtiss commented 3 years ago

True. Sure, good idea--here are some logs from my iPhone. Noticing that the device began advertising again after "Exchange MTU Request", and timeout occurs shortly after that. I suppose the question is why does the device begin advertising again?

Heartrate iOS Logs.txt

paul-szczepanek-arm commented 3 years ago

If it starts advertising it means it thinks the other side disconnected, can you print the disconnect reason on the mbed board?

apcurtiss commented 3 years ago

Yes! I've already done that in fact, it's 0x08 (timeout), same as in the other issue.

pan- commented 3 years ago

@apcurtiss What surprises me is it disconnects after sending an MTU request and the MTU size requested by the mobile is 527. The maximum is supposed to be 517...

Which model of iPhone do you use ?

apcurtiss commented 3 years ago

@pan- Hm interesting... It's an iPhone 11 running iOS 14.3.

pan- commented 3 years ago

It works fine on iPhone 8 😭 and Mac. Would it be possible for you to put traces in attsProcMtuReq and tell us if the server is trying to send an error, What is the size of the local MTU computed and if the allocation of the response fail or not. Then post the result in this thread.

apcurtiss commented 3 years ago

Sure thing. And for what it's worth in the meantime, here are the phone logs from the BLE_GattServer_CharacteristicUpdates program, which does work with my iPhone.

GattServer_CharacteristicUpdates BLE Logs.txt

pan- commented 3 years ago

That's a long shot but can you try to enable LL_OP_MODE_FLAG_SLV_DELAY_LLCP_STARTUP ?

apcurtiss commented 3 years ago

That didn't seem to change things ^

Regarding attsProcMtuReq, most of the time the device doesn't actually seem to be hitting that function. Rarely it will, and this is what I saw when it did:

image

The logs from the iPhone show this (first when there is no MTU response, next when there is).

Heartrate MTU Response Log.txt

Presumably it isn't related to the MTU response and it just happens to fail around then?

apcurtiss commented 3 years ago

^^ just to clarify, when it was hit the attProcMtuReq function completed successfully and didn't try to send an error out.

pan- commented 3 years ago

Thanks for trying @apcurtiss , these are difficult problems to solve without the hardware available to reproduce them. Both ends reporting a timeout as the disconnection reason is surprising to me, as well as the Characteristic update example working and not the hearthrate one.

Are you experiencing incorrect behavior on other examples ?

ghost commented 3 years ago

I can replicate this on an android based phone with another nrf52832 based board. EDIT: I was able to connect with the GattServer_CharacteristicUpdates example.

ghost commented 3 years ago

I ended up finding this issue because I had the exact same problem with my own service, so i figured I'd start with the upstream examples to figure out if the problem was similar.

I migrated my own code to use mbed-ble-utils ble_process.h (with the queue dispatch_forever call commented out and now it works again.

I wonder if it has to do with advertising handle code.

gap.setAdvertisingPayload(ble::LEGACY_ADVERTISING_HANDLE, _adv_data_builder.getAdvertisingData()); vs: gap.setAdvertisingPayload(_adv_handle, _adv_data_builder.getAdvertisingData());