All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type
@ 2022-11-04 21:36 Luiz Augusto von Dentz
  2022-11-04 21:36 ` [PATCH BlueZ 2/2] monitor/att: Add support for decoding Characteristic Declaration Luiz Augusto von Dentz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2022-11-04 21:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds handler support for Read by Type so it can further decode
the values when the procedure is used.
---
 monitor/att.c   | 206 ++++++++++++++++++++++++++++++++++--------------
 monitor/l2cap.h |  13 ++-
 2 files changed, 155 insertions(+), 64 deletions(-)

diff --git a/monitor/att.c b/monitor/att.c
index fbd75db03b83..289f4fc04d9a 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -43,6 +43,21 @@
 #include "l2cap.h"
 #include "att.h"
 
+struct att_read {
+	struct gatt_db_attribute *attr;
+	bool in;
+	uint16_t chan;
+	void (*func)(const struct l2cap_frame *frame);
+};
+
+struct att_conn_data {
+	struct gatt_db *ldb;
+	struct timespec ldb_mtim;
+	struct gatt_db *rdb;
+	struct timespec rdb_mtim;
+	struct queue *reads;
+};
+
 static void print_uuid(const char *label, const void *data, uint16_t size)
 {
 	const char *str;
@@ -77,27 +92,66 @@ static void print_handle_range(const char *label, const void *data)
 				get_le16(data), get_le16(data + 2));
 }
 
-static void print_data_list(const char *label, uint8_t length,
-					const void *data, uint16_t size)
+static bool match_read_frame(const void *data, const void *match_data)
 {
+	const struct att_read *read = data;
+	const struct l2cap_frame *frame = match_data;
+
+	/* Read frame and response frame shall be in the opposite direction to
+	 * match.
+	 */
+	if (read->in == frame->in)
+		return false;
+
+	return read->chan == frame->chan;
+}
+
+static void print_data_list(const char *label, uint8_t length,
+					const struct l2cap_frame *frame)
+{
+	struct packet_conn_data *conn;
+	struct att_conn_data *data;
+	struct att_read *read;
 	uint8_t count;
 
 	if (length == 0)
 		return;
 
-	count = size / length;
+	conn = packet_get_conn_data(frame->handle);
+	if (conn) {
+		data = conn->data;
+		if (data)
+			read = queue_remove_if(data->reads, match_read_frame,
+						(void *)frame);
+		else
+			read = NULL;
+	} else
+		read = NULL;
+
+	count = frame->size / length;
 
 	print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies");
 
-	while (size >= length) {
-		print_field("Handle: 0x%4.4x", get_le16(data));
-		print_hex_field("Value", data + 2, length - 2);
+	while (frame->size >= length) {
+		if (!l2cap_frame_print_le16((void *)frame, "Handle"))
+			break;
 
-		data += length;
-		size -= length;
+		print_hex_field("Value", frame->data, length - 2);
+
+		if (read) {
+			struct l2cap_frame f;
+
+			l2cap_frame_clone_size(&f, frame, length - 2);
+
+			read->func(&f);
+		}
+
+		if (!l2cap_frame_pull((void *)frame, frame, length - 2))
+			break;
 	}
 
-	packet_hexdump(data, size);
+	packet_hexdump(frame->data, frame->size);
+	free(read);
 }
 
 static void print_attribute_info(uint16_t type, const void *data, uint16_t len)
@@ -2292,9 +2346,8 @@ struct gatt_handler {
 	GATT_HANDLER(0x2bba, content_control_id_read, NULL, NULL),
 };
 
-static struct gatt_handler *get_handler(struct gatt_db_attribute *attr)
+static struct gatt_handler *get_handler_uuid(const bt_uuid_t *uuid)
 {
-	const bt_uuid_t *uuid = gatt_db_attribute_get_type(attr);
 	size_t i;
 
 	for (i = 0; i < ARRAY_SIZE(gatt_handlers); i++) {
@@ -2307,6 +2360,11 @@ static struct gatt_handler *get_handler(struct gatt_db_attribute *attr)
 	return NULL;
 }
 
+static struct gatt_handler *get_handler(struct gatt_db_attribute *attr)
+{
+	return get_handler_uuid(gatt_db_attribute_get_type(attr));
+}
+
 static void att_exchange_mtu_req(const struct l2cap_frame *frame)
 {
 	const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data;
@@ -2403,36 +2461,23 @@ static void att_find_by_type_val_rsp(const struct l2cap_frame *frame)
 	packet_hexdump(ptr, len);
 }
 
-static void att_read_type_req(const struct l2cap_frame *frame)
+static int bt_uuid_from_data(bt_uuid_t *uuid, const void *data, uint16_t size)
 {
-	print_handle_range("Handle range", frame->data);
-	print_uuid("Attribute type", frame->data + 4, frame->size - 4);
+	uint128_t u128;
+
+	switch (size) {
+	case 2:
+		return bt_uuid16_create(uuid, get_le16(data));
+	case 4:
+		return bt_uuid32_create(uuid, get_le32(data));
+	case 16:
+		memcpy(u128.data, data, sizeof(u128.data));
+		return bt_uuid128_create(uuid, u128);
+	}
+
+	return -EINVAL;
 }
 
-static void att_read_type_rsp(const struct l2cap_frame *frame)
-{
-	const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data;
-
-	print_field("Attribute data length: %d", pdu->length);
-	print_data_list("Attribute data list", pdu->length,
-					frame->data + 1, frame->size - 1);
-}
-
-struct att_read {
-	struct gatt_db_attribute *attr;
-	bool in;
-	uint16_t chan;
-	void (*func)(const struct l2cap_frame *frame);
-};
-
-struct att_conn_data {
-	struct gatt_db *ldb;
-	struct timespec ldb_mtim;
-	struct gatt_db *rdb;
-	struct timespec rdb_mtim;
-	struct queue *reads;
-};
-
 static void att_conn_data_free(void *data)
 {
 	struct att_conn_data *att_data = data;
@@ -2443,6 +2488,67 @@ static void att_conn_data_free(void *data)
 	free(att_data);
 }
 
+static struct att_conn_data *att_get_conn_data(struct packet_conn_data *conn)
+{
+	struct att_conn_data *data = conn->data;
+
+	if (data)
+		return data;
+
+	data = new0(struct att_conn_data, 1);
+	data->rdb = gatt_db_new();
+	data->ldb = gatt_db_new();
+	conn->data = data;
+	conn->destroy = att_conn_data_free;
+
+	return data;
+}
+
+static void att_read_type_req(const struct l2cap_frame *frame)
+{
+	bt_uuid_t uuid;
+	struct packet_conn_data *conn;
+	struct att_conn_data *data;
+	struct att_read *read;
+	struct gatt_handler *handler;
+
+	print_handle_range("Handle range", frame->data);
+	print_uuid("Attribute type", frame->data + 4, frame->size - 4);
+
+	if (bt_uuid_from_data(&uuid, frame->data + 4, frame->size - 4))
+		return;
+
+	handler = get_handler_uuid(&uuid);
+	if (!handler || !handler->read)
+		return;
+
+	conn = packet_get_conn_data(frame->handle);
+	data = att_get_conn_data(conn);
+
+	if (!data->reads)
+		data->reads = queue_new();
+
+	read = new0(struct att_read, 1);
+	read->in = frame->in;
+	read->chan = frame->chan;
+	read->func = handler->read;
+
+	queue_push_tail(data->reads, read);
+}
+
+static void att_read_type_rsp(const struct l2cap_frame *frame)
+{
+	uint8_t len;
+
+	if (!l2cap_frame_get_u8((void *)frame, &len)) {
+		print_text(COLOR_ERROR, "invalid size");
+		return;
+	}
+
+	print_field("Attribute data length: %d", len);
+	print_data_list("Attribute data list", len, frame);
+}
+
 static void gatt_load_db(struct gatt_db *db, const char *filename,
 						struct timespec *mtim)
 {
@@ -2467,19 +2573,11 @@ static void gatt_load_db(struct gatt_db *db, const char *filename,
 
 static void load_gatt_db(struct packet_conn_data *conn)
 {
-	struct att_conn_data *data = conn->data;
+	struct att_conn_data *data = att_get_conn_data(conn);
 	char filename[PATH_MAX];
 	char local[18];
 	char peer[18];
 
-	if (!data) {
-		data = new0(struct att_conn_data, 1);
-		data->rdb = gatt_db_new();
-		data->ldb = gatt_db_new();
-		conn->data = data;
-		conn->destroy = att_conn_data_free;
-	}
-
 	ba2str((bdaddr_t *)conn->src, local);
 	ba2str((bdaddr_t *)conn->dst, peer);
 
@@ -2605,20 +2703,6 @@ static void att_read_req(const struct l2cap_frame *frame)
 	queue_push_tail(data->reads, read);
 }
 
-static bool match_read_frame(const void *data, const void *match_data)
-{
-	const struct att_read *read = data;
-	const struct l2cap_frame *frame = match_data;
-
-	/* Read frame and response frame shall be in the opposite direction to
-	 * match.
-	 */
-	if (read->in == frame->in)
-		return false;
-
-	return read->chan == frame->chan;
-}
-
 static void att_read_rsp(const struct l2cap_frame *frame)
 {
 	struct packet_conn_data *conn;
diff --git a/monitor/l2cap.h b/monitor/l2cap.h
index e63377857cf7..935066e6e7dc 100644
--- a/monitor/l2cap.h
+++ b/monitor/l2cap.h
@@ -31,8 +31,9 @@ void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in,
 				uint16_t cid, uint16_t psm,
 				const void *data, uint16_t size);
 
-static inline void l2cap_frame_clone(struct l2cap_frame *frame,
-				const struct l2cap_frame *source)
+static inline void l2cap_frame_clone_size(struct l2cap_frame *frame,
+				const struct l2cap_frame *source,
+				uint16_t size)
 {
 	if (frame != source) {
 		frame->index   = source->index;
@@ -44,10 +45,16 @@ static inline void l2cap_frame_clone(struct l2cap_frame *frame,
 		frame->chan    = source->chan;
 		frame->mode    = source->mode;
 		frame->data    = source->data;
-		frame->size    = source->size;
+		frame->size    = size;
 	}
 }
 
+static inline void l2cap_frame_clone(struct l2cap_frame *frame,
+				const struct l2cap_frame *source)
+{
+	l2cap_frame_clone_size(frame, source, source->size);
+}
+
 static inline void *l2cap_frame_pull(struct l2cap_frame *frame,
 				const struct l2cap_frame *source, uint16_t len)
 {
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH BlueZ 2/2] monitor/att: Add support for decoding Characteristic Declaration
  2022-11-04 21:36 [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type Luiz Augusto von Dentz
@ 2022-11-04 21:36 ` Luiz Augusto von Dentz
  2022-11-04 22:23 ` [BlueZ,1/2] monitor/att: Add handler support for Read by Type bluez.test.bot
  2022-11-07 19:10 ` [PATCH BlueZ 1/2] " patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2022-11-04 21:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds supports for decoding the so called Characteristic
Declaration (0x2803):

> ACL Data RX: Handle 3585 flags 0x02 dlen 76
      ATT: Read By Type Response (0x09) len 71
        Attribute data length: 7
        Attribute data list: 10 entries
        Handle: 0x0002
        Value: 200300052a
            Properties: 0x20
              Indicate (0x20)
            Value Handle: 0x0003
            Value UUID: Service Changed (0x2a05)
        Handle: 0x0015
        Value: 021600002a
            Properties: 0x02
              Read (0x02)
            Value Handle: 0x0016
            Value UUID: Device Name (0x2a00)
        Handle: 0x0017
        Value: 021800012a
            Properties: 0x02
              Read (0x02)
            Value Handle: 0x0018
            Value UUID: Appearance (0x2a01)
        Handle: 0x0019
        Value: 021a00a62a
            Properties: 0x02
              Read (0x02)
            Value Handle: 0x001a
            Value UUID: Central Address Resolution (0x2aa6)
        Handle: 0x0029
        Value: 102a00372a
            Properties: 0x10
              Notify (0x10)
            Value Handle: 0x002a
            Value UUID: Heart Rate Measurement (0x2a37)
        Handle: 0x002c
        Value: 022d00382a
            Properties: 0x02
              Read (0x02)
            Value Handle: 0x002d
            Value UUID: Body Sensor Location (0x2a38)
        Handle: 0x002e
        Value: 082f00392a
            Properties: 0x08
              Write (0x08)
            Value Handle: 0x002f
            Value UUID: Heart Rate Control Point (0x2a39)
        Handle: 0x0031
        Value: 0a32008a2a
            Properties: 0x0a
              Read (0x02)
              Write (0x08)
            Value Handle: 0x0032
            Value UUID: First Name (0x2a8a)
        Handle: 0x0033
        Value: 0a3400902a
            Properties: 0x0a
              Read (0x02)
              Write (0x08)
            Value Handle: 0x0034
            Value UUID: Last Name (0x2a90)
        Handle: 0x0035
        Value: 0a36008c2a
            Properties: 0x0a
              Read (0x02)
              Write (0x08)
            Value Handle: 0x0036
            Value UUID: Gender (0x2a8c)
---
 monitor/att.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/monitor/att.c b/monitor/att.c
index 289f4fc04d9a..efd840d51961 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -273,6 +273,46 @@ static void att_error_response(const struct l2cap_frame *frame)
 	print_field("Error: %s (0x%2.2x)", str, pdu->error);
 }
 
+static const struct bitfield_data chrc_prop_table[] = {
+	{  0, "Broadcast (0x01)"		},
+	{  1, "Read (0x02)"			},
+	{  2, "Write Without Response (0x04)"	},
+	{  3, "Write (0x08)"			},
+	{  4, "Notify (0x10)"			},
+	{  5, "Indicate (0x20)"			},
+	{  6, "Authorize (0x40)"		},
+	{  6, "Extended Properties (0x80)"	},
+	{ }
+};
+
+static void print_chrc(const struct l2cap_frame *frame)
+{
+	uint8_t prop;
+	uint8_t mask;
+
+	if (!l2cap_frame_get_u8((void *)frame, &prop)) {
+		print_text(COLOR_ERROR, "Property: invalid size");
+		return;
+	}
+
+	print_field("    Properties: 0x%2.2x", prop);
+
+	mask = print_bitfield(6, prop, chrc_prop_table);
+	if (mask)
+		print_text(COLOR_WHITE_BG, "    Unknown fields (0x%2.2x)",
+								mask);
+
+	if (!l2cap_frame_print_le16((void *)frame, "    Value Handle"))
+		return;
+
+	print_uuid("    Value UUID", frame->data, frame->size);
+}
+
+static void chrc_read(const struct l2cap_frame *frame)
+{
+	print_chrc(frame);
+}
+
 static const struct bitfield_data ccc_value_table[] = {
 	{  0, "Notification (0x01)"		},
 	{  1, "Indication (0x02)"		},
@@ -2314,6 +2354,7 @@ struct gatt_handler {
 	void (*write)(const struct l2cap_frame *frame);
 	void (*notify)(const struct l2cap_frame *frame);
 } gatt_handlers[] = {
+	GATT_HANDLER(0x2803, chrc_read, NULL, NULL),
 	GATT_HANDLER(0x2902, ccc_read, ccc_write, NULL),
 	GATT_HANDLER(0x2bc4, ase_read, NULL, ase_notify),
 	GATT_HANDLER(0x2bc5, ase_read, NULL, ase_notify),
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [BlueZ,1/2] monitor/att: Add handler support for Read by Type
  2022-11-04 21:36 [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type Luiz Augusto von Dentz
  2022-11-04 21:36 ` [PATCH BlueZ 2/2] monitor/att: Add support for decoding Characteristic Declaration Luiz Augusto von Dentz
@ 2022-11-04 22:23 ` bluez.test.bot
  2022-11-07 19:10 ` [PATCH BlueZ 1/2] " patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2022-11-04 22:23 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

[-- Attachment #1: Type: text/plain, Size: 1049 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=692284

---Test result---

Test Summary:
CheckPatch                    PASS      2.48 seconds
GitLint                       PASS      1.63 seconds
Prep - Setup ELL              PASS      26.72 seconds
Build - Prep                  PASS      0.74 seconds
Build - Configure             PASS      8.59 seconds
Build - Make                  PASS      822.68 seconds
Make Check                    PASS      11.56 seconds
Make Check w/Valgrind         PASS      292.16 seconds
Make Distcheck                PASS      237.97 seconds
Build w/ext ELL - Configure   PASS      8.62 seconds
Build w/ext ELL - Make        PASS      85.40 seconds
Incremental Build w/ patches  PASS      204.50 seconds
Scan Build                    PASS      603.42 seconds



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type
  2022-11-04 21:36 [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type Luiz Augusto von Dentz
  2022-11-04 21:36 ` [PATCH BlueZ 2/2] monitor/att: Add support for decoding Characteristic Declaration Luiz Augusto von Dentz
  2022-11-04 22:23 ` [BlueZ,1/2] monitor/att: Add handler support for Read by Type bluez.test.bot
@ 2022-11-07 19:10 ` patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+bluetooth @ 2022-11-07 19:10 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Fri,  4 Nov 2022 14:36:48 -0700 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This adds handler support for Read by Type so it can further decode
> the values when the procedure is used.
> ---
>  monitor/att.c   | 206 ++++++++++++++++++++++++++++++++++--------------
>  monitor/l2cap.h |  13 ++-
>  2 files changed, 155 insertions(+), 64 deletions(-)

Here is the summary with links:
  - [BlueZ,1/2] monitor/att: Add handler support for Read by Type
    (no matching commit)
  - [BlueZ,2/2] monitor/att: Add support for decoding Characteristic Declaration
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7e0e08ca5396

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-11-07 19:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-04 21:36 [PATCH BlueZ 1/2] monitor/att: Add handler support for Read by Type Luiz Augusto von Dentz
2022-11-04 21:36 ` [PATCH BlueZ 2/2] monitor/att: Add support for decoding Characteristic Declaration Luiz Augusto von Dentz
2022-11-04 22:23 ` [BlueZ,1/2] monitor/att: Add handler support for Read by Type bluez.test.bot
2022-11-07 19:10 ` [PATCH BlueZ 1/2] " patchwork-bot+bluetooth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.