BLE: Client Characteristic Configuration data not read correctly from AppDB
Observed behaviour:
- Connect an Android device, enable notifications for the battery service.
- Observe notifications of the battery state arriving
- Disconnect the Android device
- Restart the card10
- Connect the Android device
- Observe no notifications of the battery state arriving anymore
- Disconnect the Android device
- Connect the Android device
- Observe notifications of the battery state arriving
Desired behaviour:
- Connect an Android device, enable notifications for the battery service.
- Observe notifications of the battery state arriving
- Disconnect the Android device
- Restart the card10
- Connect the Android device
- Observe notifications of the battery state arriving
Investigation:
When opening a connection from an Android device, the stack tries to read persisted CCC data from the AppDB. This data is stored together with other pairing information and is persisted once notifications are enabled for a characteristic by a certain client/connection/bonding.
When a new connection is opened, AppServerConnCback()
in stack/ble-profiles/sources/apps/app/app_server.c
tries to read this information again. It uses AppDbGetHdl(connId)
to resolve the appDbHdl_t
which contains this data. This fails when connecting for the first time as there is no AppDb handle available yet for this connId
.
The mapping of connId
to AppDb handle is held in appConnCb_t appConnCb[DM_CONN_MAX]
which is part of stack/ble-profiles/sources/apps/app/app_main.c
. It looks like it gets updated in stack/ble-profiles/sources/apps/app/app_master.c
and stack/ble-profiles/sources/apps/app/app_slave.c
.
Some function in app_master.c
or app_slave.c
later on updates the mapping. Looks like it is in appSlaveResolvedAddrInd()
as the Android device is using private addresses which first have to be resolved using pairing information (AFAIK). This though happens after consulting the mapping for the CCC data.
Conclusion: It looks like the stack tries to read persisted CCC data before the mapping from connection to AppDb entry has been established. In fact the read is performed on outdated information from the previous connection (possibly being a security issue).
Writing this down to not forget about it and test with an mbed board, using an upstream version of the stack.