Subscribing to attributes in BLE service

Hello!

I am developing my own BLE solution where I have the different attributes in my service and I am connecting two different nrf52840, one to act as a GATTClient and one as a GATTServer

The code below is for my client where I am discovering the service and my attributes. 

All attributes can be found BUT I can not subscribe to them. What do I need to do because I am lost?

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_FROG)) {
		printk("Discovering TxDATA\n");
		memcpy(&frog_discover_uuid, BT_UUID_TXDATA, sizeof(frog_discover_uuid));
		discover_params.uuid = &frog_discover_uuid.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_TXDATA)) {
		printk("Discovering RxCREDIT\n");
		memcpy(&frog_discover_uuid, BT_UUID_RXCREDIT, sizeof(frog_discover_uuid));
		discover_params.uuid = &frog_discover_uuid.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_RXCREDIT)) {
		printk("Discovering CCC TxData\n");
		//memcpy(&frog_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_discover_uuid));
		discover_params.uuid = ccc_uuid;
		ccc_uuid2 = ccc_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 if (!bt_uuid_cmp(discover_params.uuid, ccc_uuid2)){
		printk("Discovering CCC RxCredit\n");
		//memcpy(&frog_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_discover_uuid));
		discover_params.uuid = ccc_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_CONTINUE;
	}

	return BT_GATT_ITER_STOP;
}



Regards,

Björn

Parents
  • Hello,

    You need to create a bt_gatt_subscribe_params for each CCCD and call bt_gatt_subscribe(). From the initial code you shared, it looks like you're only discovering the CCCD descriptors but never actually subscribing after discovery.

    Your discover_func() should first find all the handles and then subscribe only after the discovery is complete. Also, value_handle should be the characteristic's value handle, not the descriptor's handle.

    Instead of setting subscribe_params.value_handle like this:

    subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

    You should store the characteristic's handle when you find it.

    Kind Regards,

    Abhijith

Reply
  • Hello,

    You need to create a bt_gatt_subscribe_params for each CCCD and call bt_gatt_subscribe(). From the initial code you shared, it looks like you're only discovering the CCCD descriptors but never actually subscribing after discovery.

    Your discover_func() should first find all the handles and then subscribe only after the discovery is complete. Also, value_handle should be the characteristic's value handle, not the descriptor's handle.

    Instead of setting subscribe_params.value_handle like this:

    subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

    You should store the characteristic's handle when you find it.

    Kind Regards,

    Abhijith

Children
  • Why should I store the characteristics handle when the original code from one of the samples does like what I am doing?

    And which handle is that exactly if I shouldn't store the value_handle? Is it the ccc_handle?
    Isn't it like the code I have in the original snippet from row 62 onwards? Isn't that the correct subscription methodology?

    With the exception that I am only subscribing to one of the cccd:s at the moment?

    Regards,

    Björn


Related