Bluetooth: CAP: Make unicast stop more similar to unicast start
Modify the parameters for bt_cap_initiator_unicast_audio_stop so that they are more similar to bt_cap_initiator_unicast_audio_start. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
ec549cebd5
commit
065253c173
7 changed files with 274 additions and 44 deletions
|
@ -255,6 +255,18 @@ struct bt_cap_unicast_audio_update_param {
|
|||
struct bt_cap_unicast_audio_update_stream_param *stream_params;
|
||||
};
|
||||
|
||||
/** Parameters for the bt_cap_initiator_unicast_audio_stop() function */
|
||||
struct bt_cap_unicast_audio_stop_param {
|
||||
/** The type of the set. */
|
||||
enum bt_cap_set_type type;
|
||||
|
||||
/** The number of streams in @p streams */
|
||||
size_t count;
|
||||
|
||||
/** Array of streams to stop */
|
||||
struct bt_cap_stream **streams;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register Common Audio Profile Initiator callbacks
|
||||
*
|
||||
|
@ -297,19 +309,19 @@ int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start
|
|||
int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param *param);
|
||||
|
||||
/**
|
||||
* @brief Stop unicast audio streams for a unicast group.
|
||||
* @brief Stop unicast audio streams.
|
||||
*
|
||||
* This will stop one or more streams.
|
||||
*
|
||||
* @note @kconfig{CONFIG_BT_CAP_INITIATOR} and
|
||||
* @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT} must be enabled for this function
|
||||
* to be enabled.
|
||||
*
|
||||
* @param unicast_group The group of unicast devices to stop. The audio streams
|
||||
* in this will be stopped and reset, and the
|
||||
* @p unicast_group will be invalidated.
|
||||
* @param param Stop parameters.
|
||||
*
|
||||
* @return 0 on success or negative error value on failure.
|
||||
*/
|
||||
int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_group);
|
||||
int bt_cap_initiator_unicast_audio_stop(const struct bt_cap_unicast_audio_stop_param *param);
|
||||
|
||||
/** @brief Cancel any current Common Audio Profile procedure
|
||||
*
|
||||
|
|
|
@ -1135,12 +1135,98 @@ static bool can_release(const struct bt_bap_stream *bap_stream)
|
|||
return ep_info.state != BT_BAP_EP_STATE_IDLE;
|
||||
}
|
||||
|
||||
int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_group)
|
||||
static bool valid_unicast_audio_stop_param(const struct bt_cap_unicast_audio_stop_param *param)
|
||||
{
|
||||
struct bt_bap_unicast_group *unicast_group = NULL;
|
||||
|
||||
CHECKIF(param == NULL) {
|
||||
LOG_DBG("param is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->count == 0) {
|
||||
LOG_DBG("Invalid param->count: %u", param->count);
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->streams == NULL) {
|
||||
LOG_DBG("param->streams is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
|
||||
LOG_DBG("param->count (%zu) is larger than "
|
||||
"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
|
||||
param->count, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < param->count; i++) {
|
||||
const struct bt_cap_stream *cap_stream = param->streams[i];
|
||||
const struct bt_bap_stream *bap_stream;
|
||||
struct bt_cap_common_client *client;
|
||||
struct bt_conn *conn;
|
||||
|
||||
CHECKIF(cap_stream == NULL) {
|
||||
LOG_DBG("param->streams[%zu] is NULL", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
bap_stream = &cap_stream->bap_stream;
|
||||
conn = bap_stream->conn;
|
||||
CHECKIF(conn == NULL) {
|
||||
LOG_DBG("param->streams[%zu]->bap_stream.conn is NULL", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client = bt_cap_common_get_client_by_acl(conn);
|
||||
if (!client->cas_found) {
|
||||
LOG_DBG("CAS was not found for param->streams[%zu]", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(bap_stream->group == NULL) {
|
||||
LOG_DBG("param->streams[%zu] is not in a unicast group", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Use the group of the first stream for comparison */
|
||||
if (unicast_group == NULL) {
|
||||
unicast_group = bap_stream->group;
|
||||
} else {
|
||||
CHECKIF(bap_stream->group != unicast_group) {
|
||||
LOG_DBG("param->streams[%zu] is not in this group %p", i,
|
||||
unicast_group);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_release(bap_stream)) {
|
||||
LOG_DBG("Cannot stop param->streams[%zu]", i);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t j = 0U; j < i; j++) {
|
||||
if (param->streams[j] == cap_stream) {
|
||||
LOG_DBG("param->stream_params[%zu] (%p) is "
|
||||
"duplicated by "
|
||||
"param->stream_params[%zu] (%p)",
|
||||
j, param->streams[j], i, cap_stream);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int bt_cap_initiator_unicast_audio_stop(const struct bt_cap_unicast_audio_stop_param *param)
|
||||
{
|
||||
struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
|
||||
struct bt_cap_initiator_proc_param *proc_param;
|
||||
struct bt_bap_stream *bap_stream;
|
||||
size_t stream_cnt;
|
||||
int err;
|
||||
|
||||
if (bt_cap_common_proc_is_active()) {
|
||||
|
@ -1149,28 +1235,17 @@ int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_gro
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
CHECKIF(unicast_group == NULL) {
|
||||
LOG_DBG("unicast_group is NULL");
|
||||
if (!valid_unicast_audio_stop_param(param)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_cnt = 0U;
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, bap_stream, _node) {
|
||||
if (can_release(bap_stream)) {
|
||||
struct bt_cap_stream *cap_stream =
|
||||
CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream);
|
||||
active_proc->proc_param.initiator[stream_cnt].stream = cap_stream;
|
||||
stream_cnt++;
|
||||
}
|
||||
for (size_t i = 0U; i < param->count; i++) {
|
||||
struct bt_cap_stream *cap_stream = param->streams[i];
|
||||
|
||||
active_proc->proc_param.initiator[i].stream = cap_stream;
|
||||
}
|
||||
|
||||
if (stream_cnt == 0U) {
|
||||
LOG_DBG("All streams are already stopped");
|
||||
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_STOP, stream_cnt);
|
||||
bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_STOP, param->count);
|
||||
|
||||
bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE);
|
||||
|
||||
|
|
|
@ -444,17 +444,75 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
static int cmd_cap_initiator_unicast_stop(const struct shell *sh, size_t argc,
|
||||
char *argv[])
|
||||
{
|
||||
struct bt_cap_stream *streams[CAP_UNICAST_CLIENT_STREAM_COUNT];
|
||||
struct bt_cap_unicast_audio_stop_param param = {0};
|
||||
int err = 0;
|
||||
|
||||
if (default_conn == NULL) {
|
||||
shell_error(sh, "Not connected");
|
||||
return -ENOEXEC;
|
||||
} else if (default_unicast_group == NULL) {
|
||||
shell_error(sh, "No unicast group started");
|
||||
}
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "all") == 0) {
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
|
||||
struct bt_cap_stream *stream = &unicast_streams[i].stream;
|
||||
struct bt_bap_ep_info ep_info;
|
||||
|
||||
if (stream->bap_stream.conn == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
err = bt_bap_ep_get_info(stream->bap_stream.ep, &ep_info);
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to get endpoint info: %d", err);
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
streams[param.count] = stream;
|
||||
param.count++;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (size_t i = 1U; i < argc; i++) {
|
||||
struct bt_cap_stream *stream = (void *)shell_strtoul(argv[i], 16, &err);
|
||||
struct bt_bap_ep_info ep_info;
|
||||
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to parse stream argument %s: %d", argv[i],
|
||||
err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!PART_OF_ARRAY(unicast_streams, stream)) {
|
||||
shell_error(sh, "Pointer %p is not a CAP stream pointer", stream);
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
err = bt_bap_ep_get_info(stream->bap_stream.ep, &ep_info);
|
||||
if (err != 0) {
|
||||
shell_error(sh, "Failed to get endpoint info: %d", err);
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
streams[param.count] = stream;
|
||||
param.count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (param.count == 0) {
|
||||
shell_error(sh, "No streams to update");
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(default_unicast_group);
|
||||
param.streams = streams;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(¶m);
|
||||
if (err != 0) {
|
||||
shell_print(sh, "Failed to update unicast audio: %d", err);
|
||||
}
|
||||
|
|
|
@ -405,16 +405,40 @@ static uint8_t btp_cap_unicast_audio_update(const void *cmd, uint16_t cmd_len,
|
|||
static uint8_t btp_cap_unicast_audio_stop(const void *cmd, uint16_t cmd_len,
|
||||
void *rsp, uint16_t *rsp_len)
|
||||
{
|
||||
|
||||
struct bt_cap_stream
|
||||
*streams[ARRAY_SIZE(btp_csip_set_members) * BTP_BAP_UNICAST_MAX_STREAMS_COUNT];
|
||||
struct bt_cap_unicast_audio_stop_param param = {0};
|
||||
int err;
|
||||
const struct btp_cap_unicast_audio_stop_cmd *cp = cmd;
|
||||
struct btp_bap_unicast_group *group;
|
||||
size_t stream_cnt = 0U;
|
||||
|
||||
LOG_DBG("");
|
||||
|
||||
group = btp_bap_unicast_group_find(cp->cig_id);
|
||||
/* Get generate the same stream list as used by btp_cap_unicast_audio_start */
|
||||
for (size_t conn_index = 0; conn_index < ARRAY_SIZE(btp_csip_set_members); conn_index++) {
|
||||
struct btp_bap_unicast_connection *u_conn = btp_bap_unicast_conn_get(conn_index);
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(group->cig);
|
||||
if (u_conn->end_points_count == 0) {
|
||||
/* Connection not initialized */
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(u_conn->streams); i++) {
|
||||
struct btp_bap_unicast_stream *u_stream = &u_conn->streams[i];
|
||||
|
||||
if (!u_stream->in_use || u_stream->cig_id != cp->cig_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
streams[stream_cnt++] = stream_unicast_to_cap(u_stream);
|
||||
}
|
||||
}
|
||||
|
||||
param.streams = streams;
|
||||
param.count = stream_cnt;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(¶m);
|
||||
if (err != 0) {
|
||||
LOG_ERR("Failed to start unicast audio: %d", err);
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ static struct bt_conn *connected_conns[CAP_AC_MAX_CONN];
|
|||
static size_t connected_conn_cnt;
|
||||
static const struct named_lc3_preset *snk_named_preset;
|
||||
static const struct named_lc3_preset *src_named_preset;
|
||||
static struct bt_cap_stream *non_idle_streams[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
|
||||
static size_t non_idle_streams_cnt;
|
||||
|
||||
CREATE_FLAG(flag_discovered);
|
||||
CREATE_FLAG(flag_codec_found);
|
||||
|
@ -106,8 +108,19 @@ static const struct named_lc3_preset lc3_unicast_presets[] = {
|
|||
static void unicast_stream_configured(struct bt_bap_stream *stream,
|
||||
const struct bt_audio_codec_qos_pref *pref)
|
||||
{
|
||||
struct bt_cap_stream *cap_stream = cap_stream_from_bap_stream(stream);
|
||||
printk("Configured stream %p\n", stream);
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(non_idle_streams); i++) {
|
||||
if (non_idle_streams[i] == NULL) {
|
||||
non_idle_streams[i] = cap_stream;
|
||||
non_idle_streams_cnt++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FAIL("Could not store cap_stream in non_idle_streams\n");
|
||||
|
||||
/* TODO: The preference should be used/taken into account when
|
||||
* setting the QoS
|
||||
*/
|
||||
|
@ -145,7 +158,19 @@ static void unicast_stream_stopped(struct bt_bap_stream *stream, uint8_t reason)
|
|||
|
||||
static void unicast_stream_released(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct bt_cap_stream *cap_stream = cap_stream_from_bap_stream(stream);
|
||||
|
||||
printk("Released stream %p\n", stream);
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(non_idle_streams); i++) {
|
||||
if (non_idle_streams[i] == cap_stream) {
|
||||
non_idle_streams[i] = NULL;
|
||||
non_idle_streams_cnt--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FAIL("Could not find cap_stream in non_idle_streams\n");
|
||||
}
|
||||
|
||||
static struct bt_bap_stream_ops unicast_stream_ops = {
|
||||
|
@ -347,6 +372,10 @@ static void init(void)
|
|||
for (size_t i = 0; i < ARRAY_SIZE(unicast_client_source_streams); i++) {
|
||||
bt_cap_stream_ops_register(&unicast_client_source_streams[i], &unicast_stream_ops);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(unicast_streams); i++) {
|
||||
bt_cap_stream_ops_register(&unicast_streams[i].stream, &unicast_stream_ops);
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
|
||||
|
@ -744,30 +773,35 @@ static void unicast_audio_stop_inval(void)
|
|||
|
||||
err = bt_cap_initiator_unicast_audio_stop(NULL);
|
||||
if (err == 0) {
|
||||
FAIL("bt_cap_initiator_unicast_audio_stop with NULL group did not fail\n");
|
||||
FAIL("bt_cap_initiator_unicast_audio_stop with NULL param did not fail\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void unicast_audio_stop(struct bt_bap_unicast_group *unicast_group)
|
||||
{
|
||||
struct bt_cap_unicast_audio_stop_param param;
|
||||
int err;
|
||||
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
param.count = non_idle_streams_cnt;
|
||||
param.streams = non_idle_streams;
|
||||
|
||||
UNSET_FLAG(flag_stopped);
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(unicast_group);
|
||||
err = bt_cap_initiator_unicast_audio_stop(¶m);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to start unicast audio: %d\n", err);
|
||||
FAIL("Failed to stop unicast audio: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
WAIT_FOR_FLAG(flag_stopped);
|
||||
|
||||
/* Verify that it cannot be stopped twice */
|
||||
err = bt_cap_initiator_unicast_audio_stop(unicast_group);
|
||||
err = bt_cap_initiator_unicast_audio_stop(¶m);
|
||||
if (err == 0) {
|
||||
FAIL("bt_cap_initiator_unicast_audio_stop with already-stopped unicast group did "
|
||||
"not fail\n");
|
||||
FAIL("bt_cap_initiator_unicast_audio_stop with already-stopped streams did not "
|
||||
"fail\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,16 @@ struct audio_test_stream {
|
|||
size_t rx_cnt;
|
||||
};
|
||||
|
||||
static inline struct bt_cap_stream *cap_stream_from_bap_stream(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
return CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream);
|
||||
}
|
||||
|
||||
static inline struct bt_bap_stream *bap_stream_from_cap_stream(struct bt_cap_stream *cap_stream)
|
||||
{
|
||||
return &cap_stream->bap_stream;
|
||||
}
|
||||
|
||||
static inline struct audio_test_stream *
|
||||
audio_test_stream_from_cap_stream(struct bt_cap_stream *cap_stream)
|
||||
{
|
||||
|
@ -148,10 +158,7 @@ audio_test_stream_from_cap_stream(struct bt_cap_stream *cap_stream)
|
|||
static inline struct audio_test_stream *
|
||||
audio_test_stream_from_bap_stream(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
struct bt_cap_stream *cap_stream =
|
||||
CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream);
|
||||
|
||||
return audio_test_stream_from_cap_stream(cap_stream);
|
||||
return audio_test_stream_from_cap_stream(cap_stream_from_bap_stream(bap_stream));
|
||||
}
|
||||
|
||||
static inline struct bt_cap_stream *
|
||||
|
@ -163,7 +170,7 @@ cap_stream_from_audio_test_stream(struct audio_test_stream *test_stream)
|
|||
static inline struct bt_bap_stream *
|
||||
bap_stream_from_audio_test_stream(struct audio_test_stream *test_stream)
|
||||
{
|
||||
return &cap_stream_from_audio_test_stream(test_stream)->bap_stream;
|
||||
return bap_stream_from_cap_stream(cap_stream_from_audio_test_stream(test_stream));
|
||||
}
|
||||
|
||||
#endif /* ZEPHYR_TEST_BSIM_BT_AUDIO_TEST_ */
|
||||
|
|
|
@ -106,6 +106,8 @@ struct named_lc3_preset named_preset;
|
|||
|
||||
static struct audio_test_stream broadcast_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
|
||||
static struct unicast_stream unicast_streams[GMAP_UNICAST_AC_MAX_STREAM];
|
||||
static struct bt_cap_stream *started_unicast_streams[GMAP_UNICAST_AC_MAX_STREAM];
|
||||
static size_t started_unicast_streams_cnt;
|
||||
static struct bt_bap_ep
|
||||
*sink_eps[GMAP_UNICAST_AC_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
|
||||
static struct bt_bap_ep
|
||||
|
@ -685,6 +687,7 @@ static int gmap_ac_cap_unicast_start(const struct gmap_unicast_ac_param *param,
|
|||
size_t stream_cnt = 0U;
|
||||
size_t snk_ep_cnt = 0U;
|
||||
size_t src_ep_cnt = 0U;
|
||||
int err;
|
||||
|
||||
for (size_t i = 0U; i < param->conn_cnt; i++) {
|
||||
#if UNICAST_SINK_SUPPORTED
|
||||
|
@ -797,7 +800,16 @@ static int gmap_ac_cap_unicast_start(const struct gmap_unicast_ac_param *param,
|
|||
start_param.count = stream_cnt;
|
||||
start_param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
return bt_cap_initiator_unicast_audio_start(&start_param);
|
||||
err = bt_cap_initiator_unicast_audio_start(&start_param);
|
||||
if (err == 0) {
|
||||
for (size_t i = 0U; i < start_param.count; i++) {
|
||||
started_unicast_streams[i] = start_param.stream_params[i].stream;
|
||||
}
|
||||
|
||||
started_unicast_streams_cnt = start_param.count;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gmap_ac_unicast(const struct gmap_unicast_ac_param *param,
|
||||
|
@ -887,17 +899,25 @@ static int gmap_ac_unicast(const struct gmap_unicast_ac_param *param,
|
|||
|
||||
static void unicast_audio_stop(struct bt_bap_unicast_group *unicast_group)
|
||||
{
|
||||
struct bt_cap_unicast_audio_stop_param param;
|
||||
int err;
|
||||
|
||||
UNSET_FLAG(flag_stopped);
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(unicast_group);
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
param.count = started_unicast_streams_cnt;
|
||||
param.streams = started_unicast_streams;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_stop(¶m);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to start unicast audio: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
WAIT_FOR_FLAG(flag_stopped);
|
||||
|
||||
started_unicast_streams_cnt = 0U;
|
||||
memset(started_unicast_streams, 0, sizeof(started_unicast_streams));
|
||||
}
|
||||
|
||||
static void unicast_group_delete(struct bt_bap_unicast_group *unicast_group)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue