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 snks;
|
||||||
static sys_slist_t srcs;
|
static sys_slist_t srcs;
|
||||||
|
|
||||||
IF_ENABLED(CONFIG_BT_PAC_SNK, (static enum bt_audio_context sink_available_contexts;))
|
#if defined(CONFIG_BT_PAC_SNK)
|
||||||
IF_ENABLED(CONFIG_BT_PAC_SRC, (static enum bt_audio_context source_available_contexts;));
|
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);
|
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);
|
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,
|
static ssize_t available_contexts_read(struct bt_conn *conn,
|
||||||
const struct bt_gatt_attr *attr, void *buf,
|
const struct bt_gatt_attr *attr, void *buf,
|
||||||
uint16_t len, uint16_t offset)
|
uint16_t len, uint16_t offset)
|
||||||
{
|
{
|
||||||
struct bt_pacs_context context;
|
struct bt_pacs_context context = {
|
||||||
int err;
|
.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,
|
BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
|
||||||
offset);
|
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,
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, &context,
|
||||||
sizeof(context));
|
sizeof(context));
|
||||||
}
|
}
|
||||||
|
@ -233,19 +190,10 @@ static ssize_t supported_context_read(struct bt_conn *conn,
|
||||||
const struct bt_gatt_attr *attr,
|
const struct bt_gatt_attr *attr,
|
||||||
void *buf, uint16_t len, uint16_t offset)
|
void *buf, uint16_t len, uint16_t offset)
|
||||||
{
|
{
|
||||||
struct bt_pacs_context context;
|
struct bt_pacs_context context = {
|
||||||
|
.snk = sys_cpu_to_le16(snk_supported_contexts),
|
||||||
#if defined(CONFIG_BT_PAC_SNK)
|
.src = sys_cpu_to_le16(src_supported_contexts),
|
||||||
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
|
|
||||||
|
|
||||||
BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
|
BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
|
||||||
offset);
|
offset);
|
||||||
|
@ -254,6 +202,32 @@ static ssize_t supported_context_read(struct bt_conn *conn,
|
||||||
sizeof(context));
|
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)
|
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
|
||||||
static void pac_notify_loc(struct k_work *work);
|
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);
|
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)
|
#if defined(CONFIG_BT_PAC_SNK_LOC)
|
||||||
static K_WORK_DELAYABLE_DEFINE(snks_loc_work, pac_notify_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);
|
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)
|
#if defined(CONFIG_BT_PAC_SRC_LOC)
|
||||||
static K_WORK_DELAYABLE_DEFINE(srcs_loc_work, pac_notify_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)
|
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;
|
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,
|
err = bt_gatt_notify_uuid(NULL, BT_UUID_PACS_AVAILABLE_CONTEXT, pacs_svc.attrs,
|
||||||
&context, sizeof(context));
|
&context, sizeof(context));
|
||||||
if (err != 0 && err != -ENOTCONN) {
|
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)
|
bool bt_pacs_context_available(enum bt_audio_dir dir, uint16_t context)
|
||||||
{
|
{
|
||||||
struct bt_pacs_context available_context;
|
if (dir == BT_AUDIO_DIR_SOURCE) {
|
||||||
int err;
|
return (context & src_available_contexts) == context;
|
||||||
|
|
||||||
err = available_contexts_get(NULL, &available_context);
|
|
||||||
if (err) {
|
|
||||||
BT_DBG("get_available_contexts returned %d", err);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_PAC_SRC) && dir == BT_AUDIO_DIR_SOURCE) {
|
if (dir == BT_AUDIO_DIR_SINK) {
|
||||||
return (context & available_context.src) == context;
|
return (context & snk_available_contexts) == context;
|
||||||
} else if (IS_ENABLED(CONFIG_BT_PAC_SNK) && dir == BT_AUDIO_DIR_SINK) {
|
|
||||||
return (context & available_context.snk) == context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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 */
|
#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)
|
enum bt_audio_context contexts)
|
||||||
{
|
{
|
||||||
IF_ENABLED(CONFIG_BT_PAC_SNK, (
|
switch (dir) {
|
||||||
if (dir == BT_AUDIO_DIR_SINK) {
|
case BT_AUDIO_DIR_SINK:
|
||||||
const enum bt_audio_context supported = CONFIG_BT_PACS_SNK_CONTEXT;
|
return set_snk_available_contexts(contexts);
|
||||||
|
case BT_AUDIO_DIR_SOURCE:
|
||||||
if (contexts & ~supported) {
|
return set_src_available_contexts(contexts);
|
||||||
return -ENOTSUP;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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 bt_audio_capability_get_available_contexts(enum bt_audio_dir dir)
|
||||||
{
|
{
|
||||||
enum bt_audio_context contexts;
|
switch (dir) {
|
||||||
int err;
|
case BT_AUDIO_DIR_SINK:
|
||||||
|
return snk_available_contexts;
|
||||||
err = get_available_contexts(dir, &contexts);
|
case BT_AUDIO_DIR_SOURCE:
|
||||||
if (err < 0) {
|
return src_available_contexts;
|
||||||
return BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return contexts;
|
return BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue