/* Bluetooth Audio Content Control */ /* * Copyright (c) 2020 Bose Corporation * Copyright (c) 2021-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include #include struct ccid_search_param { const struct bt_gatt_attr *attr; uint8_t ccid; }; static uint8_t ccid_attr_cb(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) { struct ccid_search_param *search_param = user_data; if (attr->read != NULL) { uint8_t ccid = 0U; ssize_t res; res = attr->read(NULL, attr, &ccid, sizeof(ccid), 0); if (res == sizeof(ccid) && search_param->ccid == ccid) { search_param->attr = attr; return BT_GATT_ITER_STOP; } } return BT_GATT_ITER_CONTINUE; } const struct bt_gatt_attr *bt_ccid_find_attr(uint8_t ccid) { struct ccid_search_param search_param = { .attr = NULL, .ccid = ccid, }; bt_gatt_foreach_attr_type(BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE, BT_UUID_CCID, NULL, 0, ccid_attr_cb, &search_param); return search_param.attr; } int bt_ccid_alloc_value(void) { static uint8_t next_ccid_value; const uint8_t tmp = next_ccid_value; /* Verify that the CCID is unused and increment until we reach an unused value or until we * reach our starting point * This is not a perfect check as there may be services that are not registered that have * allocated a CCID. * Implementing a perfect solution would require a alloc and free API where we need to * keep track of all allocated CCIDs, which requires additional memory for something that's * very unlikely to be an issue. */ while (bt_ccid_find_attr(next_ccid_value) != NULL) { next_ccid_value++; if (tmp == next_ccid_value) { return -ENOMEM; } } return next_ccid_value++; }