bluetooth: audio: ascs: Fix Codec Config initiated by server

The Codec Specific Configuration Parameters provided by server was
not copied at bt_ascs_config_ase. Detected by PTS in BAP/USR/SCC PTS
test cases, because no LTV values appeared in ASE Codec Configured
notification.

Signed-off-by: Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl>
This commit is contained in:
Magdalena Kasenberg 2023-07-18 13:02:08 +02:00 committed by Fabio Baltieri
parent 691b357b59
commit 6135ae0fa0

View file

@ -1541,6 +1541,37 @@ static int ase_config(struct bt_ascs_ase *ase, const struct bt_ascs_config *cfg)
return 0;
}
void copy_codec_cfg_pointers(struct bt_audio_codec_cfg *dst,
struct bt_audio_codec_cfg *src)
{
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT > 0 && CONFIG_BT_AUDIO_CODEC_MAX_DATA_LEN > 0
/* Need to update the `bt_data.data` pointer to the new value after copying the codec */
for (size_t i = 0U; i < ARRAY_SIZE(dst->data); i++) {
const struct bt_audio_codec_data *codec_data = &src->data[i];
struct bt_audio_codec_data *data = &dst->data[i];
const uint8_t data_len = codec_data->data.data_len;
data->data.data = data->value;
data->data.data_len = data_len;
memcpy(data->value, codec_data->data.data, data_len);
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT > 0 && CONFIG_BT_AUDIO_CODEC_MAX_DATA_LEN > 0 */
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_COUNT > 0 && CONFIG_BT_AUDIO_CODEC_MAX_DATA_LEN > 0
for (size_t i = 0U; i < ARRAY_SIZE(dst->meta); i++) {
const struct bt_audio_codec_data *meta_data = &src->meta[i];
struct bt_audio_codec_data *data = &dst->meta[i];
const uint8_t data_len = meta_data->data.data_len;
data->data.data = data->value;
data->data.data_len = data_len;
memcpy(data->value, meta_data->data.data, data_len);
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_COUNT > 0 &&
* CONFIG_BT_AUDIO_CODEC_MAX_DATA_LEN > 0
*/
}
int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
struct bt_audio_codec_cfg *codec_cfg,
const struct bt_audio_codec_qos_pref *qos_pref)
@ -1548,16 +1579,13 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
int err;
struct bt_ascs_ase *ase = NULL;
struct bt_bap_ep *ep;
struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
BT_BAP_ASCS_REASON_NONE);
struct codec_cap_lookup_id_data lookup_data;
CHECKIF(conn == NULL || stream == NULL || codec_cfg == NULL || qos_pref == NULL) {
LOG_DBG("NULL value(s) supplied)");
return -EINVAL;
}
ep = stream->ep;
if (stream->ep != NULL) {
LOG_DBG("Stream already configured for conn %p", (void *)stream->conn);
return -EALREADY;
@ -1578,13 +1606,27 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
ep = &ase->ep;
err = ascs_ep_set_codec(ep, codec_cfg->id, sys_le16_to_cpu(codec_cfg->cid),
sys_le16_to_cpu(codec_cfg->vid), NULL, 0, &rsp);
if (err) {
ase_free(ase);
return err;
if (ep == NULL) {
return -EINVAL;
}
lookup_data.id = codec_cfg->id;
lookup_data.cid = codec_cfg->cid;
lookup_data.vid = codec_cfg->vid;
bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);
if (lookup_data.codec_cap == NULL) {
LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities",
codec_cfg->id, bt_audio_dir_str(ep->dir));
return -ENOENT;
}
(void)memcpy(&ep->codec_cfg, codec_cfg, sizeof(ep->codec_cfg));
/* TODO: Remove this after refactoring bt_audio_codec_cfg to use flat arrays */
copy_codec_cfg_pointers(&ep->codec_cfg, codec_cfg);
ep->qos_pref = *qos_pref;
bt_bap_stream_attach(conn, stream, ep, &ep->codec_cfg);