mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-11-13 16:00:34 +00:00
apps/btshell: Add Audio Broadcast Sink to shell application
this extends the btshell application with Audio Broadcast Sink functionality.
This commit is contained in:
committed by
Łukasz Rymanowski
parent
cf42d74a70
commit
868ecb0bdb
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
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, ¶ms.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(¶ms, &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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user