Bluetooth: audio: pacs: Refactor context related code
This implifies and removes redundant code. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
parent
2a1cb0acd8
commit
49f9119c99
1 changed files with 93 additions and 164 deletions
|
@ -36,8 +36,21 @@
|
|||
static sys_slist_t snks;
|
||||
static sys_slist_t srcs;
|
||||
|
||||
IF_ENABLED(CONFIG_BT_PAC_SNK, (static enum bt_audio_context sink_available_contexts;))
|
||||
IF_ENABLED(CONFIG_BT_PAC_SRC, (static enum bt_audio_context source_available_contexts;));
|
||||
#if defined(CONFIG_BT_PAC_SNK)
|
||||
static uint16_t snk_available_contexts;
|
||||
static const uint16_t snk_supported_contexts = CONFIG_BT_PACS_SNK_CONTEXT;
|
||||
#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;
|
||||
#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;
|
||||
#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;
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
|
||||
NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, CONFIG_BT_L2CAP_TX_MTU);
|
||||
|
||||
|
@ -150,75 +163,19 @@ static void available_context_cfg_changed(const struct bt_gatt_attr *attr, uint1
|
|||
BT_DBG("attr %p value 0x%04x", attr, value);
|
||||
}
|
||||
|
||||
static int get_available_contexts(enum bt_audio_dir dir,
|
||||
enum bt_audio_context *contexts)
|
||||
{
|
||||
IF_ENABLED(CONFIG_BT_PAC_SNK, (
|
||||
if (dir == BT_AUDIO_DIR_SINK) {
|
||||
*contexts = sink_available_contexts;
|
||||
return 0;
|
||||
}
|
||||
));
|
||||
|
||||
IF_ENABLED(CONFIG_BT_PAC_SRC, (
|
||||
if (dir == BT_AUDIO_DIR_SOURCE) {
|
||||
*contexts = source_available_contexts;
|
||||
return 0;
|
||||
}
|
||||
));
|
||||
|
||||
BT_ASSERT_PRINT_MSG("Invalid endpoint dir: %u", dir);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int available_contexts_get(struct bt_conn *conn, struct bt_pacs_context *context)
|
||||
{
|
||||
enum bt_audio_context context_snk, context_src;
|
||||
int err;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
|
||||
err = get_available_contexts(BT_AUDIO_DIR_SINK, &context_snk);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* Server is not available to receive audio for any Context */
|
||||
context_snk = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
|
||||
err = get_available_contexts(BT_AUDIO_DIR_SOURCE, &context_src);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* Server is not available to send audio for any Context */
|
||||
context_src = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
}
|
||||
|
||||
context->snk = sys_cpu_to_le16((uint16_t)context_snk);
|
||||
context->src = sys_cpu_to_le16((uint16_t)context_src);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t available_contexts_read(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct bt_pacs_context context;
|
||||
int err;
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(snk_available_contexts),
|
||||
.src = sys_cpu_to_le16(src_available_contexts),
|
||||
};
|
||||
|
||||
BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
|
||||
offset);
|
||||
|
||||
err = available_contexts_get(NULL, &context);
|
||||
if (err) {
|
||||
BT_DBG("get_available_contexts returned %d", err);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &context,
|
||||
sizeof(context));
|
||||
}
|
||||
|
@ -233,19 +190,10 @@ static ssize_t supported_context_read(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct bt_pacs_context context;
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SNK)
|
||||
context.snk = sys_cpu_to_le16(CONFIG_BT_PACS_SNK_CONTEXT);
|
||||
#else
|
||||
context.snk = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SRC)
|
||||
context.src = sys_cpu_to_le16(CONFIG_BT_PACS_SRC_CONTEXT);
|
||||
#else
|
||||
context.src = BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
#endif
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(snk_supported_contexts),
|
||||
.src = sys_cpu_to_le16(src_supported_contexts),
|
||||
};
|
||||
|
||||
BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
|
||||
offset);
|
||||
|
@ -254,6 +202,32 @@ static ssize_t supported_context_read(struct bt_conn *conn,
|
|||
sizeof(context));
|
||||
}
|
||||
|
||||
static void available_contexts_notify(struct k_work *work);
|
||||
static K_WORK_DELAYABLE_DEFINE(available_contexts_work, available_contexts_notify);
|
||||
|
||||
static int set_available_contexts(uint16_t contexts, uint16_t *available,
|
||||
const uint16_t supported)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (contexts & ~supported) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (contexts == *available) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*available = contexts;
|
||||
|
||||
err = k_work_reschedule(&available_contexts_work, PAC_NOTIFY_TIMEOUT);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
|
||||
static void pac_notify_loc(struct k_work *work);
|
||||
|
||||
|
@ -324,6 +298,17 @@ static void snk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
|||
BT_DBG("attr %p value 0x%04x", attr, value);
|
||||
}
|
||||
|
||||
static inline int set_snk_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return set_available_contexts(contexts, &snk_available_contexts,
|
||||
snk_supported_contexts);
|
||||
}
|
||||
#else
|
||||
static inline int set_snk_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SNK_LOC)
|
||||
static K_WORK_DELAYABLE_DEFINE(snks_loc_work, pac_notify_loc);
|
||||
|
||||
|
@ -427,6 +412,17 @@ static void src_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
|||
BT_DBG("attr %p value 0x%04x", attr, value);
|
||||
}
|
||||
|
||||
static inline int set_src_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return set_available_contexts(contexts, &src_available_contexts,
|
||||
src_supported_contexts);
|
||||
}
|
||||
#else
|
||||
static inline int set_src_available_contexts(uint16_t contexts)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PAC_SRC_LOC)
|
||||
static K_WORK_DELAYABLE_DEFINE(srcs_loc_work, pac_notify_loc);
|
||||
|
||||
|
@ -692,15 +688,12 @@ static int bt_audio_pacs_location_changed(enum bt_audio_dir dir)
|
|||
|
||||
static void available_contexts_notify(struct k_work *work)
|
||||
{
|
||||
struct bt_pacs_context context;
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(snk_available_contexts),
|
||||
.src = sys_cpu_to_le16(src_available_contexts),
|
||||
};
|
||||
int err;
|
||||
|
||||
err = available_contexts_get(NULL, &context);
|
||||
if (err) {
|
||||
BT_DBG("get_available_contexts returned %d, won't notify", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_gatt_notify_uuid(NULL, BT_UUID_PACS_AVAILABLE_CONTEXT, pacs_svc.attrs,
|
||||
&context, sizeof(context));
|
||||
if (err != 0 && err != -ENOTCONN) {
|
||||
|
@ -708,35 +701,14 @@ static void available_contexts_notify(struct k_work *work)
|
|||
}
|
||||
}
|
||||
|
||||
static K_WORK_DELAYABLE_DEFINE(available_contexts_work, available_contexts_notify);
|
||||
|
||||
static int bt_pacs_available_contexts_changed(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = k_work_reschedule(&available_contexts_work, PAC_NOTIFY_TIMEOUT);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool bt_pacs_context_available(enum bt_audio_dir dir, uint16_t context)
|
||||
{
|
||||
struct bt_pacs_context available_context;
|
||||
int err;
|
||||
|
||||
err = available_contexts_get(NULL, &available_context);
|
||||
if (err) {
|
||||
BT_DBG("get_available_contexts returned %d", err);
|
||||
return false;
|
||||
if (dir == BT_AUDIO_DIR_SOURCE) {
|
||||
return (context & src_available_contexts) == context;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PAC_SRC) && dir == BT_AUDIO_DIR_SOURCE) {
|
||||
return (context & available_context.src) == context;
|
||||
} else if (IS_ENABLED(CONFIG_BT_PAC_SNK) && dir == BT_AUDIO_DIR_SINK) {
|
||||
return (context & available_context.snk) == context;
|
||||
if (dir == BT_AUDIO_DIR_SINK) {
|
||||
return (context & snk_available_contexts) == context;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -867,70 +839,27 @@ int bt_audio_capability_set_location(enum bt_audio_dir dir,
|
|||
}
|
||||
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
|
||||
|
||||
static int set_available_contexts(enum bt_audio_dir dir,
|
||||
int bt_audio_capability_set_available_contexts(enum bt_audio_dir dir,
|
||||
enum bt_audio_context contexts)
|
||||
{
|
||||
IF_ENABLED(CONFIG_BT_PAC_SNK, (
|
||||
if (dir == BT_AUDIO_DIR_SINK) {
|
||||
const enum bt_audio_context supported = CONFIG_BT_PACS_SNK_CONTEXT;
|
||||
|
||||
if (contexts & ~supported) {
|
||||
return -ENOTSUP;
|
||||
switch (dir) {
|
||||
case BT_AUDIO_DIR_SINK:
|
||||
return set_snk_available_contexts(contexts);
|
||||
case BT_AUDIO_DIR_SOURCE:
|
||||
return set_src_available_contexts(contexts);
|
||||
}
|
||||
|
||||
sink_available_contexts = contexts;
|
||||
return 0;
|
||||
}
|
||||
));
|
||||
|
||||
IF_ENABLED(CONFIG_BT_PAC_SRC, (
|
||||
if (dir == BT_AUDIO_DIR_SOURCE) {
|
||||
const enum bt_audio_context supported = CONFIG_BT_PACS_SRC_CONTEXT;
|
||||
|
||||
if (contexts & ~supported) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
source_available_contexts = contexts;
|
||||
return 0;
|
||||
}
|
||||
));
|
||||
|
||||
BT_ERR("Invalid endpoint dir: %u", dir);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int bt_audio_capability_set_available_contexts(enum bt_audio_dir dir,
|
||||
enum bt_audio_context contexts)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = set_available_contexts(dir, contexts);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PACS)) {
|
||||
err = bt_pacs_available_contexts_changed();
|
||||
if (err) {
|
||||
BT_DBG("Available contexts weren't notified: %d", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum bt_audio_context bt_audio_capability_get_available_contexts(enum bt_audio_dir dir)
|
||||
{
|
||||
enum bt_audio_context contexts;
|
||||
int err;
|
||||
|
||||
err = get_available_contexts(dir, &contexts);
|
||||
if (err < 0) {
|
||||
return BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
switch (dir) {
|
||||
case BT_AUDIO_DIR_SINK:
|
||||
return snk_available_contexts;
|
||||
case BT_AUDIO_DIR_SOURCE:
|
||||
return src_available_contexts;
|
||||
}
|
||||
|
||||
return contexts;
|
||||
return BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue