From fa70c86cd62799bc701dd7baddce6419bd356692 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 29 Nov 2022 13:44:04 +0100 Subject: [PATCH] Bluetooth: Audio: Add common audio shell print commands to audio.h Move common audio shell print functions into audio.h. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/shell/audio.h | 101 ++++++++++++++++++ subsys/bluetooth/audio/shell/bap.c | 48 ++------- .../audio/shell/bap_broadcast_assistant.c | 55 +++++++++- 3 files changed, 162 insertions(+), 42 deletions(-) diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index 5dea87902a4..0112899f220 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -13,7 +13,13 @@ #ifndef __AUDIO_H #define __AUDIO_H +#include + +#include +#include #include +#include +#include extern struct bt_csip_set_member_svc_inst *svc_inst; @@ -65,6 +71,101 @@ extern const struct named_lc3_preset *default_sink_preset; extern const struct named_lc3_preset *default_source_preset; #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */ #endif /* CONFIG_BT_BAP_UNICAST */ + +static inline void print_qos(const struct shell *sh, const struct bt_codec_qos *qos) +{ +#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST) + shell_print(sh, + "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u latency %u pd %u", + qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency, + qos->pd); +#else + shell_print(sh, "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u pd %u", + qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->pd); +#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */ +} + +static inline void print_codec(const struct shell *sh, const struct bt_codec *codec) +{ + shell_print(sh, "codec 0x%02x cid 0x%04x vid 0x%04x", codec->id, codec->cid, codec->vid); + +#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 + shell_print(sh, "data_count %u", codec->data_count); + for (size_t i = 0U; i < codec->data_count; i++) { + shell_print(sh, "data #%u: type 0x%02x len %u", i, codec->data[i].data.type, + codec->data[i].data.data_len); + shell_hexdump(sh, codec->data[i].data.data, + codec->data[i].data.data_len - sizeof(codec->data[i].data.type)); + } +#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ + +#if CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 + shell_print(sh, "meta_count %u", codec->data_count); + for (size_t i = 0U; i < codec->meta_count; i++) { + shell_print(sh, "meta #%u: type 0x%02x len %u", i, codec->meta[i].data.type, + codec->meta[i].data.data_len); + shell_hexdump(sh, codec->meta[i].data.data, + codec->meta[i].data.data_len - sizeof(codec->meta[i].data.type)); + } +#endif /* CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 */ +} + +#if BROADCAST_SNK_SUBGROUP_CNT > 0 +static inline void print_base(const struct shell *sh, const struct bt_bap_base *base) +{ + uint8_t bis_indexes[BT_ISO_MAX_GROUP_ISO_COUNT] = {0}; + /* "0xXX " requires 5 characters */ + char bis_indexes_str[5 * ARRAY_SIZE(bis_indexes) + 1]; + size_t index_count = 0; + + for (size_t i = 0U; i < base->subgroup_count; i++) { + const struct bt_bap_base_subgroup *subgroup; + + subgroup = &base->subgroups[i]; + + shell_print(sh, "Subgroup[%d]:", i); + print_codec(sh, &subgroup->codec); + + for (size_t j = 0U; j < subgroup->bis_count; j++) { + const struct bt_bap_base_bis_data *bis_data; + + bis_data = &subgroup->bis_data[j]; + + shell_print(sh, "BIS[%d] index 0x%02x", j, bis_data->index); + bis_indexes[index_count++] = bis_data->index; + +#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 + for (size_t k = 0U; k < bis_data->data_count; k++) { + const struct bt_codec_data *codec_data; + + codec_data = &bis_data->data[k]; + + shell_print(sh, "data #%u: type 0x%02x len %u", k, + codec_data->data.type, codec_data->data.data_len); + shell_hexdump(sh, codec_data->data.data, + codec_data->data.data_len - + sizeof(codec_data->data.type)); + } +#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ + } + } + + (void)memset(bis_indexes_str, 0, sizeof(bis_indexes_str)); + + /* Create space separated list of indexes as hex values */ + for (size_t i = 0U; i < index_count; i++) { + char bis_index_str[6]; + + sprintf(bis_index_str, "0x%02x ", bis_indexes[i]); + + strcat(bis_indexes_str, bis_index_str); + shell_print(sh, "[%d]: %s", i, bis_index_str); + } + + shell_print(sh, "Possible indexes: %s", bis_indexes_str); +} +#endif /* BROADCAST_SNK_SUBGROUP_CNT > 0 */ + #endif /* CONFIG_BT_AUDIO */ #endif /* __AUDIO_H */ diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index cb250105530..e99cc9813f1 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -367,32 +367,6 @@ static void lc3_audio_timer_timeout(struct k_work *work) static K_WORK_DELAYABLE_DEFINE(audio_send_work, lc3_audio_timer_timeout); #endif /* CONFIG_LIBLC3 && CONFIG_BT_AUDIO_TX */ -static void print_codec(const struct bt_codec *codec) -{ - int i; - - shell_print(ctx_shell, "codec 0x%02x cid 0x%04x vid 0x%04x count %u", - codec->id, codec->cid, codec->vid, codec->data_count); - - for (i = 0; i < codec->data_count; i++) { - shell_print(ctx_shell, "data #%u: type 0x%02x len %u", i, - codec->data[i].data.type, - codec->data[i].data.data_len); - shell_hexdump(ctx_shell, codec->data[i].data.data, - codec->data[i].data.data_len - - sizeof(codec->data[i].data.type)); - } - - for (i = 0; i < codec->meta_count; i++) { - shell_print(ctx_shell, "meta #%u: type 0x%02x len %u", i, - codec->meta[i].data.type, - codec->meta[i].data.data_len); - shell_hexdump(ctx_shell, codec->meta[i].data.data, - codec->meta[i].data.data_len - - sizeof(codec->meta[i].data.type)); - } -} - static const struct named_lc3_preset *get_named_preset(bool is_unicast, const char *preset_arg) { if (is_unicast) { @@ -423,14 +397,6 @@ static void set_unicast_stream(struct bt_bap_stream *stream) } } -static void print_qos(const struct bt_codec_qos *qos) -{ - shell_print(ctx_shell, "QoS: interval %u framing 0x%02x " - "phy 0x%02x sdu %u rtn %u latency %u pd %u", - qos->interval, qos->framing, qos->phy, qos->sdu, - qos->rtn, qos->latency, qos->pd); -} - static int cmd_select_unicast(const struct shell *sh, size_t argc, char *argv[]) { struct bt_bap_stream *stream; @@ -476,7 +442,7 @@ static int lc3_config(struct bt_conn *conn, const struct bt_bap_ep *ep, enum bt_ { shell_print(ctx_shell, "ASE Codec Config: conn %p ep %p dir %u", conn, ep, dir); - print_codec(codec); + print_codec(ctx_shell, codec); *stream = stream_alloc(); if (*stream == NULL) { @@ -502,7 +468,7 @@ static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir, { shell_print(ctx_shell, "ASE Codec Reconfig: stream %p", stream); - print_codec(codec); + print_codec(ctx_shell, codec); if (default_stream == NULL) { set_unicast_stream(stream); @@ -518,7 +484,7 @@ static int lc3_qos(struct bt_bap_stream *stream, const struct bt_codec_qos *qos, { shell_print(ctx_shell, "QoS: stream %p %p", stream, qos); - print_qos(qos); + print_qos(ctx_shell, qos); return 0; } @@ -744,7 +710,7 @@ static void print_remote_codec(const struct bt_conn *conn, struct bt_codec *code shell_print(ctx_shell, "conn %p: #%u: codec %p dir 0x%02x", conn, index, codec, dir); - print_codec(codec); + print_codec(ctx_shell, codec); } #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 @@ -1433,8 +1399,8 @@ static int cmd_preset(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "%s", named_preset->name); - print_codec(&named_preset->preset.codec); - print_qos(&named_preset->preset.qos); + print_codec(ctx_shell, &named_preset->preset.codec); + print_qos(ctx_shell, &named_preset->preset.qos); return 0; } @@ -1640,7 +1606,7 @@ static void base_recv(struct bt_bap_broadcast_sink *sink, const struct bt_bap_ba subgroup = &base->subgroups[i]; shell_print(ctx_shell, "Subgroup[%d]:", i); - print_codec(&subgroup->codec); + print_codec(ctx_shell, &subgroup->codec); for (int j = 0; j < subgroup->bis_count; j++) { const struct bt_bap_base_bis_data *bis_data; diff --git a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c index 342a62b86b7..e20eea6e4d5 100644 --- a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c @@ -20,6 +20,48 @@ #include #include "shell/bt.h" #include "../../host/hci_core.h" +#include "audio.h" + +static struct bt_bap_base received_base; + +static bool pa_decode_base(struct bt_data *data, void *user_data) +{ + struct bt_bap_base base = { 0 }; + int err; + + if (data->type != BT_DATA_SVC_DATA16) { + return true; + } + + if (data->data_len < BT_BAP_BASE_MIN_SIZE) { + return true; + } + + err = bt_bap_decode_base(data, &base); + if (err != 0 && err != -ENOMSG) { + shell_error(ctx_shell, "Failed to decode BASE: %d", err); + + return false; + } + + /* Compare BASE and print if different */ + if (memcmp(&base, &received_base, sizeof(base)) != 0) { + (void)memcpy(&received_base, &base, sizeof(base)); + +#if BROADCAST_SNK_SUBGROUP_CNT > 0 + print_base(ctx_shell, &received_base); +#endif /* BROADCAST_SNK_SUBGROUP_CNT > 0 */ + } + + return false; +} + +static void pa_recv(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_recv_info *info, + struct net_buf_simple *buf) +{ + bt_data_parse(buf, pa_decode_base, NULL); +} static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err, uint8_t recv_state_count) @@ -251,9 +293,20 @@ static struct bt_bap_broadcast_assistant_cb cbs = { static int cmd_bap_broadcast_assistant_discover(const struct shell *sh, size_t argc, char **argv) { + static bool registered; int result; - bt_bap_broadcast_assistant_register_cb(&cbs); + if (!registered) { + static struct bt_le_per_adv_sync_cb cb = { + .recv = pa_recv, + }; + + bt_le_per_adv_sync_cb_register(&cb); + + bt_bap_broadcast_assistant_register_cb(&cbs); + + registered = true; + } result = bt_bap_broadcast_assistant_discover(default_conn); if (result) {