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,

    I recommend including logs to verify and handle the discovery. You first need to discover the characteristic, then find the CCCD descriptor, and finally subscribe to notifications. You can follow this exercise from the Developer Academy course, which discusses something very similar.

    Kind regards,
    Abhijith

  • Hello! 
    Already find all the CCCD descriptors and the characteristics, I need to subscribe to them and I don't know how to add that when I have two different sets of CCCDs and characteristics.

    The question is fairly straight forward, if I have the code I have given in my post. In these two sections:

    } 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);
    		}
    	}

    Do I need to add subscribing within each of those blocks? Or should it be done outside of those blocks?

Reply
  • Hello! 
    Already find all the CCCD descriptors and the characteristics, I need to subscribe to them and I don't know how to add that when I have two different sets of CCCDs and characteristics.

    The question is fairly straight forward, if I have the code I have given in my post. In these two sections:

    } 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);
    		}
    	}

    Do I need to add subscribing within each of those blocks? Or should it be done outside of those blocks?

Children
No Data
Related