Bluetooth: Audio: Add missing error checks for calls to bt_gatt_subscribe

Several places the LE Audio clients called bt_gatt_subscribe without
checking the return value, which could cause some issues in the worst
case, and in the best case, cause some unexpected behavior.

Some implementations had a bit more updating to handle the new
behavior.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2024-01-15 17:49:10 +01:00 committed by Maureen Helm
commit 922ac3c7c1
8 changed files with 65 additions and 20 deletions

View file

@ -608,6 +608,8 @@ static uint8_t aics_discover_func(struct bt_conn *conn, const struct bt_gatt_att
} }
if (sub_params) { if (sub_params) {
int err;
sub_params->value = BT_GATT_CCC_NOTIFY; sub_params->value = BT_GATT_CCC_NOTIFY;
sub_params->value_handle = chrc->value_handle; sub_params->value_handle = chrc->value_handle;
/* /*
@ -616,7 +618,16 @@ static uint8_t aics_discover_func(struct bt_conn *conn, const struct bt_gatt_att
*/ */
sub_params->ccc_handle = attr->handle + 2; sub_params->ccc_handle = attr->handle + 2;
sub_params->notify = aics_client_notify_handler; sub_params->notify = aics_client_notify_handler;
bt_gatt_subscribe(conn, sub_params); err = bt_gatt_subscribe(conn, sub_params);
if (err != 0 && err != -EALREADY) {
LOG_ERR("Failed to subscribe: %d", err);
if (inst->cli.cb && inst->cli.cb->discover) {
inst->cli.cb->discover(inst, err);
}
return BT_GATT_ITER_STOP;
}
} }
} }

View file

@ -1721,7 +1721,7 @@ static void unicast_client_ep_set_cp(struct bt_conn *conn, uint16_t handle)
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to subscribe: %d", err); LOG_DBG("Failed to subscribe: %d", err);
discover_cb(conn, BT_ATT_ERR_UNLIKELY); discover_cb(conn, err);
return; return;
} }
@ -3229,10 +3229,12 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
struct unicast_client *client; struct unicast_client *client;
struct net_buf_simple *buf; struct net_buf_simple *buf;
struct bt_bap_ep *ep; struct bt_bap_ep *ep;
int cb_err;
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
if (err) { if (err) {
cb_err = err;
goto fail; goto fail;
} }
@ -3246,7 +3248,7 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
LOG_DBG("Buffer full, invalid server response of size %u", LOG_DBG("Buffer full, invalid server response of size %u",
length + client->net_buf.len); length + client->net_buf.len);
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN; cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
goto fail; goto fail;
} }
@ -3262,7 +3264,7 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
if (buf->len < sizeof(struct bt_ascs_ase_status)) { if (buf->len < sizeof(struct bt_ascs_ase_status)) {
LOG_DBG("Read response too small (%u)", buf->len); LOG_DBG("Read response too small (%u)", buf->len);
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN; cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
goto fail; goto fail;
} }
@ -3274,28 +3276,32 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
* consider the discovery procedure as failing. * consider the discovery procedure as failing.
*/ */
LOG_WRN("No space left to parse ASE"); LOG_WRN("No space left to parse ASE");
err = -ENOMEM; cb_err = -ENOMEM;
goto fail; goto fail;
} }
unicast_client_ep_set_status(ep, buf); unicast_client_ep_set_status(ep, buf);
unicast_client_ep_subscribe(conn, ep); cb_err = unicast_client_ep_subscribe(conn, ep);
if (cb_err != 0) {
LOG_DBG("Failed to subcribe to ep %p: %d", ep, cb_err);
goto fail;
}
reset_att_buf(client); reset_att_buf(client);
endpoint_cb(conn, ep); endpoint_cb(conn, ep);
err = unicast_client_ase_discover(conn, handle); cb_err = unicast_client_ase_discover(conn, handle);
if (err != 0) { if (cb_err != 0) {
LOG_DBG("Failed to read ASE: %d", err); LOG_DBG("Failed to read ASE: %d", cb_err);
goto fail;
discover_cb(conn, err);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
fail: fail:
discover_cb(conn, err); discover_cb(conn, cb_err);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
@ -3313,7 +3319,7 @@ static uint8_t unicast_client_ase_discover_cb(struct bt_conn *conn,
if (err != 0) { if (err != 0) {
LOG_ERR("Unable to discover ASE Control Point"); LOG_ERR("Unable to discover ASE Control Point");
discover_cb(conn, BT_ATT_ERR_UNLIKELY); discover_cb(conn, err);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
@ -3404,7 +3410,7 @@ static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uin
if (cb_err != 0) { if (cb_err != 0) {
LOG_ERR("Unable to read ASE: %d", cb_err); LOG_ERR("Unable to read ASE: %d", cb_err);
discover_cb(conn, err); discover_cb(conn, cb_err);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;

View file

@ -740,12 +740,21 @@ static uint8_t discover_func(struct bt_conn *conn,
} }
if (sub_params->value != 0) { if (sub_params->value != 0) {
int err;
/* With ccc_handle == 0 it will use auto discovery */ /* With ccc_handle == 0 it will use auto discovery */
sub_params->ccc_handle = 0; sub_params->ccc_handle = 0;
sub_params->end_handle = cur_inst->end_handle; sub_params->end_handle = cur_inst->end_handle;
sub_params->value_handle = chrc->value_handle; sub_params->value_handle = chrc->value_handle;
sub_params->notify = notify_handler; sub_params->notify = notify_handler;
bt_gatt_subscribe(conn, sub_params);
err = bt_gatt_subscribe(conn, sub_params);
if (err != 0 && err != -EALREADY) {
LOG_DBG("Failed to subscribe (err %d)", err);
discover_complete(client, err);
return BT_GATT_ITER_STOP;
}
} }
} }
} }
@ -1315,6 +1324,9 @@ static int csip_set_coordinator_read_set_lock(struct bt_csip_set_coordinator_svc
static void csip_set_coordinator_reset(struct bt_csip_set_coordinator_inst *inst) static void csip_set_coordinator_reset(struct bt_csip_set_coordinator_inst *inst)
{ {
inst->inst_count = 0U;
memset(&inst->set_member, 0, sizeof(inst->set_member));
for (size_t i = 0; i < ARRAY_SIZE(inst->svc_insts); i++) { for (size_t i = 0; i < ARRAY_SIZE(inst->svc_insts); i++) {
struct bt_csip_set_coordinator_svc_inst *svc_inst = &inst->svc_insts[i]; struct bt_csip_set_coordinator_svc_inst *svc_inst = &inst->svc_insts[i];
@ -1433,7 +1445,7 @@ int bt_csip_set_coordinator_discover(struct bt_conn *conn)
client = &client_insts[bt_conn_index(conn)]; client = &client_insts[bt_conn_index(conn)];
(void)memset(client, 0, sizeof(*client)); csip_set_coordinator_reset(client);
/* Discover CSIS on peer, setup handles and notify */ /* Discover CSIS on peer, setup handles and notify */
(void)memset(&discover_params, 0, sizeof(discover_params)); (void)memset(&discover_params, 0, sizeof(discover_params));

View file

@ -1297,7 +1297,13 @@ static uint8_t discover_otc_char_func(struct bt_conn *conn,
sub_params->value_handle = chrc->value_handle; sub_params->value_handle = chrc->value_handle;
sub_params->notify = bt_ots_client_indicate_handler; sub_params->notify = bt_ots_client_indicate_handler;
bt_gatt_subscribe(conn, sub_params); err = bt_gatt_subscribe(conn, sub_params);
if (err != 0) {
LOG_DBG("Failed to subscribe (err %d)", err);
discovery_complete(conn, err);
return BT_GATT_ITER_STOP;
}
} }
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;

View file

@ -416,6 +416,10 @@ static uint8_t micp_discover_func(struct bt_conn *conn,
} else { } else {
LOG_DBG("Could not subscribe to handle 0x%04X: %d", attr->handle, LOG_DBG("Could not subscribe to handle 0x%04X: %d", attr->handle,
err); err);
micp_mic_ctlr_discover_complete(mic_ctlr, err);
return BT_GATT_ITER_STOP;
} }
} }
} }

View file

@ -1545,6 +1545,9 @@ static uint8_t discover_func(struct bt_conn *conn,
"characterstic at handle 0x%04X" "characterstic at handle 0x%04X"
"(%d)", "(%d)",
sub_params->value_handle, err); sub_params->value_handle, err);
tbs_client_discover_complete(conn, err);
return BT_GATT_ITER_STOP;
} else { } else {
LOG_DBG("Subscribed to characterstic at " LOG_DBG("Subscribed to characterstic at "
"handle 0x%04X", "handle 0x%04X",

View file

@ -454,8 +454,11 @@ static uint8_t vcs_discover_func(struct bt_conn *conn,
LOG_DBG("Subscribed to handle 0x%04X", LOG_DBG("Subscribed to handle 0x%04X",
attr->handle); attr->handle);
} else { } else {
LOG_DBG("Could not subscribe to handle 0x%04X", LOG_DBG("Could not subscribe to handle 0x%04X (%d)", attr->handle,
attr->handle); err);
vcp_vol_ctlr_discover_complete(vol_ctlr, err);
return BT_GATT_ITER_STOP;
} }
} }
} }

View file

@ -21,7 +21,7 @@ static void csip_discover_cb(struct bt_conn *conn,
int err, size_t set_count) int err, size_t set_count)
{ {
if (err != 0) { if (err != 0) {
printk("CSIP Lock Discover failed (err = %d)\n", err); FAIL("CSIP Lock Discover failed (err = %d)\n", err);
return; return;
} }