hrs example with btuuid128

The zephyr peripheral hr example us altered create a custom GATT service with a 128 bit BT uuid instead of a 16 bit bt number. I tried the following which does not trigger the notify event:

On the peripheral role, I changed advertising data and service definitions. I won't bother you with my code, it works in nrf52 connectivity.

#define uuid_ppg_service_val BT_UUID_128_ENCODE(0x20000001, 0xA000, 0xB000, 0xC000, 0xC00000000001)
#define BT_UUID_PPGS BT_UUID_DECLARE_128(uuid_ppg_service_val)
#define BT_UUID_PPGS_MEASUREMENT BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x10000001, 0xA000, 0xB000, 0xC000, 0xC00000000002))

BT_GATT_SERVICE_DEFINE(ppg_svc,
	BT_GATT_PRIMARY_SERVICE(BT_UUID_PPGS),	
		BT_GATT_CHARACTERISTIC(BT_UUID_PPGS_MEASUREMENT,
					BT_GATT_CHRC_NOTIFY, 
					BT_GATT_PERM_NONE, NULL, NULL, NULL),
			BT_GATT_CCC(vnd_ccc_cfg_changed,
					BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),				
);

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL,
			  //BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
		      	BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
			  ),
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, uuid_ppg_service_val),
};

On the central role, I made these modifications:

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
    // ... 
    if (conn == default_conn) {
        memcpy(&uuid128, BT_UUID_PPGS, sizeof(uuid128));				
		discover_params.uuid = &uuid128.uuid;
	//...
}

static bool eir_found(struct bt_data *data, void *user_data)
{
	bt_addr_le_t *addr = user_data;
	int i;
	int err;

	printk("[AD]: %u data_len %u\n", data->type, data->data_len);
	struct bt_le_conn_param *param;
	param = BT_LE_CONN_PARAM_DEFAULT;

	switch (data->type) {
		case BT_DATA_UUID128_SOME:
			printk("128bit type some");
			break;
		case BT_DATA_UUID128_ALL:
			if (data->data_len % BT_UUID_SIZE_128 != 0U) {
				printk("AD malformed\n");
				return true;
			}
			for(i = 0; i < data->data_len; i+= BT_UUID_SIZE_128) {
				
				printk("128bit type all");
				struct bt_uuid *uuid128;
				uint8_t btadvData[16];
				memcpy(btadvData, data->data, 16);
				uuid128 = (struct bt_uuid *)btadvData;
				if(bt_uuid_cmp(uuid128, BT_UUID_PPGS_MEASUREMENT)) {
					printk("uuid128 == PPGID\n");				
					err = bt_le_scan_stop();
					if(err) {
						printk("Stop LE scan failed (err %d)\n", err);					
					}
					printk("make connection");
					err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
								param, &default_conn);
					if (err) {
						printk("Create conn failed (err %d)\n", err);					
					}		
					return false;			
				}
			}
			break;
		}
	return true;
}

static uint8_t discover_func(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	int err;

	if (!attr) {
	 	printk("Discover complete\n");
	 	(void)memset(params, 0, sizeof(*params));
	 	return BT_GATT_ITER_STOP;
	}

	printk("[ATTRIBUTE] handle %u\n", attr->handle);

	if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_PPGS)) {
		memcpy(&uuid128, BT_UUID_PPGS_MEASUREMENT, sizeof(uuid128));
		discover_params.uuid = &uuid128.uuid;
	
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err) {
			printk("Discover failed (err %d)\n", err);
		}
	} else if (!bt_uuid_cmp(discover_params.uuid,
	
					BT_UUID_PPGS_MEASUREMENT)) {
		memcpy(&uuid16, BT_UUID_GATT_CCC, sizeof(uuid16));
		discover_params.uuid = &uuid16.uuid;
		discover_params.start_handle = attr->handle + 2;
		discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
		subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

		err = bt_gatt_discover(conn, &discover_params);
		if (err) {
			printk("Discover failed (err %d)\n", err);
		}
	} else {
		subscribe_params.notify = notify_func;
		subscribe_params.value = BT_GATT_CCC_NOTIFY;
		subscribe_params.ccc_handle = attr->handle;

		err = bt_gatt_subscribe(conn, &subscribe_params);
		if (err && err != -EALREADY) {
			printk("Subscribe failed (err %d)\n", err);
		} else {
			printk("[SUBSCRIBED]\n");
		}

		return BT_GATT_ITER_STOP;
	}

	return BT_GATT_ITER_STOP;
}

Central connects but notifications do not work. When I change back to BT_UUID_HRS value, notifications are received.

Parents
  • Sorry I made an mistake, the discover_func callback needs an 16bit uuid for BT_UUID_GATT_CCC. I changed that now it works. Resides one more question:

    Why does eir_found loops through the data in the hr_central example. bt_data_parse function explanations says: "Callback function which will be called for each element that's found in the data. The callback should return true to continue parsing, or false to stop parsing.".

Reply
  • Sorry I made an mistake, the discover_func callback needs an 16bit uuid for BT_UUID_GATT_CCC. I changed that now it works. Resides one more question:

    Why does eir_found loops through the data in the hr_central example. bt_data_parse function explanations says: "Callback function which will be called for each element that's found in the data. The callback should return true to continue parsing, or false to stop parsing.".

Children
Related