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"); memset(params, 0, sizeof(*params)); return BT_GATT_ITER_STOP; } printk("[ATTRIBUTE] handle %u\n", attr->handle); if (BT_UUID_16(discover_params.uuid)->val == BT_UUID_HRS_VAL) { uuid.val = BT_UUID_HRS_MEASUREMENT_VAL; discover_params.uuid = &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_16(discover_params.uuid)->val == BT_UUID_HRS_MEASUREMENT_VAL) { uuid.val = BT_UUID_GATT_CCC_VAL; discover_params.uuid = &uuid.uuid; discover_params.start_handle = attr->handle + 2; discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; subscribe_params.value_handle = attr->handle + 1; 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; }
bool BLECharacteristicImp::subscribe(void) { int retval = 0; bt_conn_t* conn = NULL; if (true == BLEUtils::isLocalBLE(_ble_device)) { // GATT server can't subscribe return false; } if (_gatt_chrc.properties & BT_GATT_CHRC_NOTIFY) { _sub_params.value |= BT_GATT_CCC_NOTIFY; } if (_gatt_chrc.properties & BT_GATT_CHRC_INDICATE) { _sub_params.value |= BT_GATT_CCC_INDICATE; } if (_sub_params.value == 0) { return false; } conn = bt_conn_lookup_addr_le(_ble_device.bt_le_address()); if (NULL == conn) { return false; } bt_addr_le_copy(&_sub_params._peer, bt_conn_get_dst(conn)); _sub_params.ccc_handle = _cccd_handle; _sub_params.value_handle = _value_handle; // Enable CCCD to allow peripheral send Notification/Indication retval = bt_gatt_subscribe(conn, &_sub_params); bt_conn_unref(conn); if (0 == retval) { _subscribed = true; } return _subscribed; }
static int cmd_gatt_subscribe(int argc, char *argv[]) { int err; if (subscribe_params.value_handle) { printk("Cannot subscribe: subscription to %x already exists\n", subscribe_params.value_handle); return 0; } if (!default_conn) { printk("Not connected\n"); return 0; } if (argc < 3) { return -EINVAL; } subscribe_params.ccc_handle = strtoul(argv[1], NULL, 16); subscribe_params.value_handle = strtoul(argv[2], NULL, 16); subscribe_params.value = BT_GATT_CCC_NOTIFY; subscribe_params.notify = notify_func; if (argc > 3) { subscribe_params.value = strtoul(argv[3], NULL, 16); } err = bt_gatt_subscribe(default_conn, &subscribe_params); if (err) { printk("Subscribe failed (err %d)\n", err); } else { printk("Subscribed\n"); } return 0; }