Bluetooth: audio: Add configurable PACS supported contexts
Add the ability to change supported contexts in PACS. Enhance the context command in the shell module to make it configurable. Signed-off-by: Szymon Czapracki <szymon.czapracki@codecoup.pl>
This commit is contained in:
parent
cc40bc33ba
commit
35bd427927
4 changed files with 143 additions and 17 deletions
|
@ -96,6 +96,14 @@ int bt_pacs_set_available_contexts(enum bt_audio_dir dir,
|
|||
*/
|
||||
enum bt_audio_context bt_pacs_get_available_contexts(enum bt_audio_dir dir);
|
||||
|
||||
/** @brief Set the supported contexts for an endpoint type
|
||||
*
|
||||
* @param dir Direction of the endpoints to change available contexts for.
|
||||
* @param contexts The contexts to be set.
|
||||
*/
|
||||
int bt_pacs_set_supported_contexts(enum bt_audio_dir dir,
|
||||
enum bt_audio_context contexts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -55,20 +55,20 @@ struct pacs {
|
|||
sys_slist_t list;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SNK)
|
||||
#if defined(CONTIG_BT_PAC_SNK)
|
||||
static uint16_t snk_available_contexts;
|
||||
static const uint16_t snk_supported_contexts = CONFIG_BT_PACS_SNK_CONTEXT;
|
||||
static uint16_t snk_supported_contexts;
|
||||
#else
|
||||
static const uint16_t snk_available_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static const uint16_t snk_supported_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static uint16_t snk_available_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static uint16_t snk_supported_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
#endif /* CONFIG_BT_PAC_SNK */
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SRC)
|
||||
static uint16_t src_available_contexts;
|
||||
static const uint16_t src_supported_contexts = CONFIG_BT_PACS_SRC_CONTEXT;
|
||||
static uint16_t src_supported_contexts;
|
||||
#else
|
||||
static const uint16_t src_available_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static const uint16_t src_supported_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static uint16_t src_available_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
static uint16_t src_supported_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
|
||||
NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, CONFIG_BT_L2CAP_TX_MTU);
|
||||
|
@ -231,10 +231,12 @@ static ssize_t supported_context_read(struct bt_conn *conn,
|
|||
}
|
||||
|
||||
static void available_contexts_notify(struct k_work *work);
|
||||
static void supported_contexts_notify(struct k_work *work);
|
||||
static K_WORK_DELAYABLE_DEFINE(available_contexts_work, available_contexts_notify);
|
||||
static K_WORK_DELAYABLE_DEFINE(supported_contexts_work, supported_contexts_notify);
|
||||
|
||||
static int set_available_contexts(uint16_t contexts, uint16_t *available,
|
||||
const uint16_t supported)
|
||||
uint16_t supported)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -246,13 +248,45 @@ static int set_available_contexts(uint16_t contexts, uint16_t *available,
|
|||
return 0;
|
||||
}
|
||||
|
||||
*available = contexts;
|
||||
|
||||
err = k_work_reschedule(&available_contexts_work, PAC_NOTIFY_TIMEOUT);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*available = contexts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_supported_contexts(uint16_t contexts, uint16_t *supported,
|
||||
uint16_t *available)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Ensure unspecified is always supported */
|
||||
contexts |= BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED;
|
||||
|
||||
if (*supported == contexts) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = k_work_reschedule(&supported_contexts_work, PAC_NOTIFY_TIMEOUT);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*supported = contexts;
|
||||
|
||||
/* Update available contexts if needed*/
|
||||
if ((contexts & *available) != *available) {
|
||||
*available = *available & contexts;
|
||||
err = k_work_reschedule(&available_contexts_work,
|
||||
PAC_NOTIFY_TIMEOUT);
|
||||
if (err < 0) {
|
||||
LOG_WRN("Update available contexts notify failed: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -281,11 +315,22 @@ static inline int set_snk_available_contexts(uint16_t contexts)
|
|||
return set_available_contexts(contexts, &snk_available_contexts,
|
||||
snk_supported_contexts);
|
||||
}
|
||||
|
||||
static inline int set_snk_supported_contexts(uint16_t contexts)
|
||||
{
|
||||
return set_supported_contexts(contexts, &snk_supported_contexts,
|
||||
&snk_available_contexts);
|
||||
}
|
||||
#else
|
||||
static inline int set_snk_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static inline int set_snk_supported_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SNK */
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SNK_LOC)
|
||||
|
@ -385,11 +430,22 @@ static inline int set_src_available_contexts(uint16_t contexts)
|
|||
return set_available_contexts(contexts, &src_available_contexts,
|
||||
src_supported_contexts);
|
||||
}
|
||||
|
||||
static inline int set_src_supported_contexts(uint16_t contexts)
|
||||
{
|
||||
return set_supported_contexts(contexts, &src_supported_contexts,
|
||||
&snk_supported_contexts);
|
||||
}
|
||||
#else
|
||||
static inline int set_src_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static inline int set_src_supported_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SRC_LOC)
|
||||
|
@ -602,6 +658,21 @@ static void available_contexts_notify(struct k_work *work)
|
|||
}
|
||||
}
|
||||
|
||||
static void supported_contexts_notify(struct k_work *work)
|
||||
{
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(snk_supported_contexts),
|
||||
.src = sys_cpu_to_le16(src_supported_contexts),
|
||||
};
|
||||
int err;
|
||||
|
||||
err = bt_gatt_notify_uuid(NULL, BT_UUID_PACS_SUPPORTED_CONTEXT, pacs_svc.attrs,
|
||||
&context, sizeof(context));
|
||||
if (err != 0 && err != -ENOTCONN) {
|
||||
LOG_WRN("Supported Audio Contexts notify failed: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
bool bt_pacs_context_available(enum bt_audio_dir dir, uint16_t context)
|
||||
{
|
||||
if (dir == BT_AUDIO_DIR_SOURCE) {
|
||||
|
@ -722,6 +793,18 @@ int bt_pacs_set_available_contexts(enum bt_audio_dir dir, enum bt_audio_context
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int bt_pacs_set_supported_contexts(enum bt_audio_dir dir, enum bt_audio_context contexts)
|
||||
{
|
||||
switch (dir) {
|
||||
case BT_AUDIO_DIR_SINK:
|
||||
return set_snk_supported_contexts(contexts);
|
||||
case BT_AUDIO_DIR_SOURCE:
|
||||
return set_src_supported_contexts(contexts);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
enum bt_audio_context bt_pacs_get_available_contexts(enum bt_audio_dir dir)
|
||||
{
|
||||
switch (dir) {
|
||||
|
|
|
@ -1887,11 +1887,22 @@ static int cmd_context(const struct shell *sh, size_t argc, char *argv[])
|
|||
return err;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[3], "supported")) {
|
||||
err = bt_pacs_set_supported_contexts(dir, ctx);
|
||||
if (err) {
|
||||
shell_error(ctx_shell, "Set supported contexts err %d", err);
|
||||
return err;
|
||||
}
|
||||
} else if (!strcmp(argv[3], "available")) {
|
||||
err = bt_pacs_set_available_contexts(dir, ctx);
|
||||
if (err) {
|
||||
shell_error(ctx_shell, "Set available contexts err %d", err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
shell_error(sh, "Unsupported context type: %s", argv[3]);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1924,6 +1935,10 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
|
|||
err = bt_pacs_set_location(BT_AUDIO_DIR_SINK, LOCATION);
|
||||
__ASSERT(err == 0, "Failed to set sink location");
|
||||
|
||||
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
|
||||
CONTEXT);
|
||||
__ASSERT(err == 0, "Failed to set sink supported contexts");
|
||||
|
||||
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
|
||||
CONTEXT);
|
||||
__ASSERT(err == 0, "Failed to set sink available contexts");
|
||||
|
@ -1933,6 +1948,10 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
|
|||
err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE, LOCATION);
|
||||
__ASSERT(err == 0, "Failed to set source location");
|
||||
|
||||
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
|
||||
CONTEXT);
|
||||
__ASSERT(err == 0, "Failed to set sink supported contexts");
|
||||
|
||||
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
|
||||
CONTEXT);
|
||||
__ASSERT(err == 0, "Failed to set source available contexts");
|
||||
|
@ -2084,9 +2103,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(audio_cmds,
|
|||
SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_location, NULL,
|
||||
"<direction: sink, source> <location bitmask>",
|
||||
cmd_set_loc, 3, 0),
|
||||
SHELL_COND_CMD_ARG(CONFIG_BT_PACS, add_context, NULL,
|
||||
"<direction: sink, source> <context bitmask>",
|
||||
cmd_context, 3, 0),
|
||||
SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_context, NULL,
|
||||
"<direction: sink, source>"
|
||||
"<context bitmask> <type: supported, available>",
|
||||
cmd_context, 4, 0),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
||||
|
|
|
@ -296,6 +296,14 @@ static void set_available_contexts(void)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
|
||||
BT_AUDIO_CONTEXT_TYPE_MEDIA |
|
||||
BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL);
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SNK) && err != 0) {
|
||||
FAIL("Failed to set sink supported contexts (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
|
||||
BT_AUDIO_CONTEXT_TYPE_MEDIA |
|
||||
BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL);
|
||||
|
@ -304,6 +312,13 @@ static void set_available_contexts(void)
|
|||
return;
|
||||
}
|
||||
|
||||
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
|
||||
BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS);
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
|
||||
FAIL("Failed to set source supported contexts (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
|
||||
BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS);
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue