Potential memory leak issue in NCS GATT Discovery gatt_dm, "No space for a UUID."

Hi,

I'm using the gatt_dm library in NCS v2.2.0 to manage service discovery for a project. The first connection is discovered correctly, without any issue. After that discovery process finishes and the device disconnects, I attempt to reconnect and rediscover services, but I get the error "No space for a UUID," followed by "The discovery procedure failed, err -12".

I'm not sure where I'm going wrong, I'm calling bt_gatt_dm_data_release(dm) and bt_gatt_dm_continue(dm, NULL) any time the discover_completed callback returns. They both report success. Here are a few sections of my code, but I can upload a full example project too if that works better.

static void discover_completed(struct bt_gatt_dm *dm, void *ctx)
{
	char uuid_str[37];

	const struct bt_gatt_dm_attr *gatt_service_attr =
			bt_gatt_dm_service_get(dm);
	const struct bt_gatt_service_val *gatt_service =
			bt_gatt_dm_attr_service_val(gatt_service_attr);

	int err = 0;
	//decide to continue parsing or return
	if(discovery_mode == PAIRING){
		//Check if service is DIS (for serial) or PERIPHERAL (for group #)
		//bt_uuid_cmp returns 0 if match. so, return if !(!dis || !peripheral)
		//ie, dis && peripheral
		if(bt_uuid_cmp(gatt_service->uuid, BT_UUID_DIS) && 
			bt_uuid_cmp(gatt_service->uuid, PERIPHERAL_UUID))
		{
			err = bt_gatt_dm_data_release(dm);
			NOTIFY_IF_ERR(err);
			err = bt_gatt_dm_continue(dm, NULL);
			NOTIFY_IF_ERR(err);
			return;
		}
	}
	if(discovery_mode == GROUP){
		if(bt_uuid_cmp(gatt_service->uuid, PERIPHERAL_UUID)){
			err = bt_gatt_dm_data_release(dm);
			NOTIFY_IF_ERR(err);
			err = bt_gatt_dm_continue(dm, NULL);
			NOTIFY_IF_ERR(err);
			return;
		}
	}
	uint8_t characteristic_arr[] = {0, 0};
	characteristic_arr[1] = characteristic & 0xFF;
	characteristic_arr[0] = characteristic >> 8;
	struct bt_uuid * uuid = CUSTOM_UUID(characteristic_arr[0], characteristic_arr[1]);
	bt_uuid_to_str(uuid, uuid_str, sizeof(uuid_str));
	LOG_DBG("Looking for characteristic %s", uuid_str);

	const struct bt_gatt_dm_attr *attr = NULL;
	while (NULL != (attr = bt_gatt_dm_attr_next(dm, attr))) {
		bt_uuid_to_str(attr->uuid, uuid_str, sizeof(uuid_str));
		LOG_DBG("Found characteristic %s", uuid_str);
		//Check UUIDs and handle their handles accordingly
		if(!bt_uuid_cmp(attr->uuid, SERIAL_UUID)){
			LOG_DBG("Serial UUID detected!");
			serial_handle = attr->handle;
		}
		if(!bt_uuid_cmp(attr->uuid, GROUP_UUID)){
			LOG_DBG("Group UUID detected!");
			group_num_handle = attr->handle;
		}
		if(!bt_uuid_cmp(attr->uuid, uuid)){
			LOG_DBG("Specific characteristic detected!");
			characteristic_handle = attr->handle;
		}
	}

	//Serial read request, followed by group write request, happens when DM is
	//  complete, in discover_service_not_found.
	err = bt_gatt_dm_data_release(dm);
	NOTIFY_IF_ERR(err);
	err = bt_gatt_dm_continue(dm, NULL);
	NOTIFY_IF_ERR(err);
	LOG_DBG("Returning! %d", __LINE__);
}

static void discover_service_not_found(struct bt_conn *conn, void *ctx)
{
	LOG_DBG("Service discovery all done.");
	int err = 0;
	if(discovery_mode == PAIRING){
		serial_read_params.single.handle = serial_handle;
		err = bt_gatt_read(peripheral_conn, &serial_read_params);
	}
	else if(discovery_mode == GROUP){
		if(characteristic_handle == 0xFFFF){
			notify_error_disconnect(controller_conn, -ENOENT, __LINE__);
		}
		err = characteristic_write(conn, characteristic_handle, value, write_characteristic_cb);
	}
	NOTIFY_IF_ERR(err);
}

static void discover_error_found(struct bt_conn *conn, int err, void *ctx)
{
	LOG_ERR("The discovery procedure failed, err %d\n", err);
}

static struct bt_gatt_dm_cb discover_serial_cb = {
	.completed = discover_completed,
	.service_not_found = discover_service_not_found,
	.error_found = discover_error_found,
};

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
	LOG_INF("Connected!");
	if(conn == peripheral_conn){
		if(conn_err){
			LOG_ERR("Connection failed: %d",conn_err);
			bt_conn_unref(peripheral_conn);
			peripheral_conn = NULL;
			bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
			return;
		}
		// ie, peripheral device - start discovery of serial number.
		int err = bt_gatt_dm_start(conn, NULL, &discover_serial_cb, NULL);
		NOTIFY_IF_ERR(err);
	}
	else{
		if(conn_err){
			LOG_ERR("Connection failed: %d",conn_err);
			bt_conn_unref(controller_conn);
			controller_conn = NULL;
			return;
		}
		controller_conn = bt_conn_ref(conn);
	}
}

I also changed the gatt_dm log level to DBG, and put a few print statements in uuid_store to see what addresses it's allocating for the UUID buffer. I noticed that the pointers only increase and don't reset with the new connection, making me think k_free isn't being called where it should be.

I: Filters matched. Address: F64171FB4147, connectable: yes, mode: 2
I: Connected!
D: Attr: handle 1
D: Attr store, pos: 0, handle: 1
D: Service detected, handles range: <2, 9>
D: Size: 4
D: Buffer: 536904496
D: Starting descriptors discovery
D: Attr: handle 2
D: Attr store, pos: 1, handle: 2
D: Attr: handle 3
D: Attr store, pos: 2, handle: 3
D: Attr: handle 4
D: Attr store, pos: 3, handle: 4
D: Attr: handle 5
D: Attr store, pos: 4, handle: 5
D: Attr: handle 6
D: Attr store, pos: 5, handle: 6
D: Attr: handle 7
D: Attr store, pos: 6, handle: 7
D: Attr: handle 8
D: Attr store, pos: 7, handle: 8
D: Attr: handle 9
D: Attr store, pos: 8, handle: 9
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 2
D: Size: 4
D: Buffer: 536904564
D: Attr: handle 4
D: Size: 4
D: Buffer: 536904568
D: Attr: handle 6
D: Size: 4
D: Buffer: 536904572
D: Attr: handle 8
D: Size: 4
D: Buffer: 536904576
D: NULL attribute
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 10
D: Attr store, pos: 0, handle: 10
D: Empty service detected with handle: 10
D: Size: 4
D: Buffer: 536904496
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 11
D: Attr store, pos: 0, handle: 11
D: Service detected, handles range: <12, 14>
D: Size: 4
D: Buffer: 536904496
D: Starting descriptors discovery
D: Attr: handle 12
D: Attr store, pos: 1, handle: 12
D: Attr: handle 13
D: Attr store, pos: 2, handle: 13
D: Attr: handle 14
D: Attr store, pos: 3, handle: 14
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 12
D: Size: 17
D: Buffer: 536904536
D: NULL attribute
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 15
D: Attr store, pos: 0, handle: 15
D: Service detected, handles range: <16, 42>
D: Size: 17
D: Buffer: 536904496
D: Starting descriptors discovery
D: Attr: handle 16
D: Attr store, pos: 1, handle: 16
D: Attr: handle 17
D: Attr store, pos: 2, handle: 17
D: Attr: handle 18
D: Attr store, pos: 3, handle: 18
D: Attr: handle 19
D: Attr store, pos: 4, handle: 19
D: Attr: handle 20
D: Attr store, pos: 5, handle: 20
D: Attr: handle 21
D: Attr store, pos: 6, handle: 21
D: Attr: handle 22
D: Attr store, pos: 7, handle: 22
D: Attr: handle 23
D: Attr store, pos: 8, handle: 23
D: Attr: handle 24
D: Attr store, pos: 9, handle: 24
D: Attr: handle 25
D: Attr store, pos: 10, handle: 25
D: Attr: handle 26
D: Attr store, pos: 11, handle: 26
D: Attr: handle 27
D: Attr store, pos: 12, handle: 27
D: Attr: handle 28
D: Attr store, pos: 13, handle: 28
D: Attr: handle 29
D: Attr store, pos: 14, handle: 29
D: Attr: handle 30
D: Attr store, pos: 15, handle: 30
D: Attr: handle 31
D: Attr store, pos: 16, handle: 31
D: Attr: handle 32
D: Attr store, pos: 17, handle: 32
D: Attr: handle 33
D: Attr store, pos: 18, handle: 33
D: Attr: handle 34
D: Attr store, pos: 19, handle: 34
D: Attr: handle 35
D: Attr store, pos: 20, handle: 35
D: Attr: handle 36
D: Attr store, pos: 21, handle: 36
D: Attr: handle 37
D: Attr store, pos: 22, handle: 37
D: Attr: handle 38
D: Attr store, pos: 23, handle: 38
D: Attr: handle 39
D: Attr store, pos: 24, handle: 39
D: Attr: handle 40
D: Attr store, pos: 25, handle: 40
D: Attr: handle 41
D: Attr store, pos: 26, handle: 41
D: Attr: handle 42
D: Attr store, pos: 27, handle: 42
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 16
D: Size: 17
D: Buffer: 536905000
D: Attr: handle 18
D: Size: 17
D: Buffer: 536905020
D: Attr: handle 20
D: Size: 17
D: Buffer: 536905040
D: Attr: handle 22
D: Size: 17
D: Buffer: 536905060
D: Attr: handle 24
D: Size: 17
D: Buffer: 536905080
D: Attr: handle 26
D: Size: 17
D: Buffer: 536905124
D: Attr: handle 28
D: Size: 17
D: Buffer: 536905144
D: Attr: handle 30
D: Size: 17
D: Buffer: 536905164
D: Attr: handle 32
D: Size: 17
D: Buffer: 536905184
D: Attr: handle 34
D: Size: 17
D: Buffer: 536905204
D: Attr: handle 36
D: Size: 17
D: Buffer: 536905252
D: Attr: handle 38
D: Size: 17
D: Buffer: 536905272
D: Attr: handle 40
D: Size: 17
D: Buffer: 536905292
D: NULL attribute
D: Discovery complete.
D: Looking for characteristic 00000000-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001522-5948-4f3b-9e29-95c3322d9d6c
D: Group UUID detected!
D: Found characteristic 2803
D: Found characteristic 00001526-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001527-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001528-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152a-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152b-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152c-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152d-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152e-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 0000152f-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001529-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001530-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 00001531-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2902
D: Attr memory release
D: Returning! 341
D: Attr: handle 43
D: Attr store, pos: 0, handle: 43
D: Service detected, handles range: <44, 65535>
D: Size: 4
D: Buffer: 536904496
D: Starting descriptors discovery
D: Attr: handle 44
D: Attr store, pos: 1, handle: 44
D: Attr: handle 45
D: Attr store, pos: 2, handle: 45
D: Attr: handle 46
D: Attr store, pos: 3, handle: 46
D: Attr: handle 47
D: Attr store, pos: 4, handle: 47
D: Attr: handle 48
D: Attr store, pos: 5, handle: 48
D: Attr: handle 49
D: Attr store, pos: 6, handle: 49
D: Attr: handle 50
D: Attr store, pos: 7, handle: 50
D: Attr: handle 51
D: Attr store, pos: 8, handle: 51
D: Attr: handle 52
D: Attr store, pos: 9, handle: 52
D: Attr: handle 53
D: Attr store, pos: 10, handle: 53
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 44
D: Size: 4
D: Buffer: 536904580
D: Attr: handle 46
D: Size: 4
D: Buffer: 536904584
D: Attr: handle 48
D: Size: 4
D: Buffer: 536904588
D: Attr: handle 50
D: Size: 4
D: Buffer: 536904592
D: Attr: handle 52
D: Size: 4
D: Buffer: 536904596
D: NULL attribute
D: Discovery complete.
D: Looking for characteristic 00000000-5948-4f3b-9e29-95c3322d9d6c
D: Found characteristic 2803
D: Found characteristic 2a29
D: Found characteristic 2803
D: Found characteristic 2a24
D: Found characteristic 2803
D: Found characteristic 2a25
D: Serial UUID detected!
D: Found characteristic 2803
D: Found characteristic 2a27
D: Found characteristic 2803
D: Found characteristic 2a26
D: Attr memory release
D: Discover complete. No service found.
D: Attr memory release
D: Service discovery all done.
D: Returning! 341
D: Received serial number P-L2C-000000001 on address F64171FB4147
I: Stored new serial mapping.
I: Group number sent.
I: Disconnected: (reason 22)
I: Disconnected from peripheral.
D: Setting PSR value to 0x1
I: Disconnected: (reason 22)
I: Disconnected from controller.
W: opcode 0x200a status 0x09

// Here is where the second connection attempt starts.
I: Connected!
I: Running packet_rx_cb...
I: Packet received!

D: PAIRING packet contents: Address F64171FB4147, group num 1
I: Filters matched. Address: F64171FB4147, connectable: yes, mode: 2
I: Connected!
D: Attr: handle 1
D: Attr store, pos: 0, handle: 1
D: Service detected, handles range: <2, 9>
D: Size: 4
D: Buffer: 536904608
D: Starting descriptors discovery
D: Attr: handle 2
D: Attr store, pos: 1, handle: 2
D: Attr: handle 3
D: Attr store, pos: 2, handle: 3
D: Attr: handle 4
D: Attr store, pos: 3, handle: 4
D: Attr: handle 5
D: Attr store, pos: 4, handle: 5
D: Attr: handle 6
D: Attr store, pos: 5, handle: 6
D: Attr: handle 7
D: Attr store, pos: 6, handle: 7
D: Attr: handle 8
D: Attr store, pos: 7, handle: 8
D: Attr: handle 9
D: Attr store, pos: 8, handle: 9
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 2
D: Size: 4
D: Buffer: 536904676
D: Attr: handle 4
D: Size: 4
D: Buffer: 536904680
D: Attr: handle 6
D: Size: 4
D: Buffer: 536904684
D: Attr: handle 8
D: Size: 4
D: Buffer: 536904688
D: NULL attribute
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 10
D: Attr store, pos: 0, handle: 10
D: Empty service detected with handle: 10
D: Size: 4
D: Buffer: 536904608
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 11
D: Attr store, pos: 0, handle: 11
D: Service detected, handles range: <12, 14>
D: Size: 4
D: Buffer: 536904608
D: Starting descriptors discovery
D: Attr: handle 12
D: Attr store, pos: 1, handle: 12
D: Attr: handle 13
D: Attr store, pos: 2, handle: 13
D: Attr: handle 14
D: Attr store, pos: 3, handle: 14
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 12
D: Size: 17
D: Buffer: 536904648
D: NULL attribute
D: Discovery complete.
D: Attr memory release
D: Returning! 287
D: Attr: handle 15
D: Attr store, pos: 0, handle: 15
D: Service detected, handles range: <16, 42>
D: Size: 17
D: Buffer: 536904608
D: Starting descriptors discovery
D: Attr: handle 16
D: Attr store, pos: 1, handle: 16
D: Attr: handle 17
D: Attr store, pos: 2, handle: 17
D: Attr: handle 18
D: Attr store, pos: 3, handle: 18
D: Attr: handle 19
D: Attr store, pos: 4, handle: 19
D: Attr: handle 20
D: Attr store, pos: 5, handle: 20
D: Attr: handle 21
D: Attr store, pos: 6, handle: 21
D: Attr: handle 22
D: Attr store, pos: 7, handle: 22
D: Attr: handle 23
D: Attr store, pos: 8, handle: 23
D: Attr: handle 24
D: Attr store, pos: 9, handle: 24
D: Attr: handle 25
D: Attr store, pos: 10, handle: 25
D: Attr: handle 26
D: Attr store, pos: 11, handle: 26
D: Attr: handle 27
D: Attr store, pos: 12, handle: 27
D: Attr: handle 28
D: Attr store, pos: 13, handle: 28
D: Attr: handle 29
D: Attr store, pos: 14, handle: 29
D: Attr: handle 30
D: Attr store, pos: 15, handle: 30
D: Attr: handle 31
D: Attr store, pos: 16, handle: 31
D: Attr: handle 32
D: Attr store, pos: 17, handle: 32
D: Attr: handle 33
D: Attr store, pos: 18, handle: 33
D: Attr: handle 34
D: Attr store, pos: 19, handle: 34
D: Attr: handle 35
D: Attr store, pos: 20, handle: 35
D: Attr: handle 36
D: Attr store, pos: 21, handle: 36
D: Attr: handle 37
D: Attr store, pos: 22, handle: 37
D: Attr: handle 38
D: Attr store, pos: 23, handle: 38
D: Attr: handle 39
D: Attr store, pos: 24, handle: 39
D: Attr: handle 40
D: Attr store, pos: 25, handle: 40
D: Attr: handle 41
D: Attr store, pos: 26, handle: 41
D: Attr: handle 42
D: Attr store, pos: 27, handle: 42
D: NULL attribute
D: Starting characteristic discovery
D: Attr: handle 16
D: Size: 17
D: Buffer: 536905112
D: Attr: handle 18
D: Size: 17
D: Buffer: 536905132
D: Attr: handle 20
D: Size: 17
D: Buffer: 536905152
D: Attr: handle 22
D: Size: 17
D: Buffer: 536905172
D: Attr: handle 24
D: Size: 17
D: Buffer: 536905192
D: Attr: handle 26
D: Size: 17
D: Buffer: 536905236
D: Attr: handle 28
D: Size: 17
D: Buffer: 536905256
D: Attr: handle 30
D: Size: 17
D: Buffer: 536905276
D: Attr: handle 32
D: Size: 17
D: Buffer: 536905296
D: Attr: handle 34
D: Size: 17
D: Buffer: 536905316
D: Attr: handle 36
D: Size: 17
D: Buffer: 0
E: No space for a UUID.
D: Attr memory release
E: The discovery procedure failed, err -12

Using Nordic Connect SDK v2.2.0 with VSCode on nRF52832 dev kit PCA10040 3.0.0.

Thank you, and let me know if there's any other information I can provide to assist in debugging this problem.

Ella

Parents Reply Children
No Data
Related