I'm creating a simple service and client application with two nRF52840 DKs that resembles the central_hr_codes nrf sample, but instead it's a custom service and characteristic that the client subscribes to.
I'm having trouble on the client side, specifically in the notify value callback as defined in the bt_gatt_subscribe_params struct.
I've successfully connected, discovered, and subscribed to my custom characteristic. But when the notify_process callback is called, I get a BUS fault when the program tries to call the actual notify callback in main. Similar to line 23 in the on_hrs_measurement_notify function below.
static uint8_t on_hrs_measurement_notify(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
int err;
struct bt_hrs_client *hrs_c;
struct bt_hrs_client_measurement hr_measurement;
hrs_c = CONTAINER_OF(params, struct bt_hrs_client, measurement_char.notify_params);
if (!data) {
atomic_clear_bit(&hrs_c->state, HRS_MEASUREMENT_NOTIFY_ENABLED);
LOG_DBG("[UNSUBSCRIBE] from Heart Rate Measurement characterictic");
return BT_GATT_ITER_STOP;
}
LOG_HEXDUMP_DBG(data, length, "[NOTIFICATION] Heart Rate Measurement: ");
err = hrs_measurement_data_parse(&hr_measurement, data, length);
if (hrs_c->measurement_char.notify_cb) {
hrs_c->measurement_char.notify_cb(hrs_c, &hr_measurement, err);
}
return BT_GATT_ITER_CONTINUE;
}
Obviously I'm implementing this incorrectly. Here's my client objects defined (paging client).
typedef void (*bt_pag_notify_cb)(struct bt_pag_client *pag,
uint8_t page_alert);
struct bt_page_alert_charcteristic {
struct bt_gatt_subscribe_params notify_params;
/** Notify callback. */
bt_pag_notify_cb notify_cb;
/** Properties of the service. */
uint8_t properties;
uint16_t ccc_handle;
/** handle of the page alert value*/
uint16_t val_handle;
};
/** @brief Paging Client instance. */
//TODO add property that IDs which device sent the page alert
struct bt_pag_client {
/** Connection handle. */
struct bt_conn *conn;
struct bt_page_alert_charcteristic page_chrc;
/** Notification supported. */
bool notify;
};
This is my implementation of the notify value callback.
static uint8_t notify_process(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length)
{
//test byte to forward to main when notified
uint8_t byte = 0x01;
struct bt_pag_client *pag_c;
pag_c = CONTAINER_OF(params, struct bt_pag_client, page_chrc.notify_cb);
//Parse the data
if (pag_c->page_chrc.notify_cb) {
pag_c->page_chrc.notify_cb(pag_c, byte);
}
return BT_GATT_ITER_CONTINUE;
}
Where line 13 above is causing this error
E: ***** BUS FAULT ***** E: Instruction bus error E: r0/a1: 0xffffffe5 r1/a2: 0x00000001 r2/a3: 0x00000000 E: r3/a4: 0x9920003c r12/ip: 0x2000261c r14/lr: 0x0004bab3 E: xpsr: 0x20000000 E: Faulting instruction address (r15/pc): 0x9920003c E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0 E: Current thread: 0x20001ce0 (BT RX)
After a lot of trouble shooting I'm still at a loss. I've tried increasing the BT_RX stack size to 8192 and eliminating the arguments passed to the notify callback. When no arguments are passed, I get an MPU fault in the same thread.
Any help would be appreciated!
Thanks
Sam