Bluetooth: audio: tbs_client: Separate GTBS from TBS instances
This improves the code readability and reduces flash usage a bit by spliting up GTBS from other TBS instances in bt_tbs_server_inst structure, so that some of the code could be conditionally compiled out. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
parent
e11cc216b1
commit
650a0d8331
1 changed files with 161 additions and 84 deletions
|
@ -45,29 +45,46 @@ BUILD_ASSERT(CONFIG_BT_L2CAP_TX_BUF_COUNT >= TBS_CLIENT_BUF_COUNT, "Too few L2CA
|
|||
|
||||
#include "common/bt_str.h"
|
||||
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
#define BT_TBS_INSTANCE_MAX_CNT (CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES + 1)
|
||||
#else
|
||||
#define BT_TBS_INSTANCE_MAX_CNT CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES
|
||||
#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */
|
||||
|
||||
struct bt_tbs_server_inst {
|
||||
struct bt_tbs_instance tbs_insts[BT_TBS_INSTANCE_MAX_CNT];
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
struct bt_tbs_instance tbs_insts[CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES];
|
||||
uint8_t inst_cnt;
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
struct bt_tbs_instance gtbs_inst;
|
||||
#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */
|
||||
struct bt_gatt_discover_params discover_params;
|
||||
struct bt_tbs_instance *current_inst;
|
||||
struct bt_tbs_instance *gtbs;
|
||||
uint8_t inst_cnt;
|
||||
bool subscribe_all;
|
||||
};
|
||||
|
||||
static const struct bt_tbs_client_cb *tbs_client_cbs;
|
||||
|
||||
static struct bt_tbs_server_inst srv_insts[CONFIG_BT_MAX_CONN];
|
||||
static const struct bt_uuid *tbs_uuid = BT_UUID_TBS;
|
||||
static const struct bt_uuid *gtbs_uuid = BT_UUID_GTBS;
|
||||
|
||||
static void discover_next_instance(struct bt_conn *conn, uint8_t index);
|
||||
|
||||
typedef bool (*tbs_instance_find_func_t)(struct bt_tbs_instance *inst, void *user_data);
|
||||
|
||||
static struct bt_tbs_instance *tbs_instance_find(struct bt_tbs_server_inst *server,
|
||||
tbs_instance_find_func_t func, void *user_data)
|
||||
{
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
if (func(&server->gtbs_inst, user_data)) {
|
||||
return &server->gtbs_inst;
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
for (size_t i = 0; i < server->inst_cnt; i++) {
|
||||
if (func(&server->tbs_insts[i], user_data)) {
|
||||
return &server->tbs_insts[i];
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct bt_tbs_instance *tbs_inst_by_index(struct bt_conn *conn, uint8_t index)
|
||||
{
|
||||
struct bt_tbs_server_inst *server;
|
||||
|
@ -76,20 +93,16 @@ static struct bt_tbs_instance *tbs_inst_by_index(struct bt_conn *conn, uint8_t i
|
|||
|
||||
server = &srv_insts[bt_conn_index(conn)];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
|
||||
/* GTBS can be accessed by BT_TBS_GTBS_INDEX only */
|
||||
if (index == ARRAY_SIZE(server->tbs_insts) - 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (index == BT_TBS_GTBS_INDEX) {
|
||||
return server->gtbs;
|
||||
}
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
if (index == BT_TBS_GTBS_INDEX) {
|
||||
return &server->gtbs_inst;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
if (index < server->inst_cnt) {
|
||||
return &server->tbs_insts[index];
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -104,12 +117,19 @@ static uint8_t tbs_index(struct bt_conn *conn, const struct bt_tbs_instance *ins
|
|||
|
||||
server = &srv_insts[bt_conn_index(conn)];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst == server->gtbs) {
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
if (inst == &server->gtbs_inst) {
|
||||
return BT_TBS_GTBS_INDEX;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
index = inst - server->tbs_insts;
|
||||
__ASSERT_NO_MSG(index >= 0 && index < ARRAY_SIZE(server->tbs_insts));
|
||||
__ASSERT(index >= 0 && index < ARRAY_SIZE(server->tbs_insts),
|
||||
"Invalid bt_tbs_instance pointer");
|
||||
|
||||
#else
|
||||
__ASSERT_PRINT("Invalid bt_tbs_instance pointer");
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
|
||||
return (uint8_t)index;
|
||||
}
|
||||
|
@ -127,23 +147,30 @@ static bool free_call_spot(struct bt_tbs_instance *inst)
|
|||
}
|
||||
#endif /* defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL) */
|
||||
|
||||
static bool is_instance_handle(struct bt_tbs_instance *inst, void *user_data)
|
||||
{
|
||||
uint16_t handle = POINTER_TO_UINT(user_data);
|
||||
|
||||
return inst->start_handle <= handle && inst->end_handle >= handle;
|
||||
}
|
||||
|
||||
static struct bt_tbs_instance *lookup_inst_by_handle(struct bt_conn *conn,
|
||||
uint16_t handle)
|
||||
{
|
||||
uint8_t conn_index;
|
||||
struct bt_tbs_server_inst *srv_inst;
|
||||
struct bt_tbs_instance *inst;
|
||||
|
||||
__ASSERT(conn, "NULL conn");
|
||||
|
||||
conn_index = bt_conn_index(conn);
|
||||
srv_inst = &srv_insts[conn_index];
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(srv_inst->tbs_insts); i++) {
|
||||
if (srv_inst->tbs_insts[i].start_handle <= handle &&
|
||||
srv_inst->tbs_insts[i].end_handle >= handle) {
|
||||
return &srv_inst->tbs_insts[i];
|
||||
}
|
||||
inst = tbs_instance_find(srv_inst, is_instance_handle, UINT_TO_POINTER(handle));
|
||||
if (inst != NULL) {
|
||||
return inst;
|
||||
}
|
||||
|
||||
LOG_DBG("Could not find instance with handle 0x%04x", handle);
|
||||
|
||||
return NULL;
|
||||
|
@ -655,6 +682,24 @@ static int tbs_client_gatt_read(struct bt_conn *conn, struct bt_tbs_instance *in
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool gtbs_found(struct bt_tbs_server_inst *srv_inst)
|
||||
{
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
return srv_inst->gtbs_inst.start_handle != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
|
||||
}
|
||||
|
||||
static uint8_t inst_cnt(struct bt_tbs_server_inst *srv_inst)
|
||||
{
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
return srv_inst->inst_cnt;
|
||||
#else
|
||||
return 0;
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
}
|
||||
|
||||
static void tbs_client_discover_complete(struct bt_conn *conn, int err)
|
||||
{
|
||||
struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
|
||||
|
@ -665,7 +710,7 @@ static void tbs_client_discover_complete(struct bt_conn *conn, int err)
|
|||
srv_inst->current_inst = NULL;
|
||||
|
||||
if (tbs_client_cbs != NULL && tbs_client_cbs->discover != NULL) {
|
||||
tbs_client_cbs->discover(conn, err, srv_inst->inst_cnt, srv_inst->gtbs != NULL);
|
||||
tbs_client_cbs->discover(conn, err, inst_cnt(srv_inst), gtbs_found(srv_inst));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1325,17 +1370,17 @@ static uint8_t disc_read_ccid_cb(struct bt_conn *conn, uint8_t err,
|
|||
if (cb_err != 0) {
|
||||
tbs_client_discover_complete(conn, cb_err);
|
||||
} else {
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst == srv_inst->gtbs) {
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst_index == BT_TBS_GTBS_INDEX) {
|
||||
LOG_DBG("Setup complete GTBS");
|
||||
|
||||
inst_index = 0;
|
||||
} else {
|
||||
inst_index++;
|
||||
|
||||
LOG_DBG("Setup complete for %u / %u TBS", inst_index, srv_inst->inst_cnt);
|
||||
LOG_DBG("Setup complete for %u / %u TBS", inst_index, inst_cnt(srv_inst));
|
||||
}
|
||||
|
||||
if (inst_index < srv_inst->inst_cnt) {
|
||||
if (inst_index < inst_cnt(srv_inst)) {
|
||||
discover_next_instance(conn, inst_index);
|
||||
} else {
|
||||
tbs_client_discover_complete(conn, 0);
|
||||
|
@ -1552,15 +1597,15 @@ static void discover_next_instance(struct bt_conn *conn, uint8_t index)
|
|||
static void primary_discover_complete(struct bt_tbs_server_inst *server, struct bt_conn *conn)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
|
||||
LOG_DBG("Discover complete, found %u instances (GTBS%s found)", server->inst_cnt,
|
||||
server->gtbs != NULL ? "" : " not");
|
||||
LOG_DBG("Discover complete, found %u instances (GTBS%s found)",
|
||||
inst_cnt(server), gtbs_found(server) ? "" : " not");
|
||||
} else {
|
||||
LOG_DBG("Discover complete, found %u instances", server->inst_cnt);
|
||||
LOG_DBG("Discover complete, found %u instances", inst_cnt(server));
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && server->gtbs != NULL) {
|
||||
if (gtbs_found(server)) {
|
||||
discover_next_instance(conn, BT_TBS_GTBS_INDEX);
|
||||
} else if (server->inst_cnt > 0) {
|
||||
} else if (inst_cnt(server) > 0) {
|
||||
discover_next_instance(conn, 0);
|
||||
} else {
|
||||
tbs_client_discover_complete(conn, 0);
|
||||
|
@ -1572,12 +1617,17 @@ static void primary_discover_complete(struct bt_tbs_server_inst *server, struct
|
|||
* handles of the writeable characteristics and subscribing to all notify and
|
||||
* indicate characteristics.
|
||||
*/
|
||||
static uint8_t primary_discover_tbs(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
struct bt_gatt_discover_params *params)
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
static const struct bt_uuid *tbs_uuid = BT_UUID_TBS;
|
||||
|
||||
static uint8_t primary_discover_tbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
struct bt_gatt_discover_params *params)
|
||||
{
|
||||
const uint8_t conn_index = bt_conn_index(conn);
|
||||
struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
|
||||
|
||||
LOG_DBG("conn %p attr %p", (void *)conn, attr);
|
||||
|
||||
if (attr != NULL) {
|
||||
const struct bt_gatt_service_val *prim_service;
|
||||
|
||||
|
@ -1589,8 +1639,7 @@ static uint8_t primary_discover_tbs(struct bt_conn *conn, const struct bt_gatt_a
|
|||
srv_inst->current_inst->start_handle = attr->handle + 1;
|
||||
srv_inst->current_inst->end_handle = prim_service->end_handle;
|
||||
|
||||
if (CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 1 &&
|
||||
srv_inst->inst_cnt < CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES) {
|
||||
if (srv_inst->inst_cnt < CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES) {
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
@ -1600,12 +1649,35 @@ static uint8_t primary_discover_tbs(struct bt_conn *conn, const struct bt_gatt_a
|
|||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
static uint8_t primary_discover_gtbs(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
struct bt_gatt_discover_params *params)
|
||||
static int primary_discover_tbs(struct bt_conn *conn)
|
||||
{
|
||||
struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
|
||||
struct bt_gatt_discover_params *params = &srv_inst->discover_params;
|
||||
|
||||
LOG_DBG("conn %p", (void *)conn);
|
||||
|
||||
(void)memset(params, 0, sizeof(*params));
|
||||
params->uuid = tbs_uuid;
|
||||
params->func = primary_discover_tbs_cb;
|
||||
params->type = BT_GATT_DISCOVER_PRIMARY;
|
||||
params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
|
||||
|
||||
return bt_gatt_discover(conn, params);
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
static const struct bt_uuid *gtbs_uuid = BT_UUID_GTBS;
|
||||
|
||||
static uint8_t primary_discover_gtbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
struct bt_gatt_discover_params *params)
|
||||
{
|
||||
const uint8_t conn_index = bt_conn_index(conn);
|
||||
struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
|
||||
|
||||
LOG_DBG("conn %p attr %p", (void *)conn, attr);
|
||||
|
||||
if (attr != NULL) {
|
||||
const struct bt_gatt_service_val *prim_service;
|
||||
|
||||
|
@ -1613,34 +1685,45 @@ static uint8_t primary_discover_gtbs(struct bt_conn *conn, const struct bt_gatt_
|
|||
|
||||
prim_service = (struct bt_gatt_service_val *)attr->user_data;
|
||||
|
||||
/* GTBS is placed as the "last" instance */
|
||||
srv_inst->gtbs = &srv_inst->tbs_insts[ARRAY_SIZE(srv_inst->tbs_insts) - 1];
|
||||
srv_inst->gtbs->start_handle = attr->handle + 1;
|
||||
srv_inst->gtbs->end_handle = prim_service->end_handle;
|
||||
|
||||
srv_inst->current_inst = srv_inst->gtbs;
|
||||
srv_inst->current_inst = &srv_inst->gtbs_inst;
|
||||
srv_inst->current_inst->start_handle = attr->handle + 1;
|
||||
srv_inst->current_inst->end_handle = prim_service->end_handle;
|
||||
}
|
||||
|
||||
if (CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0) {
|
||||
int err;
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
int err;
|
||||
|
||||
params->uuid = tbs_uuid;
|
||||
params->func = primary_discover_tbs;
|
||||
params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
|
||||
err = bt_gatt_discover(conn, params);
|
||||
if (err == 0) {
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
LOG_DBG("Discover failed (err %d)", err);
|
||||
err = primary_discover_tbs(conn);
|
||||
if (err == 0) {
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
LOG_DBG("Discover failed (err %d)", err);
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
|
||||
primary_discover_complete(srv_inst, conn);
|
||||
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
static int primary_discover_gtbs(struct bt_conn *conn)
|
||||
{
|
||||
struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
|
||||
struct bt_gatt_discover_params *params = &srv_inst->discover_params;
|
||||
|
||||
LOG_DBG("conn %p", (void *)conn);
|
||||
|
||||
(void)memset(params, 0, sizeof(*params));
|
||||
params->uuid = gtbs_uuid;
|
||||
params->func = primary_discover_gtbs_cb;
|
||||
params->type = BT_GATT_DISCOVER_PRIMARY;
|
||||
params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
|
||||
|
||||
return bt_gatt_discover(conn, params);
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */
|
||||
|
||||
/****************************** PUBLIC API ******************************/
|
||||
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL)
|
||||
|
@ -2151,25 +2234,18 @@ int bt_tbs_client_discover(struct bt_conn *conn, bool subscribe)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0
|
||||
(void)memset(srv_inst->tbs_insts, 0, sizeof(srv_inst->tbs_insts)); /* reset data */
|
||||
srv_inst->inst_cnt = 0;
|
||||
srv_inst->gtbs = NULL;
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES > 0 */
|
||||
/* Discover TBS on peer, setup handles and notify/indicate */
|
||||
srv_inst->subscribe_all = subscribe;
|
||||
(void)memset(&srv_inst->discover_params, 0, sizeof(srv_inst->discover_params));
|
||||
if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
|
||||
LOG_DBG("Discovering GTBS");
|
||||
srv_inst->discover_params.uuid = gtbs_uuid;
|
||||
srv_inst->discover_params.func = primary_discover_gtbs;
|
||||
} else {
|
||||
srv_inst->discover_params.uuid = tbs_uuid;
|
||||
srv_inst->discover_params.func = primary_discover_tbs;
|
||||
}
|
||||
srv_inst->discover_params.type = BT_GATT_DISCOVER_PRIMARY;
|
||||
srv_inst->discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
srv_inst->discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
|
||||
|
||||
return bt_gatt_discover(conn, &srv_inst->discover_params);
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_GTBS)
|
||||
(void)memset(&srv_inst->gtbs_inst, 0, sizeof(srv_inst->gtbs_inst)); /* reset data */
|
||||
return primary_discover_gtbs(conn);
|
||||
#else
|
||||
return primary_discover_tbs(conn);
|
||||
#endif /* CONFIG_BT_TBS_CLIENT_GTBS */
|
||||
}
|
||||
|
||||
void bt_tbs_client_register_cb(const struct bt_tbs_client_cb *cbs)
|
||||
|
@ -2178,6 +2254,13 @@ void bt_tbs_client_register_cb(const struct bt_tbs_client_cb *cbs)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_BT_TBS_CLIENT_CCID)
|
||||
static bool tbs_instance_ccid_is_eq(struct bt_tbs_instance *inst, void *user_data)
|
||||
{
|
||||
uint8_t ccid = POINTER_TO_UINT(user_data);
|
||||
|
||||
return inst->ccid == ccid;
|
||||
}
|
||||
|
||||
struct bt_tbs_instance *bt_tbs_client_get_by_ccid(const struct bt_conn *conn,
|
||||
uint8_t ccid)
|
||||
{
|
||||
|
@ -2190,12 +2273,6 @@ struct bt_tbs_instance *bt_tbs_client_get_by_ccid(const struct bt_conn *conn,
|
|||
|
||||
server = &srv_insts[bt_conn_index(conn)];
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(server->tbs_insts); i++) {
|
||||
if (server->tbs_insts[i].ccid == ccid) {
|
||||
return &server->tbs_insts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return tbs_instance_find(server, tbs_instance_ccid_is_eq, UINT_TO_POINTER(ccid));
|
||||
}
|
||||
#endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue