Bluetooth: Audio: Make PACS location optional

Make the PACS location characteristic optional, and
also optionally writable.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2022-04-13 21:10:18 +02:00 committed by Carles Cufí
commit a796927961
7 changed files with 163 additions and 82 deletions

View file

@ -1070,6 +1070,7 @@ struct bt_audio_unicast_server_cb {
int (*publish_capability)(struct bt_conn *conn, uint8_t type, int (*publish_capability)(struct bt_conn *conn, uint8_t type,
uint8_t index, struct bt_codec *const codec); uint8_t index, struct bt_codec *const codec);
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
/** @brief Publish location callback /** @brief Publish location callback
* *
* Publish location callback is called whenever a remote client * Publish location callback is called whenever a remote client
@ -1090,6 +1091,7 @@ struct bt_audio_unicast_server_cb {
enum bt_audio_pac_type type, enum bt_audio_pac_type type,
enum bt_audio_location *location); enum bt_audio_location *location);
#if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE) || defined(CONFIG_BT_PAC_SRC_LOC_WRITEABLE)
/** @brief Write location callback /** @brief Write location callback
* *
* Write location callback is called whenever a remote client * Write location callback is called whenever a remote client
@ -1103,6 +1105,8 @@ struct bt_audio_unicast_server_cb {
*/ */
int (*write_location)(struct bt_conn *conn, enum bt_audio_pac_type type, int (*write_location)(struct bt_conn *conn, enum bt_audio_pac_type type,
enum bt_audio_location location); enum bt_audio_location location);
#endif /* CONFIG_BT_PAC_SNK_LOC_WRITEABLE || CONFIG_BT_PAC_SRC_LOC_WRITEABLE */
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
}; };
/** Broadcast Audio Sink callback structure */ /** Broadcast Audio Sink callback structure */

View file

@ -37,6 +37,20 @@ config BT_PACS_SNK_CONTEXT
0x0100: Ringtone 0x0100: Ringtone
0x0200: TV 0x0200: TV
config BT_PAC_SNK_LOC
bool "Sink PAC Location Support"
default y
help
This option enables support for Sink PAC Location Characteristic.
config BT_PAC_SNK_LOC_WRITEABLE
bool "Sink PAC Location Writable Support"
default y
depends on BT_PAC_SNK_LOC
help
This option enables support for clients to write to the Sink PAC
Location Characteristic.
endif # BT_PACS_SNK endif # BT_PACS_SNK
config BT_PAC_SRC config BT_PAC_SRC
@ -65,5 +79,19 @@ config BT_PACS_SRC_CONTEXT
0x0100: Ringtone 0x0100: Ringtone
0x0200: TV 0x0200: TV
config BT_PAC_SRC_LOC
bool "Source PAC Location Support"
default y
help
This option enables support for Source PAC Location Characteristic.
config BT_PAC_SRC_LOC_WRITEABLE
bool "Source PAC Location Writable Support"
default y
depends on BT_PAC_SRC_LOC
help
This option enables support for clients to write to the Source PAC
Location Characteristic.
endif # BT_PAC_SRC endif # BT_PAC_SRC
endif # BT_PACS endif # BT_PACS

View file

@ -28,9 +28,6 @@
static sys_slist_t snks; static sys_slist_t snks;
static sys_slist_t srcs; static sys_slist_t srcs;
static enum bt_audio_location sink_location;
static enum bt_audio_location source_location;
#if defined(CONFIG_BT_AUDIO_UNICAST_SERVER) && defined(CONFIG_BT_ASCS) #if defined(CONFIG_BT_AUDIO_UNICAST_SERVER) && defined(CONFIG_BT_ASCS)
/* TODO: The unicast server callbacks uses `const` for many of the pointers, /* TODO: The unicast server callbacks uses `const` for many of the pointers,
* wheras the capabilities callbacks do no. The latter should be updated to use * wheras the capabilities callbacks do no. The latter should be updated to use
@ -261,14 +258,28 @@ static int publish_capability_cb(struct bt_conn *conn, uint8_t type,
return -ENOENT; return -ENOENT;
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
#if defined(CONFIG_BT_PAC_SNK_LOC)
static enum bt_audio_location sink_location;
#endif /* CONFIG_BT_PAC_SNK_LOC */
#if defined(CONFIG_BT_PAC_SRC_LOC)
static enum bt_audio_location source_location;
#endif /* CONFIG_BT_PAC_SRC_LOC */
static int publish_location_cb(struct bt_conn *conn, static int publish_location_cb(struct bt_conn *conn,
enum bt_audio_pac_type type, enum bt_audio_pac_type type,
enum bt_audio_location *location) enum bt_audio_location *location)
{ {
if (type == BT_AUDIO_SINK) { if (0) {
#if defined(CONFIG_BT_PAC_SNK_LOC)
} else if (type == BT_AUDIO_SINK) {
*location = sink_location; *location = sink_location;
#endif /* CONFIG_BT_PAC_SNK_LOC */
#if defined(CONFIG_BT_PAC_SRC_LOC)
} else if (type == BT_AUDIO_SOURCE) { } else if (type == BT_AUDIO_SOURCE) {
*location = source_location; *location = source_location;
#endif /* CONFIG_BT_PAC_SRC_LOC */
} else { } else {
BT_ERR("Invalid endpoint type: %u", type); BT_ERR("Invalid endpoint type: %u", type);
@ -278,28 +289,14 @@ static int publish_location_cb(struct bt_conn *conn,
return 0; return 0;
} }
#if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE) || defined(CONFIG_BT_PAC_SRC_LOC_WRITEABLE)
static int write_location_cb(struct bt_conn *conn, enum bt_audio_pac_type type, static int write_location_cb(struct bt_conn *conn, enum bt_audio_pac_type type,
enum bt_audio_location location) enum bt_audio_location location)
{ {
int err; return bt_audio_capability_set_location(type, location);
if (type == BT_AUDIO_SINK) {
sink_location = location;
} else if (type == BT_AUDIO_SOURCE) {
source_location = location;
} else {
BT_ERR("Invalid endpoint type: %u", type);
return -EINVAL;
}
err = bt_audio_unicast_server_location_changed(type);
if (err) {
BT_DBG("Location for type %d wasn't notified: %d", type, err);
}
return 0;
} }
#endif /* CONFIG_BT_PAC_SNK_LOC_WRITEABLE || CONFIG_BT_PAC_SRC_LOC_WRITEABLE */
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
static struct bt_audio_unicast_server_cb unicast_server_cb = { static struct bt_audio_unicast_server_cb unicast_server_cb = {
.config = unicast_server_config_cb, .config = unicast_server_config_cb,
@ -312,8 +309,12 @@ static struct bt_audio_unicast_server_cb unicast_server_cb = {
.stop = unicast_server_stop_cb, .stop = unicast_server_stop_cb,
.release = unicast_server_release_cb, .release = unicast_server_release_cb,
.publish_capability = publish_capability_cb, .publish_capability = publish_capability_cb,
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
.publish_location = publish_location_cb, .publish_location = publish_location_cb,
#if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE) || defined(CONFIG_BT_PAC_SRC_LOC_WRITEABLE)
.write_location = write_location_cb .write_location = write_location_cb
#endif /* CONFIG_BT_PAC_SNK_LOC_WRITEABLE || CONFIG_BT_PAC_SRC_LOC_WRITEABLE */
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
}; };
#endif /* CONFIG_BT_AUDIO_UNICAST_SERVER && CONFIG_BT_ASCS */ #endif /* CONFIG_BT_AUDIO_UNICAST_SERVER && CONFIG_BT_ASCS */
@ -421,15 +422,21 @@ int bt_audio_capability_unregister(struct bt_audio_capability *cap)
return 0; return 0;
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
int bt_audio_capability_set_location(enum bt_audio_pac_type type, int bt_audio_capability_set_location(enum bt_audio_pac_type type,
enum bt_audio_location location) enum bt_audio_location location)
{ {
int err; int err;
if (type == BT_AUDIO_SINK) { if (0) {
#if defined(CONFIG_BT_PAC_SNK_LOC)
} else if (type == BT_AUDIO_SINK) {
sink_location = location; sink_location = location;
#endif /* CONFIG_BT_PAC_SNK_LOC */
#if defined(CONFIG_BT_PAC_SRC_LOC)
} else if (type == BT_AUDIO_SOURCE) { } else if (type == BT_AUDIO_SOURCE) {
source_location = location; source_location = location;
#endif /* CONFIG_BT_PAC_SRC_LOC */
} else { } else {
BT_ERR("Invalid endpoint type: %u", type); BT_ERR("Invalid endpoint type: %u", type);
@ -446,3 +453,4 @@ int bt_audio_capability_set_location(enum bt_audio_pac_type type,
return 0; return 0;
} }
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */

View file

@ -598,17 +598,23 @@ static int has_init(const struct device *dev)
has.features |= BT_HAS_FEAT_WRITABLE_PRESETS_SUPP; has.features |= BT_HAS_FEAT_WRITABLE_PRESETS_SUPP;
} }
if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
if (IS_ENABLED(CONFIG_BT_HAS_HEARING_AID_BANDED)) { if (IS_ENABLED(CONFIG_BT_HAS_HEARING_AID_BANDED)) {
/* HAP_d1.0r00; 3.7 BAP Unicast Server role requirements /* HAP_d1.0r00; 3.7 BAP Unicast Server role requirements
* A Banded Hearing Aid in the HA role shall set the Front Left and the Front * A Banded Hearing Aid in the HA role shall set the
* Right bits to a value of 0b1 in the Sink Audio Locations characteristic value. * Front Left and the Front Right bits to a value of 0b1
* in the Sink Audio Locations characteristic value.
*/ */
bt_audio_capability_set_location(BT_AUDIO_SINK, BT_AUDIO_LOCATION_FRONT_LEFT | bt_audio_capability_set_location(BT_AUDIO_SINK,
BT_AUDIO_LOCATION_FRONT_RIGHT); (BT_AUDIO_LOCATION_FRONT_LEFT |
BT_AUDIO_LOCATION_FRONT_RIGHT));
} else if (IS_ENABLED(CONFIG_BT_HAS_HEARING_AID_LEFT)) { } else if (IS_ENABLED(CONFIG_BT_HAS_HEARING_AID_LEFT)) {
bt_audio_capability_set_location(BT_AUDIO_SINK, BT_AUDIO_LOCATION_FRONT_LEFT); bt_audio_capability_set_location(BT_AUDIO_SINK,
BT_AUDIO_LOCATION_FRONT_LEFT);
} else { } else {
bt_audio_capability_set_location(BT_AUDIO_SINK, BT_AUDIO_LOCATION_FRONT_RIGHT); bt_audio_capability_set_location(BT_AUDIO_SINK,
BT_AUDIO_LOCATION_FRONT_RIGHT);
}
} }
return 0; return 0;

View file

@ -172,6 +172,7 @@ static ssize_t supported_context_read(struct bt_conn *conn,
sizeof(context)); sizeof(context));
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
static int get_pac_loc(struct bt_conn *conn, enum bt_audio_pac_type type, static int get_pac_loc(struct bt_conn *conn, enum bt_audio_pac_type type,
enum bt_audio_location *location) enum bt_audio_location *location)
{ {
@ -192,11 +193,11 @@ static int get_pac_loc(struct bt_conn *conn, enum bt_audio_pac_type type,
return 0; return 0;
} }
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */ #endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
#if defined(CONFIG_BT_PAC_SNK) #if defined(CONFIG_BT_PAC_SNK)
static struct k_work_delayable snks_work; static struct k_work_delayable snks_work;
static struct k_work_delayable snks_loc_work;
static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset) void *buf, uint16_t len, uint16_t offset)
@ -207,6 +208,14 @@ static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
return pac_read(conn, attr, buf, len, offset); return pac_read(conn, attr, buf, len, offset);
} }
static void snk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
BT_DBG("attr %p value 0x%04x", attr, value);
}
#if defined(CONFIG_BT_PAC_SNK_LOC)
static struct k_work_delayable snks_loc_work;
static ssize_t snk_loc_read(struct bt_conn *conn, static ssize_t snk_loc_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)
@ -237,6 +246,7 @@ static ssize_t snk_loc_read(struct bt_conn *conn,
&location_32_le, sizeof(location_32_le)); &location_32_le, sizeof(location_32_le));
} }
#if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE)
static ssize_t snk_loc_write(struct bt_conn *conn, static ssize_t snk_loc_write(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const void *data, const struct bt_gatt_attr *attr, const void *data,
uint16_t len, uint16_t offset, uint8_t flags) uint16_t len, uint16_t offset, uint8_t flags)
@ -272,21 +282,18 @@ static ssize_t snk_loc_write(struct bt_conn *conn,
return len; return len;
} }
#endif /* CONFIG_BT_PAC_SNK_LOC_WRITEABLE */
static void snk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
BT_DBG("attr %p value 0x%04x", attr, value);
}
static void snk_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) static void snk_loc_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);
} }
#endif /* CONFIG_BT_PAC_SNK_LOC */
#endif /* CONFIG_BT_PAC_SNK */ #endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC) #if defined(CONFIG_BT_PAC_SRC)
static struct k_work_delayable srcs_work; static struct k_work_delayable srcs_work;
static struct k_work_delayable srcs_loc_work;
static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset) void *buf, uint16_t len, uint16_t offset)
@ -297,6 +304,14 @@ static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
return pac_read(conn, attr, buf, len, offset); return pac_read(conn, attr, buf, len, offset);
} }
static void src_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
BT_DBG("attr %p value 0x%04x", attr, value);
}
#if defined(CONFIG_BT_PAC_SRC_LOC)
static struct k_work_delayable srcs_loc_work;
static ssize_t src_loc_read(struct bt_conn *conn, static ssize_t src_loc_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)
@ -327,6 +342,7 @@ static ssize_t src_loc_read(struct bt_conn *conn,
&location_32_le, sizeof(location_32_le)); &location_32_le, sizeof(location_32_le));
} }
#if defined(BT_PAC_SRC_LOC_WRITEABLE)
static ssize_t src_loc_write(struct bt_conn *conn, static ssize_t src_loc_write(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const void *data, const struct bt_gatt_attr *attr, const void *data,
uint16_t len, uint16_t offset, uint8_t flags) uint16_t len, uint16_t offset, uint8_t flags)
@ -363,16 +379,13 @@ static ssize_t src_loc_write(struct bt_conn *conn,
return len; return len;
} }
#endif /* BT_PAC_SRC_LOC_WRITEABLE */
static void src_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
BT_DBG("attr %p value 0x%04x", attr, value);
}
static void src_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) static void src_loc_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);
} }
#endif /* CONFIG_BT_PAC_SRC_LOC */
#endif /* CONFIG_BT_PAC_SRC */ #endif /* CONFIG_BT_PAC_SRC */
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC) #if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
@ -385,14 +398,22 @@ BT_GATT_SERVICE_DEFINE(pacs_svc,
snk_read, NULL, NULL), snk_read, NULL, NULL),
BT_GATT_CCC(snk_cfg_changed, BT_GATT_CCC(snk_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#if defined(CONFIG_BT_PAC_SNK_LOC)
BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK_LOC, BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK_LOC,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
BT_GATT_CHRC_NOTIFY, BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_READ_ENCRYPT |
BT_GATT_PERM_WRITE_ENCRYPT, BT_GATT_PERM_WRITE_ENCRYPT,
snk_loc_read, snk_loc_write, NULL), snk_loc_read,
#if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE)
snk_loc_write,
#else
NULL,
#endif /* BT_PAC_SRC_LOC_WRITEABLE */
NULL),
BT_GATT_CCC(snk_loc_cfg_changed, BT_GATT_CCC(snk_loc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#endif /* CONFIG_BT_PAC_SNK_LOC */
#endif /* CONFIG_BT_PAC_SNK */ #endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC) #if defined(CONFIG_BT_PAC_SRC)
BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC, BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC,
@ -401,14 +422,22 @@ BT_GATT_SERVICE_DEFINE(pacs_svc,
src_read, NULL, NULL), src_read, NULL, NULL),
BT_GATT_CCC(src_cfg_changed, BT_GATT_CCC(src_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#if defined(CONFIG_BT_PAC_SRC_LOC)
BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC_LOC, BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC_LOC,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
BT_GATT_CHRC_NOTIFY, BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_READ_ENCRYPT |
BT_GATT_PERM_WRITE_ENCRYPT, BT_GATT_PERM_WRITE_ENCRYPT,
src_loc_read, src_loc_write, NULL), src_loc_read,
#if defined(BT_PAC_SRC_LOC_WRITEABLE)
src_loc_write,
#else
NULL,
#endif /* BT_PAC_SRC_LOC_WRITEABLE */
NULL),
BT_GATT_CCC(src_loc_cfg_changed, BT_GATT_CCC(src_loc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#endif /* CONFIG_BT_PAC_SRC_LOC */
#endif /* CONFIG_BT_PAC_SNK */ #endif /* CONFIG_BT_PAC_SNK */
BT_GATT_CHARACTERISTIC(BT_UUID_PACS_CONTEXT, BT_GATT_CHARACTERISTIC(BT_UUID_PACS_CONTEXT,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
@ -441,6 +470,7 @@ static struct k_work_delayable *bt_pacs_get_work(uint8_t type)
return NULL; return NULL;
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
static struct k_work_delayable *bt_pacs_get_loc_work(uint8_t type) static struct k_work_delayable *bt_pacs_get_loc_work(uint8_t type)
{ {
switch (type) { switch (type) {
@ -457,38 +487,6 @@ static struct k_work_delayable *bt_pacs_get_loc_work(uint8_t type)
return NULL; return NULL;
} }
static void pac_notify(struct k_work *work)
{
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
struct bt_uuid *uuid;
uint8_t type;
int err;
#if defined(CONFIG_BT_PAC_SNK)
if (work == &snks_work.work) {
type = BT_AUDIO_SINK;
uuid = BT_UUID_PACS_SNK;
}
#endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC)
if (work == &srcs_work.work) {
type = BT_AUDIO_SOURCE;
uuid = BT_UUID_PACS_SRC;
}
#endif /* CONFIG_BT_PAC_SRC */
/* TODO: We can skip this if we are not connected to any devices */
get_pac_records(NULL, type, &read_buf);
err = bt_gatt_notify_uuid(NULL, uuid, pacs_svc.attrs, read_buf.data,
read_buf.len);
if (err != 0) {
BT_WARN("PACS notify failed: %d", err);
}
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
}
static void pac_notify_loc(struct k_work *work) static void pac_notify_loc(struct k_work *work)
{ {
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC) #if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
@ -526,6 +524,39 @@ static void pac_notify_loc(struct k_work *work)
} }
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */ #endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
} }
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */
static void pac_notify(struct k_work *work)
{
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
struct bt_uuid *uuid;
uint8_t type;
int err;
#if defined(CONFIG_BT_PAC_SNK)
if (work == &snks_work.work) {
type = BT_AUDIO_SINK;
uuid = BT_UUID_PACS_SNK;
}
#endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC)
if (work == &srcs_work.work) {
type = BT_AUDIO_SOURCE;
uuid = BT_UUID_PACS_SRC;
}
#endif /* CONFIG_BT_PAC_SRC */
/* TODO: We can skip this if we are not connected to any devices */
get_pac_records(NULL, type, &read_buf);
err = bt_gatt_notify_uuid(NULL, uuid, pacs_svc.attrs, read_buf.data,
read_buf.len);
if (err != 0) {
BT_WARN("PACS notify failed: %d", err);
}
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
}
void bt_pacs_add_capability(uint8_t type) void bt_pacs_add_capability(uint8_t type)
{ {
@ -556,6 +587,7 @@ void bt_pacs_remove_capability(uint8_t type)
k_work_reschedule(work, PAC_NOTIFY_TIMEOUT); k_work_reschedule(work, PAC_NOTIFY_TIMEOUT);
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
int bt_pacs_location_changed(enum bt_audio_pac_type type) int bt_pacs_location_changed(enum bt_audio_pac_type type)
{ {
struct k_work_delayable *work; struct k_work_delayable *work;
@ -574,3 +606,4 @@ int bt_pacs_location_changed(enum bt_audio_pac_type type)
return 0; return 0;
} }
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */

View file

@ -52,7 +52,9 @@ int bt_audio_unicast_server_unregister_cb(const struct bt_audio_unicast_server_c
return 0; return 0;
} }
#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(CONFIG_BT_PAC_SRC_LOC)
int bt_audio_unicast_server_location_changed(enum bt_audio_pac_type type) int bt_audio_unicast_server_location_changed(enum bt_audio_pac_type type)
{ {
return bt_pacs_location_changed(type); return bt_pacs_location_changed(type);
} }
#endif /* CONFIG_BT_PAC_SNK_LOC || CONFIG_BT_PAC_SRC_LOC */

View file

@ -209,7 +209,7 @@ static void set_location(void)
{ {
int err; int err;
if (IS_ENABLED(CONFIG_BT_PAC_SNK)) { if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
err = bt_audio_capability_set_location(BT_AUDIO_SINK, err = bt_audio_capability_set_location(BT_AUDIO_SINK,
BT_AUDIO_LOCATION_FRONT_CENTER); BT_AUDIO_LOCATION_FRONT_CENTER);
if (err != 0) { if (err != 0) {
@ -218,7 +218,7 @@ static void set_location(void)
} }
} }
if (IS_ENABLED(CONFIG_BT_PAC_SRC)) { if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
err = bt_audio_capability_set_location(BT_AUDIO_SINK, err = bt_audio_capability_set_location(BT_AUDIO_SINK,
(BT_AUDIO_LOCATION_FRONT_LEFT | (BT_AUDIO_LOCATION_FRONT_LEFT |
BT_AUDIO_LOCATION_FRONT_RIGHT)); BT_AUDIO_LOCATION_FRONT_RIGHT));