Notification subscription fails

Hi,

I'm using the nRF Connect for VS Code with SDK version 1.8.0. 

Working with one custom PCB with nRF52840 as the peripheral and another custom PCB with nRF52840 as the central. I have also tried with the nRF52840-DK with the same result as custom HW.

Currently the peripheral has one custom service with 6 characteristics. When I, from the nRF Connect app, enable notifications on all the characteristics I get updated data as expected.

Now I want to implement the service client on the central side. I have looked into hrs_client.c and enable notifications with the bt_gatt_subscribe() function as in the following code from the

bt_hrs_client_measurement_subscribe function:
params->ccc_handle = hrs_c->measurement_char.ccc_handle;
params->value_handle = hrs_c->measurement_char.handle;
params->value = BT_GATT_CCC_NOTIFY;
params->notify = on_hrs_measurement_notify;

atomic_set_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

err = bt_gatt_subscribe(hrs_c->conn, params);
if (err) {
	atomic_clear_bit(&hrs_c->state, HRS_MEASUREMENT_NOTIFY_ENABLED);
	LOG_ERR("Subscribe to Heart Rate Measurement characteristic failed");
} else {
		LOG_DBG("Subscribed to Heart Rate Measurement characteristic");
}




When attempting to subscribe to all 6 characteristics in my custom service it fails at the fourth call to bt_gatt_subscribe(). No matter which combination of characteristics I enable notifications for it works for the first 3 and data is also being notified. 
Looking into what fails it seems to be allocation of memory:

bt_gatt_subscribe() -> 
gatt_write_ccc() ->
gatt_req_send() ->
gatt_req_alloc() ->
bt_att_req_alloc() ->
k_mem_slab_alloc()

The last function checks if (slab->free_list != NULL)  and ends in the else function which fails:

	if (slab->free_list != NULL) {
		// CODE REMOVED
	} else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT) ||
		   !IS_ENABLED(CONFIG_MULTITHREADING)) {
		// CODE REMOVED
	} else {
		SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_mem_slab, alloc, slab, timeout);

		/* wait for a free block or timeout */
		result = z_pend_curr(&slab->lock, key, &slab->wait_q, timeout);
		if (result == 0) {
			*mem = _current->base.swap_data;
		}

		SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mem_slab, alloc, slab, timeout, result);

		return result;
	}
	
	

I have tried adjusting the following configs which didn't make it work:

CONFIG_HEAP_MEM_POOL_SIZE
CONFIG_MAIN_STACK_SIZE
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE

This is only the first service - I have requirements of having notification enabled for several other characteristics in other services.

I hope you have a solution to fix this.

Best regards,

Annette

Parents Reply Children
No Data
Related