summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2023-03-14 18:04:27 +0000
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-03-14 12:45:28 -0700
commit7b654b16fb04431178c13f96ec163779e3cfd752 (patch)
tree72433235f614aa0cc8841d720f3efe36fece915c /src
parent2762129212f1c4045c2ca3628cb49f42cb024689 (diff)
downloadbluez-7b654b16fb04431178c13f96ec163779e3cfd752.tar.gz
shared/bap: fix Locations, Context to be PACS not PAC properties
Audio Locations and Contexts are properties of the PACS service, not of individual PAC, as these are device-wide bitmaps and a single characteristic may exist on PACS server (PACS v1.0 Sec 3). Move the attributes out from bt_bap_pac to bt_bap_pacs, and actually keep track of the values.
Diffstat (limited to 'src')
-rw-r--r--src/shared/bap.c74
1 files changed, 62 insertions, 12 deletions
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 7a53fbc3e..1fff7e0fd 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -91,6 +91,12 @@ struct bt_pacs {
struct gatt_db_attribute *context_ccc;
struct gatt_db_attribute *supported_context;
struct gatt_db_attribute *supported_context_ccc;
+ uint32_t source_loc_value;
+ uint32_t sink_loc_value;
+ uint16_t source_context_value;
+ uint16_t sink_context_value;
+ uint16_t supported_source_context_value;
+ uint16_t supported_sink_context_value;
};
struct bt_ase {
@@ -171,8 +177,6 @@ struct bt_bap_pac {
struct bt_bap_db *bdb;
char *name;
uint8_t type;
- uint32_t locations;
- uint16_t contexts;
struct bt_bap_codec codec;
struct bt_bap_pac_qos qos;
struct iovec *data;
@@ -203,7 +207,6 @@ struct bt_bap_stream_io {
struct bt_bap_stream {
struct bt_bap *bap;
struct bt_bap_endpoint *ep;
- struct queue *pacs;
struct bt_bap_pac *lpac;
struct bt_bap_pac *rpac;
struct iovec *cc;
@@ -380,7 +383,8 @@ static void pacs_sink_loc_read(struct gatt_db_attribute *attrib,
uint8_t opcode, struct bt_att *att,
void *user_data)
{
- uint32_t value = 0x00000003;
+ struct bt_pacs *pacs = user_data;
+ uint32_t value = cpu_to_le32(pacs->sink_loc_value);
gatt_db_attribute_read_result(attrib, id, 0, (void *) &value,
sizeof(value));
@@ -412,7 +416,8 @@ static void pacs_source_loc_read(struct gatt_db_attribute *attrib,
uint8_t opcode, struct bt_att *att,
void *user_data)
{
- uint32_t value = 0x00000001;
+ struct bt_pacs *pacs = user_data;
+ uint32_t value = cpu_to_le32(pacs->source_loc_value);
gatt_db_attribute_read_result(attrib, id, 0, (void *) &value,
sizeof(value));
@@ -423,9 +428,10 @@ static void pacs_context_read(struct gatt_db_attribute *attrib,
uint8_t opcode, struct bt_att *att,
void *user_data)
{
+ struct bt_pacs *pacs = user_data;
struct bt_pacs_context ctx = {
- .snk = 0x0fff,
- .src = 0x000e
+ .snk = cpu_to_le16(pacs->sink_context_value),
+ .src = cpu_to_le16(pacs->source_context_value)
};
gatt_db_attribute_read_result(attrib, id, 0, (void *) &ctx,
@@ -437,9 +443,10 @@ static void pacs_supported_context_read(struct gatt_db_attribute *attrib,
uint8_t opcode, struct bt_att *att,
void *user_data)
{
+ struct bt_pacs *pacs = user_data;
struct bt_pacs_context ctx = {
- .snk = 0x0fff,
- .src = 0x000e
+ .snk = cpu_to_le16(pacs->supported_sink_context_value),
+ .src = cpu_to_le16(pacs->supported_source_context_value)
};
gatt_db_attribute_read_result(attrib, id, 0, (void *) &ctx,
@@ -456,6 +463,14 @@ static struct bt_pacs *pacs_new(struct gatt_db *db)
pacs = new0(struct bt_pacs, 1);
+ /* Set default values */
+ pacs->sink_loc_value = 0x00000003;
+ pacs->source_loc_value = 0x00000001;
+ pacs->sink_context_value = 0x0fff;
+ pacs->source_context_value = 0x000e;
+ pacs->supported_sink_context_value = 0x0fff;
+ pacs->supported_source_context_value = 0x000e;
+
/* Populate DB with PACS attributes */
bt_uuid16_create(&uuid, PACS_UUID);
pacs->service = gatt_db_add_service(db, &uuid, true, 19);
@@ -2862,6 +2877,13 @@ static void read_source_pac_loc(bool success, uint8_t att_ecode,
return;
}
+ if (length != sizeof(uint32_t)) {
+ DBG(bap, "Invalid Source PAC Location size: %d", length);
+ return;
+ }
+
+ pacs->source_loc_value = get_le32(value);
+
gatt_db_attribute_write(pacs->source_loc, 0, value, length, 0, NULL,
NULL, NULL);
@@ -2891,6 +2913,13 @@ static void read_sink_pac_loc(bool success, uint8_t att_ecode,
return;
}
+ if (length != sizeof(uint32_t)) {
+ DBG(bap, "Invalid Sink PAC Location size: %d", length);
+ return;
+ }
+
+ pacs->sink_loc_value = get_le32(value);
+
gatt_db_attribute_write(pacs->sink_loc, 0, value, length, 0, NULL,
NULL, NULL);
@@ -2913,12 +2942,21 @@ static void read_pac_context(bool success, uint8_t att_ecode,
{
struct bt_bap *bap = user_data;
struct bt_pacs *pacs = bap_get_pacs(bap);
+ const struct bt_pacs_context *ctx = (void *)value;
if (!success) {
DBG(bap, "Unable to read PAC Context: error 0x%02x", att_ecode);
return;
}
+ if (length != sizeof(*ctx)) {
+ DBG(bap, "Invalid PAC Context size: %d", length);
+ return;
+ }
+
+ pacs->sink_context_value = le16_to_cpu(ctx->snk);
+ pacs->source_context_value = le16_to_cpu(ctx->src);
+
gatt_db_attribute_write(pacs->context, 0, value, length, 0, NULL,
NULL, NULL);
}
@@ -2929,6 +2967,7 @@ static void read_pac_supported_context(bool success, uint8_t att_ecode,
{
struct bt_bap *bap = user_data;
struct bt_pacs *pacs = bap_get_pacs(bap);
+ const struct bt_pacs_context *ctx = (void *)value;
if (!success) {
DBG(bap, "Unable to read PAC Supproted Context: error 0x%02x",
@@ -2936,6 +2975,14 @@ static void read_pac_supported_context(bool success, uint8_t att_ecode,
return;
}
+ if (length != sizeof(*ctx)) {
+ DBG(bap, "Invalid PAC Supported Context size: %d", length);
+ return;
+ }
+
+ pacs->supported_sink_context_value = le16_to_cpu(ctx->snk);
+ pacs->supported_source_context_value = le16_to_cpu(ctx->src);
+
gatt_db_attribute_write(pacs->supported_context, 0, value, length, 0,
NULL, NULL, NULL);
}
@@ -4596,14 +4643,17 @@ uint8_t bt_bap_stream_get_dir(struct bt_bap_stream *stream)
uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
{
- struct bt_bap_pac *pac;
+ struct bt_pacs *pacs;
if (!stream)
return 0x00000000;
- pac = stream->rpac ? stream->rpac : stream->lpac;
+ pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
- return pac->locations;
+ if (stream->ep->dir == BT_BAP_SOURCE)
+ return pacs->source_loc_value;
+ else
+ return pacs->sink_loc_value;
}
struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream)