Hello, I have an nrf52840 which is acting as a central. I have a peripheral device which I can connect to, and the service that is discovered has the following table:
ATT[1]: UUID: 0x2803 Handle: 0x001B Value:
Characteristic: 0x291bed1a-6e3e-11ec-90d6-0242ac120003 Properties: 0x0008
ATT[2]: UUID: 0x291bed1a-6e3e-11ec-90d6-0242ac120003 Handle: 0x001C Value:
ATT[3]: UUID: 0x2803 Handle: 0x001D Value:
Characteristic: 0x2d99de42-6e3e-11ec-90d6-0242ac120003 Properties: 0x0012
ATT[4]: UUID: 0x2d99de42-6e3e-11ec-90d6-0242ac120003 Handle: 0x001E Value:
ATT[5]: UUID: 0x2902 Handle: 0x001F Value:
CCCD
The peripheral uses the characteristic 291bed1a-6e3d-11ec-90d6-0242ac120003 as a way to receive commands, and then uses the notification characteristic 2d99de42-6e3d-11ec-90d6-0242ac120003 to send a response to the central that is subscribed to notifications. I've studied the nRF Connect examples (central_gatt_write, peripheral_gatt_write) but I have not been able to subscribe and receive responses from the peripheral.
Here is the code that I am using to subscribe:
subscribe_params.notify = notify_func; subscribe_params.value = BT_GATT_CCC_NOTIFY; subscribe_params.ccc_handle = 0x001E; int err = bt_gatt_subscribe(context, &subscribe_params); if (err && err != -EALREADY) { printk("Subscribe failed (err %d)\n", err); } else { printk("[SUBSCRIBED]\n"); write_cmd(context); }
and here is the code for write_cmd:
int write_cmd(struct bt_conn *conn) { static uint8_t data[BT_ATT_MAX_ATTRIBUTE_LEN] = {0x50, 0x4e, 0x47, 0x0A}; static uint16_t data_len; uint16_t data_len_max; int err; data_len_max = bt_gatt_get_mtu(conn) - 3; if (data_len_max > BT_ATT_MAX_ATTRIBUTE_LEN) { data_len_max = BT_ATT_MAX_ATTRIBUTE_LEN; } data_len = data_len_max; /* Pass the 16-bit data length value (instead of reference) in * user_data so that unique value is pass for each write callback. * Using handle 0x0001, we do not care if it is writable, we just want * to transmit the data across. */ err = bt_gatt_write_without_response_cb(conn, 0x001C, data, data_len, false, write_cmd_cb, (void *)((uint32_t)data_len)); if (err) { printk("%s: Write cmd failed (%d).\n", __func__, err); } return err; }
The subscribe seems to succeed but the notification callback never gets called when I do write_cmd. What am I doing wrong? Am I using the wrong handles? I'm happy to provide a more complete code example if necessary. I'll also mention that I've demonstrated that the peripheral works properly with other frameworks, so I'm certain it's that I'm doing something wrong with the nrf52840 code.
Thank you,
Brock