Skip to content

Commit

Permalink
Bluetooth: ascs: Add dynamic ASE registration
Browse files Browse the repository at this point in the history
Added option to set the ASE count through the bap API, making ASE
configuration runtime available. The upper limit of ASEs are still
bound by the Kconfig options set for ASEs.

Signed-off-by: Fredrik Danebjer <[email protected]>
  • Loading branch information
fredrikdanebjer authored and nashif committed Sep 11, 2024
1 parent 442a068 commit c9da274
Show file tree
Hide file tree
Showing 39 changed files with 1,017 additions and 175 deletions.
2 changes: 1 addition & 1 deletion doc/connectivity/bluetooth/api/audio/shell/bap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Commands
bap --help
Subcommands:
init
init : [ase_sink_count, ase_source_count]
select_broadcast : <stream>
create_broadcast : [preset <preset_name>] [enc <broadcast_code>]
start_broadcast :
Expand Down
13 changes: 13 additions & 0 deletions doc/releases/migration-guide-4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,19 @@ Bluetooth Audio
This needs to be added to all instances of VCP Volume Renderer callback functions defined.
(:github:`76992`)

* The Unicast Server has a new registration function :c:func:`bt_bap_unicast_server_register` which
takes a :c:struct:`bt_bap_unicast_server_register_param` as argument. This allows the Unicast
Server to dynamically register Source and Sink ASE count at runtime. The old
:kconfig:option:`CONFIG_BT_ASCS_ASE_SRC_COUNT` and :kconfig:option:`CONFIG_BT_ASCS_ASE_SNK_COUNT`
has been renamed to :kconfig:option:`CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT` and
:kconfig:option:`CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT` to reflect that they now serve as a
compile-time maximum configuration of ASEs to be used.
:c:func:`bt_bap_unicast_server_register` needs to be called once before using the Unicast Server,
and more specfically prior to calling :c:func:`bt_bap_unicast_server_register_cb` for the first
time. It does not need to be called again until the new function
:c:func:`bt_bap_unicast_server_unregister` has been called.
(:github:`76632`)

Bluetooth Classic
=================

Expand Down
49 changes: 49 additions & 0 deletions include/zephyr/bluetooth/audio/bap.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,22 @@ struct bt_bap_stream_ops {
void (*disconnected)(struct bt_bap_stream *stream, uint8_t reason);
};

/** Structure for registering Unicast Server */
struct bt_bap_unicast_server_register_param {
/**
* @brief Sink Count to register.
*
* Should be in range [0, @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT}]
*/
uint8_t snk_cnt;

/** @brief Source Count to register.
*
* Should be in range [0, @kconfig{CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT}]
*/
uint8_t src_cnt;
};

/**
* @brief Register Audio callbacks for a stream.
*
Expand Down Expand Up @@ -1019,11 +1035,41 @@ struct bt_bap_unicast_server_cb {
int (*release)(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp);
};

/**
* @brief Register the Unicast Server.
*
* Register the Unicast Server. Only a single Unicast Server can be registered at any one time.
* This will register ASCS in the GATT database.
*
* @param param Registration parameters for ascs.
*
* @return 0 in case of success, negative error code otherwise.
*/
int bt_bap_unicast_server_register(const struct bt_bap_unicast_server_register_param *param);

/**
* @brief Unregister the Unicast Server.
*
* Unregister the Unicast Server.
* This will unregister ASCS in the GATT database.
* Before calling this function, any callbacks registered through
* bt_bap_unicast_server_register_cb() needs to be unregistered with
* bt_bap_unicast_server_unregister_cb().
*
* Calling this function will issue an release operation on any ASE
* in a non-idle state.
*
* @return 0 in case of success, negative error code otherwise.
*/
int bt_bap_unicast_server_unregister(void);

/**
* @brief Register unicast server callbacks.
*
* Only one callback structure can be registered, and attempting to
* registering more than one will result in an error.
* Prior to calling this function the Unicast Server needs to be
* registered with bt_bap_unicast_server_register().
*
* @param cb Unicast server callback structure.
*
Expand All @@ -1037,6 +1083,9 @@ int bt_bap_unicast_server_register_cb(const struct bt_bap_unicast_server_cb *cb)
* May only unregister a callback structure that has previously been
* registered by bt_bap_unicast_server_register_cb().
*
* Calling this function will issue an release operation on any ASE
* in a non-idle state.
*
* @param cb Unicast server callback structure.
*
* @return 0 in case of success or negative value in case of error.
Expand Down
8 changes: 4 additions & 4 deletions include/zephyr/bluetooth/audio/gmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ enum bt_gmap_ugt_feat {
/**
* @brief Source support
*
* Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 0
* Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 0
*/
BT_GMAP_UGT_FEAT_SOURCE = BIT(0),
/**
Expand All @@ -101,7 +101,7 @@ enum bt_gmap_ugt_feat {
/**
* @brief Sink support
*
* Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 0
* Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 0
*/
BT_GMAP_UGT_FEAT_SINK = BIT(2),
/**
Expand All @@ -119,14 +119,14 @@ enum bt_gmap_ugt_feat {
/**
* @brief Support for receiving at least two audio channels, each in a separate CIS
*
* Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 1 and
* Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 1 and
* @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SINK to be set as well
*/
BT_GMAP_UGT_FEAT_MULTISINK = BIT(5),
/**
* @brief Support for sending at least two audio channels, each in a separate CIS
*
* Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 1 and
* Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 1 and
* @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SOURCE to be set
* as well
*/
Expand Down
4 changes: 2 additions & 2 deletions samples/bluetooth/bap_unicast_server/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ CONFIG_BT_ISO_PERIPHERAL=y
CONFIG_BT_AUDIO=y
CONFIG_BT_BAP_UNICAST_SERVER=y
CONFIG_BT_ASCS=y
CONFIG_BT_ASCS_ASE_SNK_COUNT=2
CONFIG_BT_ASCS_ASE_SRC_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1
CONFIG_BT_ISO_TX_BUF_COUNT=2
# Support an ISO channel per ASE
CONFIG_BT_ISO_MAX_CHAN=4
Expand Down
14 changes: 10 additions & 4 deletions samples/bluetooth/bap_unicast_server/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
BT_AUDIO_CONTEXT_TYPE_MEDIA | \
BT_AUDIO_CONTEXT_TYPE_GAME)

NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT,
NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);

Expand All @@ -40,13 +40,13 @@ static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3(

static struct bt_conn *default_conn;
static struct k_work_delayable audio_send_work;
static struct bt_bap_stream sink_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT];
static struct bt_bap_stream sink_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT];
static struct audio_source {
struct bt_bap_stream stream;
uint16_t seq_num;
uint16_t max_sdu;
size_t len_to_send;
} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT];
} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
static size_t configured_source_stream_count;

static const struct bt_audio_codec_qos_pref qos_pref =
Expand Down Expand Up @@ -466,6 +466,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp
return 0;
}

static struct bt_bap_unicast_server_register_param param = {
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
};

static const struct bt_bap_unicast_server_cb unicast_server_cb = {
.config = lc3_config,
.reconfig = lc3_reconfig,
Expand Down Expand Up @@ -727,6 +732,7 @@ int main(void)

printk("Bluetooth initialized\n");

bt_bap_unicast_server_register(&param);
bt_bap_unicast_server_register_cb(&unicast_server_cb);

bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink);
Expand Down Expand Up @@ -780,7 +786,7 @@ int main(void)

printk("Advertising successfully started\n");

if (CONFIG_BT_ASCS_ASE_SRC_COUNT > 0) {
if (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0) {
/* Start send timer */
k_work_init_delayable(&audio_send_work, audio_timer_timeout);
}
Expand Down
4 changes: 2 additions & 2 deletions samples/bluetooth/cap_acceptor/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ CONFIG_BT_ATT_PREPARE_COUNT=1

# Support an ISO channel per ASE
CONFIG_BT_ASCS=y
CONFIG_BT_ASCS_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_ASE_SRC_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1

# Support an ISO channel per ASE
CONFIG_BT_ISO_MAX_CHAN=2
Expand Down
11 changes: 11 additions & 0 deletions samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,17 @@ int init_cap_acceptor_unicast(struct peer_config *peer)

if (!cbs_registered) {
int err;
struct bt_bap_unicast_server_register_param param = {
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
};

err = bt_bap_unicast_server_register(&param);
if (err != 0) {
LOG_ERR("Failed to register BAP unicast server: %d", err);

return -ENOEXEC;
}

err = bt_bap_unicast_server_register_cb(&unicast_server_cb);
if (err != 0) {
Expand Down
4 changes: 2 additions & 2 deletions samples/bluetooth/hap_ha/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ CONFIG_BT_ATT_PREPARE_COUNT=1
CONFIG_BT_AUDIO=y
CONFIG_BT_BAP_UNICAST_SERVER=y
CONFIG_BT_ASCS=y
CONFIG_BT_ASCS_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_ASE_SRC_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1
# Support an ISO channel per ASE
CONFIG_BT_ISO_MAX_CHAN=2

Expand Down
13 changes: 10 additions & 3 deletions samples/bluetooth/hap_ha/src/bap_unicast_sr.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/audio/pacs.h>

NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT,
NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);

Expand All @@ -29,11 +29,12 @@ static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3(

static struct bt_conn *default_conn;
static struct k_work_delayable audio_send_work;
static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT];
static struct bt_bap_stream streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
static struct audio_source {
struct bt_bap_stream *stream;
uint16_t seq_num;
} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT];
} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
static size_t configured_source_stream_count;

static const struct bt_audio_codec_qos_pref qos_pref =
Expand Down Expand Up @@ -316,6 +317,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp
return 0;
}

static struct bt_bap_unicast_server_register_param param = {
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
};

static const struct bt_bap_unicast_server_cb unicast_server_cb = {
.config = lc3_config,
.reconfig = lc3_reconfig,
Expand Down Expand Up @@ -394,6 +400,7 @@ static struct bt_pacs_cap cap_source = {

int bap_unicast_sr_init(void)
{
bt_bap_unicast_server_register(&param);
bt_bap_unicast_server_register_cb(&unicast_server_cb);

bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink);
Expand Down
4 changes: 2 additions & 2 deletions samples/bluetooth/tmap_peripheral/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ CONFIG_BT_MCC=y

# Support an ISO channel per ASE
CONFIG_BT_ASCS=y
CONFIG_BT_ASCS_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_ASE_SRC_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1
# Support an ISO channel per ASE
CONFIG_BT_ISO_MAX_CHAN=2

Expand Down
11 changes: 9 additions & 2 deletions samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ static const struct bt_audio_codec_cap lc3_codec_cap =
(AVAILABLE_SINK_CONTEXT | AVAILABLE_SOURCE_CONTEXT));

static struct bt_conn *default_conn;
static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT];
static struct bt_bap_stream streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
static struct audio_source {
struct bt_bap_stream *stream;
uint16_t seq_num;
} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT];
} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
static size_t configured_source_stream_count;

static const struct bt_audio_codec_qos_pref qos_pref =
Expand Down Expand Up @@ -271,6 +272,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp
return 0;
}

static struct bt_bap_unicast_server_register_param param = {
CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
};

static const struct bt_bap_unicast_server_cb unicast_server_cb = {
.config = lc3_config,
.reconfig = lc3_reconfig,
Expand Down Expand Up @@ -351,6 +357,7 @@ static struct bt_pacs_cap cap = {

int bap_unicast_sr_init(void)
{
bt_bap_unicast_server_register(&param);
bt_bap_unicast_server_register_cb(&unicast_server_cb);

if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
Expand Down
12 changes: 6 additions & 6 deletions subsys/bluetooth/audio/Kconfig.ascs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,29 @@ config BT_ASCS
This option enables support for Audio Stream Control Service.

if BT_ASCS
config BT_ASCS_ASE_SNK_COUNT
int "Number of Audio Stream Endpoint Sink Characteristics"
config BT_ASCS_MAX_ASE_SNK_COUNT
int "Maximum number of Audio Stream Endpoint Sink Characteristics"
default 2
range 0 $(UINT8_MAX)
help
An ASE Sink characteristic represents the state of an ASE, which is
coupled to a single direction of a unicast Audio Stream.

config BT_ASCS_ASE_SRC_COUNT
int "Number of Audio Stream Endpoint Source Characteristics"
config BT_ASCS_MAX_ASE_SRC_COUNT
int "Maximum number of Audio Stream Endpoint Source Characteristics"
default 2
range 0 $(UINT8_MAX)
help
An ASE Source characteristic represents the state of an ASE, which is
coupled to a single direction of a unicast Audio Stream.

config BT_ASCS_ASE_SNK
def_bool BT_ASCS_ASE_SNK_COUNT > 0
def_bool BT_ASCS_MAX_ASE_SNK_COUNT > 0
select BT_PAC_SNK
select BT_AUDIO_RX

config BT_ASCS_ASE_SRC
def_bool BT_ASCS_ASE_SRC_COUNT > 0
def_bool BT_ASCS_MAX_ASE_SRC_COUNT > 0
select BT_PAC_SRC
select BT_AUDIO_TX

Expand Down
Loading

0 comments on commit c9da274

Please sign in to comment.