apps/btshell: Add Audio Broadcast Sink to shell application

this extends the btshell application with Audio Broadcast Sink
functionality.
This commit is contained in:
Mariusz Skamra
2024-07-01 11:41:11 +02:00
committed by Łukasz Rymanowski
parent cf42d74a70
commit 868ecb0bdb
9 changed files with 830 additions and 5 deletions
+2
View File
@@ -222,6 +222,8 @@ int btshell_broadcast_start(uint8_t adv_instance);
int btshell_broadcast_stop(uint8_t adv_instance);
#endif
void btshell_leaudio_init(void);
int btshell_gap_event(struct ble_gap_event *event, void *arg);
void btshell_sync_stats(uint16_t handle);
uint8_t btshell_get_default_own_addr_type(void);
+83 -3
View File
@@ -87,14 +87,28 @@ static const struct parse_arg_kv_pair cmd_peer_addr_types[] = {
{ NULL }
};
static const struct parse_arg_kv_pair cmd_addr_type[] = {
const struct parse_arg_kv_pair cmd_addr_type[] = {
{ "public", BLE_ADDR_PUBLIC },
{ "random", BLE_ADDR_RANDOM },
{ NULL }
};
const char *
cmd_addr_type_str(uint8_t type)
{
const struct parse_arg_kv_pair *kvs = cmd_addr_type;
int i;
static int
for (i = 0; kvs[i].key != NULL; i++) {
if (type == kvs[i].val) {
return kvs[i].key;
}
}
return "unknown";
}
int
parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types,
ble_addr_t *addr)
{
@@ -152,6 +166,12 @@ parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types,
return 0;
}
int
cmd_parse_addr(const char *prefix, ble_addr_t *addr)
{
return parse_dev_addr(prefix, cmd_addr_type, addr);
}
/*****************************************************************************
* $advertise *
*****************************************************************************/
@@ -4924,7 +4944,67 @@ static const struct shell_cmd btshell_commands[] = {
.help = &leaudio_broadcast_stop_help,
#endif
},
#endif /* BLE_ISO_BROADCAST_SOURCE */
#endif
#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK)
{
.sc_cmd = "broadcast-sink-start",
.sc_cmd_func = cmd_leaudio_broadcast_sink_start,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_broadcast_sink_start_help,
#endif
},
{
.sc_cmd = "broadcast-sink-stop",
.sc_cmd_func = cmd_leaudio_broadcast_sink_stop,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_broadcast_sink_stop_help,
#endif
},
{
.sc_cmd = "broadcast-sink-metadata",
.sc_cmd_func = cmd_leaudio_broadcast_sink_metadata_update,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_broadcast_sink_metadata_update_help,
#endif
},
#endif /* BLE_AUDIO_BROADCAST_SINK */
#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR)
{
.sc_cmd = "scan-delegator-add",
.sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_add,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_scan_delegator_receive_state_add_help,
#endif
},
{
.sc_cmd = "scan-delegator-remove",
.sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_remove,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_scan_delegator_receive_state_remove_help,
#endif
},
{
.sc_cmd = "scan-delegator-set",
.sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_set,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_scan_delegator_receive_state_set_help,
#endif
},
{
.sc_cmd = "scan-delegator-get",
.sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_get,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_scan_delegator_receive_state_get_help,
#endif
},
{
.sc_cmd = "scan-delegator-show",
.sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_show,
#if MYNEWT_VAL(SHELL_CMD_HELP)
.help = &cmd_leaudio_scan_delegator_receive_state_show_help,
#endif
},
#endif /* BLE_AUDIO_SCAN_DELEGATOR */
#if MYNEWT_VAL(BLE_ISO)
#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)
{
+7
View File
@@ -30,6 +30,13 @@ int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body,
int cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start,
uint16_t *out_end);
int parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types,
ble_addr_t *addr);
int cmd_parse_addr(const char *prefix, ble_addr_t *addr);
const char *cmd_addr_type_str(uint8_t type);
void cmd_init(void);
#endif
+704 -1
View File
@@ -20,9 +20,13 @@
#include "cmd_leaudio.h"
#include "btshell.h"
#include "console/console.h"
#include "shell/shell.h"
#include "bsp/bsp.h"
#include "errno.h"
#if (MYNEWT_VAL(BLE_AUDIO))
#define STR_NULL "null"
#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE))
#include "audio/ble_audio_broadcast_source.h"
int
cmd_leaudio_base_add(int argc, char **argv)
@@ -382,4 +386,703 @@ cmd_leaudio_broadcast_stop(int argc, char **argv)
return btshell_broadcast_stop(adv_instance);
}
#endif /* BLE_ISO_BROADCAST_SOURCE */
#if (MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK))
#include "audio/ble_audio_broadcast_sink.h"
#define BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT 0x07D0
static int
broadcast_sink_pa_sync_params_get(struct ble_gap_periodic_sync_params *params)
{
params->skip = 0;
params->sync_timeout = BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT;
params->reports_disabled = false;
return 0;
}
static void
codec_specific_config_printf(const struct ble_audio_codec_id *unused, const uint8_t *data,
uint8_t len)
{
console_printf("data=%p len=%u\n", data, len);
}
static void
base_bis_printf(const struct ble_audio_codec_id *codec_id, const struct ble_audio_base_bis *bis)
{
console_printf("BISCodecConfig:\n\t");
codec_specific_config_printf(codec_id,bis->codec_spec_config, bis->codec_spec_config_len);
}
static void
metadata_printf(const uint8_t *data, uint8_t len)
{
console_printf("data=%p len=%u\n", data, len);
}
static void
base_subgroup_printf(uint8_t subgroup_index, const struct ble_audio_base_subgroup *subgroup)
{
console_printf("subgroup_index=%u\n", subgroup_index);
console_printf("Codec ID:\n\tformat=0x%02x company_id=0x%04x vendor_specific=0x%02x\n",
subgroup->codec_id.format, subgroup->codec_id.company_id,
subgroup->codec_id.vendor_specific);
console_printf("SubgroupCodecConfig:\n\t");
codec_specific_config_printf(&subgroup->codec_id,
subgroup->codec_spec_config,
subgroup->codec_spec_config_len);
console_printf("Metadata:\n\t");
metadata_printf(subgroup->metadata, subgroup->metadata_len);
}
static int
broadcast_sink_disc_start(const struct ble_gap_ext_disc_params *params)
{
uint8_t own_addr_type;
int rc;
/* Figure out address to use while scanning. */
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
console_printf("determining own address type failed (%d)", rc);
assert(0);
}
rc = ble_gap_ext_disc(own_addr_type, 0, 0, 0, 0, 0, params, NULL, NULL, NULL);
if (rc != 0) {
console_printf("ext disc failed (%d)", rc);
}
return rc;
}
static int
broadcast_sink_disc_stop(void)
{
int rc;
rc = ble_gap_disc_cancel();
if (rc != 0) {
console_printf("disc cancel failed (%d)", rc);
}
return rc;
}
static int
broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *arg)
{
switch (action->type) {
case BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC:
console_printf("PA Sync:\n");
return broadcast_sink_pa_sync_params_get(action->pa_sync.out_params);
case BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC:
console_printf("BIG Sync:\nsource_id=0x%02x iso_interval=0x%04x"
" presentation_delay=%u[us]\n",
action->big_sync.source_id, action->big_sync.iso_interval,
action->big_sync.presentation_delay);
break;
case BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC:
console_printf("BIS Sync:\n\tsource_id=0x%02x bis_index=0x%02x\n",
action->bis_sync.source_id, action->bis_sync.bis->index);
base_subgroup_printf(action->bis_sync.subgroup_index, action->bis_sync.subgroup);
base_bis_printf(&action->bis_sync.subgroup->codec_id, action->bis_sync.bis);
return 0;
case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_START:
return broadcast_sink_disc_start(action->disc_start.params_preferred);
case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_STOP:
return broadcast_sink_disc_stop();
default:
assert(false);
return ENOTSUP;
}
return 0;
}
static const struct shell_param cmd_leaudio_broadcast_sink_start_params[] = {
{"source_id", "usage: =<UINT8>"},
{"broadcast_code", "usage: =[string], default: NULL"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help = {
.summary = "Start audio Broadcast Sink",
.usage = NULL,
.params = cmd_leaudio_broadcast_sink_start_params
};
#endif
int
cmd_leaudio_broadcast_sink_start(int argc, char **argv)
{
struct ble_audio_broadcast_sink_add_params params = {0};
char *broadcast_code;
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
broadcast_code = parse_arg_extract("broadcast_code");
if (broadcast_code != NULL) {
strncpy((char *)params.broadcast_code, broadcast_code, BLE_AUDIO_BROADCAST_CODE_SIZE);
params.broadcast_code_is_valid = true;
}
rc = ble_audio_broadcast_sink_start(source_id, &params);
if (rc != 0) {
console_printf("start failed (%d)\n", rc);
}
return rc;
}
static const struct shell_param cmd_leaudio_broadcast_sink_stop_params[] = {
{"source_id", "usage: =<UINT8>"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help = {
.summary = "Stop audio Broadcast Sink",
.usage = NULL,
.params = cmd_leaudio_broadcast_sink_stop_params
};
#endif
int
cmd_leaudio_broadcast_sink_stop(int argc, char **argv)
{
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
rc = ble_audio_broadcast_sink_stop(source_id);
if (rc != 0) {
console_printf("stop failed (%d)\n", rc);
}
return rc;
}
static const struct shell_param cmd_leaudio_broadcast_sink_metadata_update_params[] = {
{"source_id", "usage: =<UINT8>"},
{"subgroup_index", "usage: =<UINT8>"},
{"metadata", "usage: =[XX:XX...]"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help = {
.summary = "Update Broadcast Sink metadata",
.usage = NULL,
.params = cmd_leaudio_broadcast_sink_metadata_update_params
};
#endif
int
cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv)
{
struct ble_audio_broadcast_sink_metadata_update_params params = {0};
static bssnz_t uint8_t metadata[UINT8_MAX];
unsigned int metadata_len;
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
params.subgroup_index = parse_arg_uint8("subgroup_index", &rc);
if (rc != 0) {
console_printf("invalid 'subgroup_index' parameter\n");
return rc;
}
rc = parse_arg_byte_stream("metadata", UINT8_MAX, metadata, &metadata_len);
if (rc == 0) {
params.metadata = metadata;
params.metadata_length = metadata_len;
} else if (rc != ENOENT) {
console_printf("invalid 'metadata' parameter\n");
return rc;
}
rc = ble_audio_broadcast_sink_metadata_update(source_id, &params);
if (rc != 0) {
console_printf("metadata update failed (%d)\n", rc);
}
return rc;
}
static int
broadcast_sink_audio_event_handler(struct ble_audio_event *event, void *arg)
{
switch (event->type) {
case BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE:
console_printf("source_id=0x%02x PA sync: %s\n",
event->broadcast_sink_pa_sync_state.source_id,
ble_audio_broadcast_sink_sync_state_str(
event->broadcast_sink_pa_sync_state.state));
break;
case BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE:
console_printf("source_id=0x%02x bis_index=0x%02x BIS sync: %s\n",
event->broadcast_sink_bis_sync_state.source_id,
event->broadcast_sink_bis_sync_state.bis_index,
ble_audio_broadcast_sink_sync_state_str(
event->broadcast_sink_bis_sync_state.state));
if (event->broadcast_sink_bis_sync_state.state ==
BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED) {
console_printf("conn_handle=0x%04x\n",
event->broadcast_sink_bis_sync_state.conn_handle);
}
break;
default:
break;
}
return 0;
}
#endif /* BLE_AUDIO_BROADCAST_SINK */
#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR)
#include "audio/ble_audio_scan_delegator.h"
static void
scan_delegator_source_desc_printf(const struct ble_audio_scan_delegator_source_desc *source_desc)
{
console_printf("broadcast_id=0x%6x adv_sid=%d adv_addr_type=%s adv_addr=",
source_desc->broadcast_id, source_desc->adv_sid,
cmd_addr_type_str(source_desc->addr.type));
print_addr(source_desc->addr.val);
console_printf("\n");
}
static void
scan_delegator_sync_opt_printf(const struct ble_audio_scan_delegator_sync_opt *sync_opt)
{
console_printf("pa_sync=%d pa_interval=0x%04x num_subgroups=%d",
sync_opt->pa_sync, sync_opt->pa_interval, sync_opt->num_subgroups);
for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) {
console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=",
sync_opt->subgroups[i].bis_sync, sync_opt->subgroups[i].metadata_length);
print_bytes(sync_opt->subgroups[i].metadata, sync_opt->subgroups[i].metadata_length);
}
console_printf("\n");
}
static int
scan_delegator_pick_source_id_to_swap(uint8_t *out_source_id_to_swap)
{
/* TODO: Add some logic here */
*out_source_id_to_swap = 0;
return 0;
}
static int
scan_delegator_action_fn(struct ble_audio_scan_delegator_action *action, void *arg)
{
switch (action->type) {
case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD:
console_printf("Source Add:\nsource_id=%u\n", action->source_add.source_id);
scan_delegator_source_desc_printf(&action->source_add.source_desc);
scan_delegator_sync_opt_printf(&action->source_add.sync_opt);
if (action->source_add.out_source_id_to_swap == NULL) {
return 0;
} else {
return scan_delegator_pick_source_id_to_swap(action->source_add.out_source_id_to_swap);
}
case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY:
console_printf("Source Modify:\nsource_id=%u\n", action->source_modify.source_id);
scan_delegator_sync_opt_printf(&action->source_modify.sync_opt);
break;
case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE:
console_printf("Source Remove:\nsource_id=%u\n", action->source_remove.source_id);
break;
default:
assert(false);
return ENOTSUP;
}
return 0;
}
static const struct shell_param cmd_leaudio_scan_delegator_receive_state_add_params[] = {
{"addr_type", "usage: =[public|random], default: public"},
{"addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
{"broadcast_id", "usage: =[0-0xFFFFFF]"},
{"adv_sid", "usage: =[UINT8], default: 0"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help = {
.summary = "Add receive state",
.usage = NULL,
.params = cmd_leaudio_scan_delegator_receive_state_add_params
};
#endif /* SHELL_CMD_HELP */
int
cmd_leaudio_scan_delegator_receive_state_add(int argc, char **argv)
{
struct ble_audio_scan_delegator_receive_state_add_params params = {0};
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
rc = cmd_parse_addr(NULL, &params.source_desc.addr);
if (rc != 0) {
console_printf("invalid 'adv_addr' parameter\n");
return rc;
}
params.source_desc.broadcast_id = parse_arg_uint32("broadcast_id", &rc);
if (rc != 0) {
console_printf("invalid 'broadcast_id' parameter\n");
return rc;
}
params.source_desc.adv_sid = parse_arg_uint8_dflt("adv_sid", 0, &rc);
if (rc != 0) {
console_printf("invalid 'adv_sid' parameter\n");
return rc;
}
rc = ble_audio_scan_delegator_receive_state_add(&params, &source_id);
if (rc != 0) {
console_printf("Failed to add receive state (%d)\n", rc);
} else {
console_printf("New source_id=%u created\n", source_id);
}
return rc;
}
static const struct shell_param cmd_leaudio_scan_delegator_receive_state_remove_params[] = {
{"source_id", "usage: =<UINT8>"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help = {
.summary = "Remove receive state",
.usage = NULL,
.params = cmd_leaudio_scan_delegator_receive_state_remove_params
};
#endif /* SHELL_CMD_HELP */
int
cmd_leaudio_scan_delegator_receive_state_remove(int argc, char **argv)
{
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
rc = ble_audio_scan_delegator_receive_state_remove(source_id);
if (rc != 0) {
console_printf("remove failed (%d)\n", rc);
}
return rc;
}
const struct parse_arg_kv_pair cmd_pa_sync_type[] = {
{ "not_synced", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED },
{ "sync_info_req", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNC_INFO_REQ },
{ "synced", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNCED },
{ "failed", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_ERROR },
{ "no_past", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NO_PAST },
{ NULL }
};
const struct parse_arg_kv_pair cmd_big_enc_type[] = {
{ "not_encrypted", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE },
{ "code_req", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_MISSING },
{ "decrypting", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_DECRYPTING },
{ "bad_code", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID },
{ NULL }
};
static const struct shell_param cmd_leaudio_scan_delegator_receive_state_set_params[] = {
{"source_id", "usage: =<UINT8>"},
{"pa_sync_state", "usage: =[not_synced|sync_info_req|synced|failed|no_past],"
" default: not_synced"},
{"big_enc", "usage: =[not_encrypted|code_req|decrypting|bad_code],"
" default: not_encrypted"},
{"bad_code", "usage: =[string], default: NULL"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_set_help = {
.summary = "Set receive state",
.usage = NULL,
.params = cmd_leaudio_scan_delegator_receive_state_set_params
};
#endif /* SHELL_CMD_HELP */
int
cmd_leaudio_scan_delegator_receive_state_set(int argc, char **argv)
{
struct ble_audio_scan_delegator_receive_state state = {0};
char *bad_code;
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
state.pa_sync_state = parse_arg_kv_dflt("pa_sync_state", cmd_pa_sync_type,
BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED, &rc);
if (rc != 0) {
console_printf("invalid 'pa_sync_state' parameter\n");
return rc;
}
state.big_enc = parse_arg_kv_dflt("big_enc", cmd_big_enc_type,
BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE, &rc);
if (rc != 0) {
console_printf("invalid 'big_enc' parameter\n");
return rc;
}
bad_code = parse_arg_extract("bad_code");
if (bad_code != NULL) {
strncpy((char *)state.bad_code, bad_code, BLE_AUDIO_BROADCAST_CODE_SIZE);
}
/* TODO: initialize state.subgroups */
state.num_subgroups = 0;
rc = ble_audio_scan_delegator_receive_state_set(source_id, &state);
if (rc != 0) {
console_printf("set failed (%d)\n", rc);
}
return rc;
}
static const char *
pa_sync_type_str(enum ble_audio_scan_delegator_pa_sync_state pa_sync_state)
{
for (size_t i = 0; i < ARRAY_SIZE(cmd_pa_sync_type); i++) {
if (cmd_pa_sync_type[i].val == pa_sync_state) {
return cmd_pa_sync_type[i].key;
}
}
return STR_NULL;
}
static const char *
big_enc_type_str(enum ble_audio_scan_delegator_big_enc big_enc)
{
for (size_t i = 0; i < ARRAY_SIZE(cmd_big_enc_type); i++) {
if (cmd_big_enc_type[i].val == big_enc) {
return cmd_big_enc_type[i].key;
}
}
return STR_NULL;
}
static void
scan_delegator_receive_state_printf(const struct ble_audio_scan_delegator_receive_state *state)
{
console_printf("pa_sync_state=%s big_enc=%s num_subgroups=%d",
pa_sync_type_str(state->pa_sync_state), big_enc_type_str(state->big_enc),
state->num_subgroups);
if (state->big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) {
console_printf("bad_code=");
print_bytes(state->bad_code, sizeof(state->bad_code));
console_printf("\n");
}
for (uint8_t i = 0; i < state->num_subgroups; i++) {
console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=",
state->subgroups[i].bis_sync, state->subgroups[i].metadata_length);
print_bytes(state->subgroups[i].metadata, state->subgroups[i].metadata_length);
console_printf("\n");
}
}
static const struct shell_param cmd_leaudio_scan_delegator_receive_state_get_params[] = {
{"source_id", "usage: =<UINT8>"},
{NULL, NULL}
};
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_get_help = {
.summary = "Get receive state",
.usage = NULL,
.params = cmd_leaudio_scan_delegator_receive_state_get_params
};
#endif /* SHELL_CMD_HELP */
int
cmd_leaudio_scan_delegator_receive_state_get(int argc, char **argv)
{
struct ble_audio_scan_delegator_receive_state state = {0};
uint8_t source_id;
int rc;
rc = parse_arg_init(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
source_id = parse_arg_uint8("source_id", &rc);
if (rc != 0) {
console_printf("invalid 'source_id' parameter\n");
return rc;
}
rc = ble_audio_scan_delegator_receive_state_get(source_id, &state);
if (rc != 0) {
console_printf("get failed (%d)\n", rc);
} else {
console_printf("source_id=%u\n", source_id);
scan_delegator_receive_state_printf(&state);
}
return rc;
}
static int
scan_delegator_receive_state_foreach_fn(struct ble_audio_scan_delegator_receive_state_entry *entry,
void *arg)
{
console_printf("source_id=%u\n", entry->source_id);
scan_delegator_source_desc_printf(&entry->source_desc);
scan_delegator_receive_state_printf(&entry->state);
return 0;
}
#if MYNEWT_VAL(SHELL_CMD_HELP)
const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_show_help = {
.summary = "List receive states",
.usage = NULL,
.params = NULL
};
#endif /* SHELL_CMD_HELP */
int
cmd_leaudio_scan_delegator_receive_state_show(int argc, char **argv)
{
uint8_t num_entries = 0;
ble_audio_scan_delegator_receive_state_foreach(scan_delegator_receive_state_foreach_fn,
&num_entries);
if (num_entries == 0) {
console_printf("No receive state\n");
}
return 0;
}
static int
scan_delegator_audio_event_handler(struct ble_audio_event *event, void *arg)
{
switch (event->type) {
case BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT:
console_printf("Broadcast Announcement\n");
console_printf("broadcast_id=0x%6x adv_sid=%d addr_type=%s addr=",
event->broadcast_announcement.broadcast_id,
event->broadcast_announcement.ext_disc->sid,
cmd_addr_type_str(event->broadcast_announcement.ext_disc->addr.type));
print_addr(event->broadcast_announcement.ext_disc->addr.val);
console_printf("\n");
break;
default:
break;
}
return 0;
}
#endif /* BLE_AUDIO_SCAN_DELEGATOR */
void
btshell_leaudio_init(void)
{
int rc = 0;
#if (MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR))
static struct ble_audio_event_listener scan_delegator_listener;
rc = ble_audio_scan_delegator_action_fn_set(scan_delegator_action_fn, NULL);
assert(rc == 0);
rc = ble_audio_event_listener_register(&scan_delegator_listener,
scan_delegator_audio_event_handler, NULL);
assert(rc == 0);
#endif /* BLE_AUDIO_SCAN_DELEGATOR */
#if (MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK))
static struct ble_audio_event_listener broadcast_sink_listener;
rc = ble_audio_broadcast_sink_cb_set(broadcast_sink_action_fn, NULL);
assert(rc == 0);
rc = ble_audio_event_listener_register(&broadcast_sink_listener,
broadcast_sink_audio_event_handler, NULL);
#endif /* BLE_AUDIO_BROADCAST_SINK */
assert(rc == 0);
}
+20
View File
@@ -43,4 +43,24 @@ int cmd_leaudio_broadcast_update(int argc, char **argv);
int cmd_leaudio_broadcast_start(int argc, char **argv);
int cmd_leaudio_broadcast_stop(int argc, char **argv);
extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help;
extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help;
extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help;
int cmd_leaudio_broadcast_sink_start(int argc, char **argv);
int cmd_leaudio_broadcast_sink_stop(int argc, char **argv);
int cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv);
extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help;
extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help;
extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_set_help;
extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_get_help;
extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_show_help;
int cmd_leaudio_scan_delegator_receive_state_add(int argc, char **argv);
int cmd_leaudio_scan_delegator_receive_state_remove(int argc, char **argv);
int cmd_leaudio_scan_delegator_receive_state_set(int argc, char **argv);
int cmd_leaudio_scan_delegator_receive_state_get(int argc, char **argv);
int cmd_leaudio_scan_delegator_receive_state_show(int argc, char **argv);
#endif /* H_CMD_LEAUDIO_ */
+6
View File
@@ -2078,6 +2078,10 @@ btshell_ext_scan(uint8_t own_addr_type, uint16_t duration, uint16_t period,
const struct ble_gap_ext_disc_params *coded_params,
void *cb_args)
{
struct btshell_scan_opts *scan_opts = cb_args;
console_printf("silent %d.", scan_opts->silent);
#if !MYNEWT_VAL(BLE_EXT_ADV)
console_printf("BLE extended advertising not supported.");
console_printf(" Configure nimble host to enable it\n");
@@ -3143,6 +3147,8 @@ mynewt_main(int argc, char **argv)
btshell_init_ext_adv_restart();
btshell_leaudio_init();
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
+3
View File
@@ -50,3 +50,6 @@ syscfg.vals:
syscfg.vals.BLE_MESH:
MSYS_1_BLOCK_COUNT: 16
syscfg.vals.BLE_AUDIO_BROADCAST_SINK:
BLE_AUDIO_BROADCAST_SINK_MAX: 1
@@ -24,3 +24,4 @@ pkg.description: Target for native btshell application with LE Audio
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.deps:
- nimble/host/audio
@@ -30,7 +30,7 @@ syscfg.vals:
# Disable security manager (pairing and bonding).
BLE_SM_LEGACY: 0
BLE_SM_SC: 0
BLE_SM_SC: 1
# Default task settings
OS_MAIN_STACK_SIZE: 512
@@ -64,6 +64,9 @@ syscfg.vals:
BLE_ISO_MAX_BIGS: 1
BLE_ISO_MAX_BISES: 2
BLE_AUDIO_BROADCAST_SINK: 1
BLE_AUDIO_SCAN_DELEGATOR: 1
CONSOLE_UART: 1
CONSOLE_UART_BAUD: 1000000
CONSOLE_STICKY_PROMPT: 1