Hello,
we are developing a device which implements BLE hid keyboard. The code is based on the hid keyboard example in the NRF Connect SDK.
The example uses battery service (bas.h and bas.c) to notify client about battery level percentage.
The problem is that the battery level is transmitted only when the connection is established. Further calls of bas_notify() from the example do not update the percentage. Obviously Android phone which I use for tests does not subscribe for this notification. The notifications are only received if I actively enable them in the NRF Connect App.
I added configuration parameter `CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION=n` to the prj.conf. Unfortunately this did not solve the problem. After debugging a while I found that the notification process exits on these lines in gatt.c:
static uint8_t notify_cb(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) { ... ... /* Notify all peers configured */ for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) { struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i]; struct bt_conn *conn; int err; /* Check if config value matches data type since consolidated * value may be for a different peer. */ if (cfg->value != data->type) { // this condition is true in my case. cfg->value == 0, data->type == 1 continue; } ...
So for some reason ccc.cfg array contains invalid data.
I have only one connection and the maximum number of connection is configured to be 1.
For now the workaround is to pass the connection to the bt_bas_set_battery_level() function and call bt_gatt_notify() with the known connection, so that gatt_notify is called directly:
int bt_bas_set_battery_level(uint8_t level, struct bt_conn *conn) { int rc; if (level > 100U) { return -EINVAL; } battery_level = level; rc = bt_gatt_notify(conn, &bas.attrs[1], &level, sizeof(level)); if (IS_ENABLED(CONFIG_BT_BAS_BLS_BATTERY_LEVEL_PRESENT)) { bt_bas_bls_set_battery_level(level); } return rc == -ENOTCONN ? 0 : rc; }
This works but changing the SDK files is not the best idea.
The SDK version is 2.9.1. The question is what I'm doing wrong