All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/1] monitor/att: Add decoding support for BASS
@ 2023-04-04 14:30 Iulia Tanasescu
  2023-04-04 14:30 ` [PATCH BlueZ 1/1] " Iulia Tanasescu
  0 siblings, 1 reply; 6+ messages in thread
From: Iulia Tanasescu @ 2023-04-04 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Iulia Tanasescu

This patch adds decoding support for BASS attributes

Iulia Tanasescu (1):
  monitor/att: Add decoding support for BASS

 monitor/att.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 461 insertions(+)


base-commit: de8e7cfce25b8d717f5ee60ee3b79d426fdcc681
-- 
2.34.1


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

* [PATCH BlueZ 1/1] monitor/att: Add decoding support for BASS
  2023-04-04 14:30 [PATCH BlueZ 0/1] monitor/att: Add decoding support for BASS Iulia Tanasescu
@ 2023-04-04 14:30 ` Iulia Tanasescu
  2023-04-04 15:31   ` bluez.test.bot
  2023-04-04 18:13   ` [PATCH BlueZ 1/1] " Luiz Augusto von Dentz
  0 siblings, 2 replies; 6+ messages in thread
From: Iulia Tanasescu @ 2023-04-04 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Iulia Tanasescu

This adds decoding support for BASS attributes:

> ACL Data RX: Handle 0 flags 0x02 dlen 7
      ATT: Read Request (0x0a) len 2
        Handle: 0x003a Type: Broadcast Receive State (0x2bc8)

< ACL Data TX: Handle 0 flags 0x00 dlen 45
      ATT: Read Response (0x0b) len 40
        Value: 0100f2698be807c0013a65010203b803eac6afbb65a25a41f15305
        	68020101000000000403020400
        Handle: 0x003a Type: Broadcast Receive State (0x2bc8)
          Source_ID: 1
          Source_Address_Type: 0
          Source_Address: C0:07:E8:8B:69:F2
          Source_Adv_SID: 1
          Broadcast_ID: 0x01653a
          PA_Sync_State: Synchronized to PA
          BIG_Encryption: Broadcast_Code required
          Num_Subgroups: 1
          Subgroup #0:
            BIS_Sync State: 0x00000000
            Metadata #0: len 0x03 type 0x02
            Metadata: 0400

> ACL Data RX: Handle 0 flags 0x02 dlen 7
      ATT: Read Request (0x0a) len 2
        Handle: 0x003d Type: Broadcast Receive State (0x2bc8)

< ACL Data TX: Handle 0 flags 0x00 dlen 5
      ATT: Read Response (0x0b) len 0
        Value: 
        Handle: 0x003d Type: Broadcast Receive State (0x2bc8)
          Empty characteristic

> ACL Data RX: Handle 0 flags 0x02 dlen 8
      ATT: Write Request (0x12) len 3
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 00
            Opcode: Remote Scan Stopped (0x00)

< ACL Data TX: Handle 0 flags 0x00 dlen 9
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x0040
        Error: Reserved (0x80)

> ACL Data RX: Handle 0 flags 0x02 dlen 8
      ATT: Write Request (0x12) len 3
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 01
            Opcode: Remote Scan Started (0x01)

< ACL Data TX: Handle 0 flags 0x00 dlen 9
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x0040
        Error: Reserved (0x80)

> ACL Data RX: Handle 0 flags 0x01 dlen 5
      ATT: Write Request (0x12) len 27
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 0200f2698be807c0013a650100ffff01000000000403020400
            Opcode: Add Source (0x02)
            Source_Address_Type: 0
            Source_Address: C0:07:E8:8B:69:F2
            Source_Adv_SID: 1
            Broadcast_ID: 0x01653a
            PA_Sync_State: Do not synchronize to PA
            PA_Interval: 0xffff
            Num_Subgroups: 1
            Subgroup #0:
              BIS_Sync State: 0x00000000
              Metadata #0: len 0x03 type 0x02
              Metadata: 0400

< ACL Data TX: Handle 0 flags 0x00 dlen 9
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x0040
        Error: Reserved (0x80)

> ACL Data RX: Handle 0 flags 0x02 dlen 22
      ATT: Write Request (0x12) len 17
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 030102780001000000000403040400
            Opcode: Modify Source (0x03)
            Source_ID: 1
            PA_Sync_State: Synchronize to PA - PAST not available
            PA_Interval: 0x0078
            Num_Subgroups: 1
            Subgroup #0:
              BIS_Sync State: 0x00000000
              Metadata #0: len 0x03 type 0x04
              Metadata: 0400

< ACL Data TX: Handle 0 flags 0x00 dlen 9
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x0040
        Error: Reserved (0x80)

> ACL Data RX: Handle 0 flags 0x02 dlen 25
      ATT: Write Request (0x12) len 20
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 0401b803eac6afbb65a25a41f15305680201
            Opcode: Set Broadcast_Code (0x04)
            Source_ID: 1
            Broadcast_Code: b803eac6afbb65a25a41f15305680201

< ACL Data TX: Handle 0 flags 0x00 dlen 5
      ATT: Write Response (0x13) len 0

< ACL Data TX: Handle 0 flags 0x00 dlen 33
      ATT: Handle Multiple Value Notification (0x23) len 28
        Length: 0x0018
        Handle: 0x003a Type: Broadcast Receive State (0x2bc8)
          Data: 0100f2698be807c0013a6501020201000000000403020400
          Source_ID: 1
          Source_Address_Type: 0
          Source_Address: C0:07:E8:8B:69:F2
          Source_Adv_SID: 1
          Broadcast_ID: 0x01653a
          PA_Sync_State: Synchronized to PA
          BIG_Encryption: Decrypting
          Num_Subgroups: 1
          Subgroup #0:
            BIS_Sync State: 0x00000000
            Metadata #0: len 0x03 type 0x02
            Metadata: 0400

> ACL Data RX: Handle 0 flags 0x02 dlen 9
      ATT: Write Request (0x12) len 4
        Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
          Data: 0501
            Opcode: Remove Source (0x05)
            Source_ID: 1

< ACL Data TX: Handle 0 flags 0x00 dlen 9
      ATT: Error Response (0x01) len 4
        Write Request (0x12)
        Handle: 0x0040
        Error: Reserved (0x80)

---
 monitor/att.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 461 insertions(+)

diff --git a/monitor/att.c b/monitor/att.c
index ff77620c5..4baf029ed 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -5,6 +5,7 @@
  *
  *  Copyright (C) 2011-2014  Intel Corporation
  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright 2023 NXP
  *
  *
  */
@@ -2514,6 +2515,462 @@ static void content_control_id_read(const struct l2cap_frame *frame)
 	print_content_control_id(frame);
 }
 
+static const struct pa_sync_state_decoder {
+	uint8_t code;
+	char *value;
+} pa_sync_state_decoders[] = {
+	{ 0x00, "Not synchronized to PA" },
+	{ 0x01, "SyncInfo Request" },
+	{ 0x02, "Synchronized to PA" },
+	{ 0x03, "Failed to synchronize to PA" },
+	{ 0x04, "No PAST" },
+};
+
+static const struct cp_pa_sync_state_decoder {
+	uint8_t code;
+	char *value;
+} cp_pa_sync_state_decoders[] = {
+	{ 0x00, "Do not synchronize to PA" },
+	{ 0x01, "Synchronize to PA - PAST available" },
+	{ 0x02, "Synchronize to PA - PAST not available" },
+};
+
+static const struct big_enc_decoder {
+	uint8_t code;
+	char *value;
+} big_enc_decoders[] = {
+	{ 0x00, "Not encrypted" },
+	{ 0x01, "Broadcast_Code required" },
+	{ 0x02, "Decrypting" },
+	{ 0x03, "Bad_Code (incorrect encryption key)" },
+};
+
+static bool print_subgroup_lv(const struct l2cap_frame *frame,
+		const char *label, struct packet_ltv_decoder *decoder,
+		size_t decoder_len)
+{
+	struct bt_hci_lv_data *lv;
+
+	lv = l2cap_frame_pull((void *)frame, frame, sizeof(*lv));
+	if (!lv) {
+		print_text(COLOR_ERROR, "%s: invalid size", label);
+		return false;
+	}
+
+	if (!l2cap_frame_pull((void *)frame, frame, lv->len)) {
+		print_text(COLOR_ERROR, "%s: invalid size", label);
+		return false;
+	}
+
+	packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len);
+
+	return true;
+}
+
+static bool print_subgroup_metadata(const char *label,
+				const struct l2cap_frame *frame)
+{
+	return print_subgroup_lv(frame, label, NULL, 0);
+}
+
+static void print_bcast_recv_state(const struct l2cap_frame *frame)
+{
+	uint8_t i;
+	uint8_t id;
+	uint8_t addr_type;
+	uint8_t *addr;
+	uint8_t sid;
+	uint32_t bid;
+	uint8_t pa_sync_state;
+	uint8_t enc;
+	uint8_t *bad_code;
+	uint8_t num_subgroups = 0;
+	uint32_t bis_sync_state;
+
+	if (frame->size == 0) {
+		print_field("  Empty characteristic");
+		goto done;
+	}
+
+	if (!l2cap_frame_get_u8((void *)frame, &id)) {
+		print_text(COLOR_ERROR, "Source_ID: invalid size");
+		goto done;
+	}
+
+	print_field("  Source_ID: %u", id);
+
+	if (!l2cap_frame_get_u8((void *)frame, &addr_type)) {
+		print_text(COLOR_ERROR, "Source_Address_Type: invalid size");
+		goto done;
+	}
+
+	print_field("  Source_Address_Type: %u", addr_type);
+
+	addr = l2cap_frame_pull((void *)frame, frame, sizeof(bdaddr_t));
+	if (!addr) {
+		print_text(COLOR_ERROR, "Source_Address: invalid size");
+		goto done;
+	}
+
+	print_field("  Source_Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+					addr[5], addr[4],
+					addr[3], addr[2],
+					addr[1], addr[0]);
+
+	if (!l2cap_frame_get_u8((void *)frame, &sid)) {
+		print_text(COLOR_ERROR, "Source_Adv_SID: invalid size");
+		goto done;
+	}
+
+	print_field("  Source_Adv_SID: %u", sid);
+
+	if (!l2cap_frame_get_le24((void *)frame, &bid)) {
+		print_text(COLOR_ERROR, "Broadcast_ID: invalid size");
+		goto done;
+	}
+
+	print_field("  Broadcast_ID: 0x%06x", bid);
+
+	if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
+		print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
+		goto done;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pa_sync_state_decoders); i++) {
+		const struct pa_sync_state_decoder *decoder;
+
+		decoder = &pa_sync_state_decoders[i];
+
+		if (decoder->code == pa_sync_state) {
+			print_field("  PA_Sync_State: %s", decoder->value);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(pa_sync_state_decoders))
+		print_field("  PA_Sync_State: %s", "Invalid value");
+
+	if (!l2cap_frame_get_u8((void *)frame, &enc)) {
+		print_text(COLOR_ERROR, "BIG_Encryption: invalid size");
+		goto done;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(big_enc_decoders); i++) {
+		const struct big_enc_decoder *decoder;
+
+		decoder = &big_enc_decoders[i];
+
+		if (decoder->code == enc) {
+			print_field("  BIG_Encryption: %s", decoder->value);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(big_enc_decoders))
+		print_field("  BIG_Encryption: %s", "Invalid value");
+
+	if (enc == 0x03) {
+		bad_code = l2cap_frame_pull((void *)frame, frame, 16);
+		if (!bad_code) {
+			print_text(COLOR_ERROR, "Bad_Code: invalid size");
+			goto done;
+		}
+
+		print_hex_field("  Bad_Code", bad_code, 16);
+	}
+
+	if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
+		print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
+		goto done;
+	}
+
+	print_field("  Num_Subgroups: %u", num_subgroups);
+
+	for (i = 0; i < num_subgroups; i++) {
+		print_field("  Subgroup #%u:", i);
+
+		if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
+			print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
+			goto done;
+		}
+
+		print_field("    BIS_Sync State: 0x%8.8x", bis_sync_state);
+
+		if (!print_subgroup_metadata("    Metadata", frame))
+			goto done;
+	}
+
+done:
+	if (frame->size)
+		print_hex_field("  Data", frame->data, frame->size);
+}
+
+static void bcast_recv_state_read(const struct l2cap_frame *frame)
+{
+	print_bcast_recv_state(frame);
+}
+
+static void bcast_recv_state_notify(const struct l2cap_frame *frame)
+{
+	print_bcast_recv_state(frame);
+}
+
+#define BCAST_AUDIO_SCAN_CP_CMD(_op, _desc, _func) \
+[_op] = { \
+	.desc = _desc, \
+	.func = _func, \
+}
+
+static void bcast_audio_scan_cp_add_src_cmd(const struct l2cap_frame *frame)
+{
+	uint8_t i;
+	uint8_t addr_type;
+	uint8_t *addr;
+	uint8_t sid;
+	uint32_t bid;
+	uint8_t pa_sync_state;
+	uint16_t pa_interval;
+	uint8_t num_subgroups = 0;
+	uint32_t bis_sync_state;
+
+	if (!l2cap_frame_get_u8((void *)frame, &addr_type)) {
+		print_text(COLOR_ERROR, "Source_Address_Type: invalid size");
+		return;
+	}
+
+	print_field("    Source_Address_Type: %u", addr_type);
+
+	addr = l2cap_frame_pull((void *)frame, frame, sizeof(bdaddr_t));
+	if (!addr) {
+		print_text(COLOR_ERROR, "Source_Address: invalid size");
+		return;
+	}
+
+	print_field("    Source_Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+					addr[5], addr[4],
+					addr[3], addr[2],
+					addr[1], addr[0]);
+
+	if (!l2cap_frame_get_u8((void *)frame, &sid)) {
+		print_text(COLOR_ERROR, "Source_Adv_SID: invalid size");
+		return;
+	}
+
+	print_field("    Source_Adv_SID: %u", sid);
+
+	if (!l2cap_frame_get_le24((void *)frame, &bid)) {
+		print_text(COLOR_ERROR, "Broadcast_ID: invalid size");
+		return;
+	}
+
+	print_field("    Broadcast_ID: 0x%06x", bid);
+
+	if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
+		print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cp_pa_sync_state_decoders); i++) {
+		const struct cp_pa_sync_state_decoder *decoder;
+
+		decoder = &cp_pa_sync_state_decoders[i];
+
+		if (decoder->code == pa_sync_state) {
+			print_field("    PA_Sync_State: %s", decoder->value);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(cp_pa_sync_state_decoders))
+		print_field("    PA_Sync_State: %s", "Invalid value");
+
+	if (!l2cap_frame_get_le16((void *)frame, &pa_interval)) {
+		print_text(COLOR_ERROR, "PA_Interval: invalid size");
+		return;
+	}
+
+	print_field("    PA_Interval: 0x%04x", pa_interval);
+
+	if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
+		print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
+		return;
+	}
+
+	print_field("    Num_Subgroups: %u", num_subgroups);
+
+	for (i = 0; i < num_subgroups; i++) {
+		print_field("    Subgroup #%u:", i);
+
+		if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
+			print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
+			return;
+		}
+
+		print_field("      BIS_Sync State: 0x%8.8x", bis_sync_state);
+
+		if (!print_subgroup_metadata("      Metadata", frame))
+			return;
+	}
+}
+
+static void bcast_audio_scan_cp_mod_src_cmd(const struct l2cap_frame *frame)
+{
+	uint8_t i;
+	uint8_t id;
+	uint8_t pa_sync_state;
+	uint16_t pa_interval;
+	uint8_t num_subgroups = 0;
+	uint32_t bis_sync_state;
+
+	if (!l2cap_frame_get_u8((void *)frame, &id)) {
+		print_text(COLOR_ERROR, "Source_ID: invalid size");
+		return;
+	}
+
+	print_field("    Source_ID: %u", id);
+
+	if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
+		print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cp_pa_sync_state_decoders); i++) {
+		const struct cp_pa_sync_state_decoder *decoder;
+
+		decoder = &cp_pa_sync_state_decoders[i];
+
+		if (decoder->code == pa_sync_state) {
+			print_field("    PA_Sync_State: %s", decoder->value);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(cp_pa_sync_state_decoders))
+		print_field("    PA_Sync_State: %s", "Invalid value");
+
+	if (!l2cap_frame_get_le16((void *)frame, &pa_interval)) {
+		print_text(COLOR_ERROR, "PA_Interval: invalid size");
+		return;
+	}
+
+	print_field("    PA_Interval: 0x%04x", pa_interval);
+
+	if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
+		print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
+		return;
+	}
+
+	print_field("    Num_Subgroups: %u", num_subgroups);
+
+	for (i = 0; i < num_subgroups; i++) {
+		print_field("    Subgroup #%u:", i);
+
+		if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
+			print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
+			return;
+		}
+
+		print_field("      BIS_Sync State: 0x%8.8x", bis_sync_state);
+
+		if (!print_subgroup_metadata("      Metadata", frame))
+			return;
+	}
+}
+
+static void bcast_audio_scan_cp_set_bcode_cmd(const struct l2cap_frame *frame)
+{
+	uint8_t id;
+	uint8_t *bcast_code;
+
+	if (!l2cap_frame_get_u8((void *)frame, &id)) {
+		print_text(COLOR_ERROR, "Source_ID: invalid size");
+		return;
+	}
+
+	print_field("    Source_ID: %u", id);
+
+	bcast_code = l2cap_frame_pull((void *)frame, frame, 16);
+	if (!bcast_code) {
+		print_text(COLOR_ERROR, "Broadcast_Code: invalid size");
+		return;
+	}
+
+	print_hex_field("    Broadcast_Code", bcast_code, 16);
+
+}
+
+static void bcast_audio_scan_cp_remove_src_cmd(const struct l2cap_frame *frame)
+{
+	uint8_t id;
+
+	if (!l2cap_frame_get_u8((void *)frame, &id)) {
+		print_text(COLOR_ERROR, "Source_ID: invalid size");
+		return;
+	}
+
+	print_field("    Source_ID: %u", id);
+}
+
+struct bcast_audio_scan_cp_cmd {
+	const char *desc;
+	void (*func)(const struct l2cap_frame *frame);
+} bcast_audio_scan_cp_cmd_table[] = {
+	/* Opcode = 0x00 (Remote Scan Stopped) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x00, "Remote Scan Stopped", NULL),
+	/* Opcode = 0x01 (Remote Scan Started) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x01, "Remote Scan Started", NULL),
+	/* Opcode = 0x02 (Add Source) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x02, "Add Source",
+					bcast_audio_scan_cp_add_src_cmd),
+	/* Opcode = 0x03 (Modify Source) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x03, "Modify Source",
+					bcast_audio_scan_cp_mod_src_cmd),
+	/* Opcode = 0x04 (Set Broadcast_Code) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x04, "Set Broadcast_Code",
+					bcast_audio_scan_cp_set_bcode_cmd),
+	/* Opcode = 0x05 (Remove Source) */
+	BCAST_AUDIO_SCAN_CP_CMD(0x05, "Remove Source",
+					bcast_audio_scan_cp_remove_src_cmd),
+};
+
+static struct bcast_audio_scan_cp_cmd *bcast_audio_scan_cp_get_cmd(uint8_t op)
+{
+	if (op > ARRAY_SIZE(bcast_audio_scan_cp_cmd_table))
+		return NULL;
+
+	return &bcast_audio_scan_cp_cmd_table[op];
+}
+
+static void print_bcast_audio_scan_cp_cmd(const struct l2cap_frame *frame)
+{
+	uint8_t op;
+	struct bcast_audio_scan_cp_cmd *cmd;
+
+	if (!l2cap_frame_get_u8((void *)frame, &op)) {
+		print_text(COLOR_ERROR, "Opcode: invalid size");
+		goto done;
+	}
+
+	cmd = bcast_audio_scan_cp_get_cmd(op);
+	if (!cmd) {
+		print_field("    Opcode: Reserved (0x%2.2x)", op);
+		goto done;
+	}
+
+	print_field("    Opcode: %s (0x%2.2x)", cmd->desc, op);
+	if (cmd->func)
+		cmd->func(frame);
+
+done:
+	if (frame->size)
+		print_hex_field("  Data", frame->data, frame->size);
+}
+
+static void bcast_audio_scan_cp_write(const struct l2cap_frame *frame)
+{
+	print_bcast_audio_scan_cp_cmd(frame);
+}
+
 #define GATT_HANDLER(_uuid, _read, _write, _notify) \
 { \
 	.uuid = { \
@@ -2568,6 +3025,10 @@ struct gatt_handler {
 	GATT_HANDLER(0x2ba5, media_cp_op_supported_read, NULL,
 					media_cp_op_supported_notify),
 	GATT_HANDLER(0x2bba, content_control_id_read, NULL, NULL),
+
+	GATT_HANDLER(0x2bc7, NULL, bcast_audio_scan_cp_write, NULL),
+	GATT_HANDLER(0x2bc8, bcast_recv_state_read, NULL,
+					bcast_recv_state_notify),
 };
 
 static struct gatt_handler *get_handler_uuid(const bt_uuid_t *uuid)
-- 
2.34.1


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

* RE: monitor/att: Add decoding support for BASS
  2023-04-04 14:30 ` [PATCH BlueZ 1/1] " Iulia Tanasescu
@ 2023-04-04 15:31   ` bluez.test.bot
  2023-04-04 18:13   ` [PATCH BlueZ 1/1] " Luiz Augusto von Dentz
  1 sibling, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2023-04-04 15:31 UTC (permalink / raw)
  To: linux-bluetooth, iulia.tanasescu

[-- Attachment #1: Type: text/plain, Size: 1791 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=736846

---Test result---

Test Summary:
CheckPatch                    PASS      0.79 seconds
GitLint                       FAIL      0.70 seconds
BuildEll                      PASS      26.74 seconds
BluezMake                     PASS      758.73 seconds
MakeCheck                     PASS      11.53 seconds
MakeDistcheck                 PASS      149.92 seconds
CheckValgrind                 PASS      242.62 seconds
CheckSmatch                   WARNING   329.06 seconds
bluezmakeextell               PASS      98.21 seconds
IncrementalBuild              PASS      617.07 seconds
ScanBuild                     PASS      988.58 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,1/1] monitor/att: Add decoding support for BASS

WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
12: B3 Line contains hard tab characters (\t): "        	68020101000000000403020400"
33: B2 Line has trailing whitespace: "        Value: "
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
monitor/att.c: note: in included file:monitor/display.h:82:26: warning: Variable length array is used.


---
Regards,
Linux Bluetooth


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

* Re: [PATCH BlueZ 1/1] monitor/att: Add decoding support for BASS
  2023-04-04 14:30 ` [PATCH BlueZ 1/1] " Iulia Tanasescu
  2023-04-04 15:31   ` bluez.test.bot
@ 2023-04-04 18:13   ` Luiz Augusto von Dentz
  2023-04-05 11:46     ` Iulia Tanasescu
  1 sibling, 1 reply; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2023-04-04 18:13 UTC (permalink / raw)
  To: Iulia Tanasescu; +Cc: linux-bluetooth

Hi Iulia,

On Tue, Apr 4, 2023 at 7:47 AM Iulia Tanasescu <iulia.tanasescu@nxp.com> wrote:
>
> This adds decoding support for BASS attributes:
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 7
>       ATT: Read Request (0x0a) len 2
>         Handle: 0x003a Type: Broadcast Receive State (0x2bc8)
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 45
>       ATT: Read Response (0x0b) len 40
>         Value: 0100f2698be807c0013a65010203b803eac6afbb65a25a41f15305
>                 68020101000000000403020400
>         Handle: 0x003a Type: Broadcast Receive State (0x2bc8)

Swap these 2 lines above so Handle is printed first and values latter.

>           Source_ID: 1
>           Source_Address_Type: 0
>           Source_Address: C0:07:E8:8B:69:F2
>           Source_Adv_SID: 1
>           Broadcast_ID: 0x01653a
>           PA_Sync_State: Synchronized to PA
>           BIG_Encryption: Broadcast_Code required
>           Num_Subgroups: 1
>           Subgroup #0:
>             BIS_Sync State: 0x00000000
>             Metadata #0: len 0x03 type 0x02
>             Metadata: 0400
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 7
>       ATT: Read Request (0x0a) len 2
>         Handle: 0x003d Type: Broadcast Receive State (0x2bc8)
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 5
>       ATT: Read Response (0x0b) len 0
>         Value:
>         Handle: 0x003d Type: Broadcast Receive State (0x2bc8)
>           Empty characteristic
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 8
>       ATT: Write Request (0x12) len 3
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 00
>             Opcode: Remote Scan Stopped (0x00)
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 9
>       ATT: Error Response (0x01) len 4
>         Write Request (0x12)
>         Handle: 0x0040
>         Error: Reserved (0x80)
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 8
>       ATT: Write Request (0x12) len 3
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 01
>             Opcode: Remote Scan Started (0x01)
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 9
>       ATT: Error Response (0x01) len 4
>         Write Request (0x12)
>         Handle: 0x0040
>         Error: Reserved (0x80)
>
> > ACL Data RX: Handle 0 flags 0x01 dlen 5
>       ATT: Write Request (0x12) len 27
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 0200f2698be807c0013a650100ffff01000000000403020400
>             Opcode: Add Source (0x02)
>             Source_Address_Type: 0
>             Source_Address: C0:07:E8:8B:69:F2
>             Source_Adv_SID: 1
>             Broadcast_ID: 0x01653a
>             PA_Sync_State: Do not synchronize to PA
>             PA_Interval: 0xffff
>             Num_Subgroups: 1
>             Subgroup #0:
>               BIS_Sync State: 0x00000000
>               Metadata #0: len 0x03 type 0x02
>               Metadata: 0400
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 9
>       ATT: Error Response (0x01) len 4
>         Write Request (0x12)
>         Handle: 0x0040
>         Error: Reserved (0x80)
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 22
>       ATT: Write Request (0x12) len 17
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 030102780001000000000403040400
>             Opcode: Modify Source (0x03)
>             Source_ID: 1
>             PA_Sync_State: Synchronize to PA - PAST not available
>             PA_Interval: 0x0078
>             Num_Subgroups: 1
>             Subgroup #0:
>               BIS_Sync State: 0x00000000
>               Metadata #0: len 0x03 type 0x04
>               Metadata: 0400
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 9
>       ATT: Error Response (0x01) len 4
>         Write Request (0x12)
>         Handle: 0x0040
>         Error: Reserved (0x80)
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 25
>       ATT: Write Request (0x12) len 20
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 0401b803eac6afbb65a25a41f15305680201
>             Opcode: Set Broadcast_Code (0x04)
>             Source_ID: 1
>             Broadcast_Code: b803eac6afbb65a25a41f15305680201
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 5
>       ATT: Write Response (0x13) len 0
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 33
>       ATT: Handle Multiple Value Notification (0x23) len 28
>         Length: 0x0018
>         Handle: 0x003a Type: Broadcast Receive State (0x2bc8)
>           Data: 0100f2698be807c0013a6501020201000000000403020400
>           Source_ID: 1
>           Source_Address_Type: 0
>           Source_Address: C0:07:E8:8B:69:F2
>           Source_Adv_SID: 1
>           Broadcast_ID: 0x01653a
>           PA_Sync_State: Synchronized to PA
>           BIG_Encryption: Decrypting
>           Num_Subgroups: 1
>           Subgroup #0:
>             BIS_Sync State: 0x00000000
>             Metadata #0: len 0x03 type 0x02
>             Metadata: 0400
>
> > ACL Data RX: Handle 0 flags 0x02 dlen 9
>       ATT: Write Request (0x12) len 4
>         Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7)
>           Data: 0501
>             Opcode: Remove Source (0x05)
>             Source_ID: 1
>
> < ACL Data TX: Handle 0 flags 0x00 dlen 9
>       ATT: Error Response (0x01) len 4
>         Write Request (0x12)
>         Handle: 0x0040
>         Error: Reserved (0x80)
>
> ---
>  monitor/att.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 461 insertions(+)
>
> diff --git a/monitor/att.c b/monitor/att.c
> index ff77620c5..4baf029ed 100644
> --- a/monitor/att.c
> +++ b/monitor/att.c
> @@ -5,6 +5,7 @@
>   *
>   *  Copyright (C) 2011-2014  Intel Corporation
>   *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
> + *  Copyright 2023 NXP
>   *
>   *
>   */
> @@ -2514,6 +2515,462 @@ static void content_control_id_read(const struct l2cap_frame *frame)
>         print_content_control_id(frame);
>  }
>
> +static const struct pa_sync_state_decoder {
> +       uint8_t code;
> +       char *value;
> +} pa_sync_state_decoders[] = {
> +       { 0x00, "Not synchronized to PA" },
> +       { 0x01, "SyncInfo Request" },
> +       { 0x02, "Synchronized to PA" },
> +       { 0x03, "Failed to synchronize to PA" },
> +       { 0x04, "No PAST" },
> +};
> +
> +static const struct cp_pa_sync_state_decoder {
> +       uint8_t code;
> +       char *value;
> +} cp_pa_sync_state_decoders[] = {
> +       { 0x00, "Do not synchronize to PA" },
> +       { 0x01, "Synchronize to PA - PAST available" },
> +       { 0x02, "Synchronize to PA - PAST not available" },
> +};
> +
> +static const struct big_enc_decoder {
> +       uint8_t code;
> +       char *value;
> +} big_enc_decoders[] = {
> +       { 0x00, "Not encrypted" },
> +       { 0x01, "Broadcast_Code required" },
> +       { 0x02, "Decrypting" },
> +       { 0x03, "Bad_Code (incorrect encryption key)" },
> +};
> +
> +static bool print_subgroup_lv(const struct l2cap_frame *frame,
> +               const char *label, struct packet_ltv_decoder *decoder,
> +               size_t decoder_len)
> +{
> +       struct bt_hci_lv_data *lv;
> +
> +       lv = l2cap_frame_pull((void *)frame, frame, sizeof(*lv));
> +       if (!lv) {
> +               print_text(COLOR_ERROR, "%s: invalid size", label);
> +               return false;
> +       }
> +
> +       if (!l2cap_frame_pull((void *)frame, frame, lv->len)) {
> +               print_text(COLOR_ERROR, "%s: invalid size", label);
> +               return false;
> +       }
> +
> +       packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len);
> +
> +       return true;
> +}
> +
> +static bool print_subgroup_metadata(const char *label,
> +                               const struct l2cap_frame *frame)
> +{
> +       return print_subgroup_lv(frame, label, NULL, 0);
> +}
> +
> +static void print_bcast_recv_state(const struct l2cap_frame *frame)
> +{
> +       uint8_t i;
> +       uint8_t id;
> +       uint8_t addr_type;
> +       uint8_t *addr;
> +       uint8_t sid;
> +       uint32_t bid;
> +       uint8_t pa_sync_state;
> +       uint8_t enc;
> +       uint8_t *bad_code;
> +       uint8_t num_subgroups = 0;
> +       uint32_t bis_sync_state;
> +
> +       if (frame->size == 0) {
> +               print_field("  Empty characteristic");
> +               goto done;
> +       }
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &id)) {
> +               print_text(COLOR_ERROR, "Source_ID: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Source_ID: %u", id);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &addr_type)) {
> +               print_text(COLOR_ERROR, "Source_Address_Type: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Source_Address_Type: %u", addr_type);
> +
> +       addr = l2cap_frame_pull((void *)frame, frame, sizeof(bdaddr_t));
> +       if (!addr) {
> +               print_text(COLOR_ERROR, "Source_Address: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Source_Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
> +                                       addr[5], addr[4],
> +                                       addr[3], addr[2],
> +                                       addr[1], addr[0]);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &sid)) {
> +               print_text(COLOR_ERROR, "Source_Adv_SID: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Source_Adv_SID: %u", sid);
> +
> +       if (!l2cap_frame_get_le24((void *)frame, &bid)) {
> +               print_text(COLOR_ERROR, "Broadcast_ID: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Broadcast_ID: 0x%06x", bid);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
> +               print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
> +               goto done;
> +       }
> +
> +       for (i = 0; i < ARRAY_SIZE(pa_sync_state_decoders); i++) {
> +               const struct pa_sync_state_decoder *decoder;
> +
> +               decoder = &pa_sync_state_decoders[i];
> +
> +               if (decoder->code == pa_sync_state) {
> +                       print_field("  PA_Sync_State: %s", decoder->value);
> +                       break;
> +               }
> +       }
> +
> +       if (i == ARRAY_SIZE(pa_sync_state_decoders))
> +               print_field("  PA_Sync_State: %s", "Invalid value");
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &enc)) {
> +               print_text(COLOR_ERROR, "BIG_Encryption: invalid size");
> +               goto done;
> +       }
> +
> +       for (i = 0; i < ARRAY_SIZE(big_enc_decoders); i++) {
> +               const struct big_enc_decoder *decoder;
> +
> +               decoder = &big_enc_decoders[i];
> +
> +               if (decoder->code == enc) {
> +                       print_field("  BIG_Encryption: %s", decoder->value);
> +                       break;
> +               }
> +       }
> +
> +       if (i == ARRAY_SIZE(big_enc_decoders))
> +               print_field("  BIG_Encryption: %s", "Invalid value");
> +
> +       if (enc == 0x03) {
> +               bad_code = l2cap_frame_pull((void *)frame, frame, 16);
> +               if (!bad_code) {
> +                       print_text(COLOR_ERROR, "Bad_Code: invalid size");
> +                       goto done;
> +               }
> +
> +               print_hex_field("  Bad_Code", bad_code, 16);
> +       }
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
> +               print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
> +               goto done;
> +       }
> +
> +       print_field("  Num_Subgroups: %u", num_subgroups);
> +
> +       for (i = 0; i < num_subgroups; i++) {
> +               print_field("  Subgroup #%u:", i);
> +
> +               if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
> +                       print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
> +                       goto done;
> +               }
> +
> +               print_field("    BIS_Sync State: 0x%8.8x", bis_sync_state);
> +
> +               if (!print_subgroup_metadata("    Metadata", frame))
> +                       goto done;
> +       }
> +
> +done:
> +       if (frame->size)
> +               print_hex_field("  Data", frame->data, frame->size);
> +}
> +
> +static void bcast_recv_state_read(const struct l2cap_frame *frame)
> +{
> +       print_bcast_recv_state(frame);
> +}
> +
> +static void bcast_recv_state_notify(const struct l2cap_frame *frame)
> +{
> +       print_bcast_recv_state(frame);
> +}
> +
> +#define BCAST_AUDIO_SCAN_CP_CMD(_op, _desc, _func) \
> +[_op] = { \
> +       .desc = _desc, \
> +       .func = _func, \
> +}
> +
> +static void bcast_audio_scan_cp_add_src_cmd(const struct l2cap_frame *frame)
> +{
> +       uint8_t i;
> +       uint8_t addr_type;
> +       uint8_t *addr;
> +       uint8_t sid;
> +       uint32_t bid;
> +       uint8_t pa_sync_state;
> +       uint16_t pa_interval;
> +       uint8_t num_subgroups = 0;
> +       uint32_t bis_sync_state;
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &addr_type)) {
> +               print_text(COLOR_ERROR, "Source_Address_Type: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_Address_Type: %u", addr_type);
> +
> +       addr = l2cap_frame_pull((void *)frame, frame, sizeof(bdaddr_t));
> +       if (!addr) {
> +               print_text(COLOR_ERROR, "Source_Address: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
> +                                       addr[5], addr[4],
> +                                       addr[3], addr[2],
> +                                       addr[1], addr[0]);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &sid)) {
> +               print_text(COLOR_ERROR, "Source_Adv_SID: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_Adv_SID: %u", sid);
> +
> +       if (!l2cap_frame_get_le24((void *)frame, &bid)) {
> +               print_text(COLOR_ERROR, "Broadcast_ID: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Broadcast_ID: 0x%06x", bid);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
> +               print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
> +               return;
> +       }
> +
> +       for (i = 0; i < ARRAY_SIZE(cp_pa_sync_state_decoders); i++) {
> +               const struct cp_pa_sync_state_decoder *decoder;
> +
> +               decoder = &cp_pa_sync_state_decoders[i];
> +
> +               if (decoder->code == pa_sync_state) {
> +                       print_field("    PA_Sync_State: %s", decoder->value);
> +                       break;
> +               }
> +       }
> +
> +       if (i == ARRAY_SIZE(cp_pa_sync_state_decoders))
> +               print_field("    PA_Sync_State: %s", "Invalid value");
> +
> +       if (!l2cap_frame_get_le16((void *)frame, &pa_interval)) {
> +               print_text(COLOR_ERROR, "PA_Interval: invalid size");
> +               return;
> +       }
> +
> +       print_field("    PA_Interval: 0x%04x", pa_interval);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
> +               print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Num_Subgroups: %u", num_subgroups);
> +
> +       for (i = 0; i < num_subgroups; i++) {
> +               print_field("    Subgroup #%u:", i);
> +
> +               if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
> +                       print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
> +                       return;
> +               }
> +
> +               print_field("      BIS_Sync State: 0x%8.8x", bis_sync_state);
> +
> +               if (!print_subgroup_metadata("      Metadata", frame))
> +                       return;
> +       }
> +}
> +
> +static void bcast_audio_scan_cp_mod_src_cmd(const struct l2cap_frame *frame)
> +{
> +       uint8_t i;
> +       uint8_t id;
> +       uint8_t pa_sync_state;
> +       uint16_t pa_interval;
> +       uint8_t num_subgroups = 0;
> +       uint32_t bis_sync_state;
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &id)) {
> +               print_text(COLOR_ERROR, "Source_ID: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_ID: %u", id);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &pa_sync_state)) {
> +               print_text(COLOR_ERROR, "PA_Sync_State: invalid size");
> +               return;
> +       }
> +
> +       for (i = 0; i < ARRAY_SIZE(cp_pa_sync_state_decoders); i++) {
> +               const struct cp_pa_sync_state_decoder *decoder;
> +
> +               decoder = &cp_pa_sync_state_decoders[i];
> +
> +               if (decoder->code == pa_sync_state) {
> +                       print_field("    PA_Sync_State: %s", decoder->value);
> +                       break;
> +               }
> +       }
> +
> +       if (i == ARRAY_SIZE(cp_pa_sync_state_decoders))
> +               print_field("    PA_Sync_State: %s", "Invalid value");
> +
> +       if (!l2cap_frame_get_le16((void *)frame, &pa_interval)) {
> +               print_text(COLOR_ERROR, "PA_Interval: invalid size");
> +               return;
> +       }
> +
> +       print_field("    PA_Interval: 0x%04x", pa_interval);
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &num_subgroups)) {
> +               print_text(COLOR_ERROR, "Num_Subgroups: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Num_Subgroups: %u", num_subgroups);
> +
> +       for (i = 0; i < num_subgroups; i++) {
> +               print_field("    Subgroup #%u:", i);
> +
> +               if (!l2cap_frame_get_le32((void *)frame, &bis_sync_state)) {
> +                       print_text(COLOR_ERROR, "BIS_Sync State: invalid size");
> +                       return;
> +               }
> +
> +               print_field("      BIS_Sync State: 0x%8.8x", bis_sync_state);
> +
> +               if (!print_subgroup_metadata("      Metadata", frame))
> +                       return;
> +       }
> +}
> +
> +static void bcast_audio_scan_cp_set_bcode_cmd(const struct l2cap_frame *frame)
> +{
> +       uint8_t id;
> +       uint8_t *bcast_code;
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &id)) {
> +               print_text(COLOR_ERROR, "Source_ID: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_ID: %u", id);
> +
> +       bcast_code = l2cap_frame_pull((void *)frame, frame, 16);
> +       if (!bcast_code) {
> +               print_text(COLOR_ERROR, "Broadcast_Code: invalid size");
> +               return;
> +       }
> +
> +       print_hex_field("    Broadcast_Code", bcast_code, 16);
> +
> +}
> +
> +static void bcast_audio_scan_cp_remove_src_cmd(const struct l2cap_frame *frame)
> +{
> +       uint8_t id;
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &id)) {
> +               print_text(COLOR_ERROR, "Source_ID: invalid size");
> +               return;
> +       }
> +
> +       print_field("    Source_ID: %u", id);
> +}
> +
> +struct bcast_audio_scan_cp_cmd {
> +       const char *desc;
> +       void (*func)(const struct l2cap_frame *frame);
> +} bcast_audio_scan_cp_cmd_table[] = {
> +       /* Opcode = 0x00 (Remote Scan Stopped) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x00, "Remote Scan Stopped", NULL),
> +       /* Opcode = 0x01 (Remote Scan Started) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x01, "Remote Scan Started", NULL),
> +       /* Opcode = 0x02 (Add Source) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x02, "Add Source",
> +                                       bcast_audio_scan_cp_add_src_cmd),
> +       /* Opcode = 0x03 (Modify Source) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x03, "Modify Source",
> +                                       bcast_audio_scan_cp_mod_src_cmd),
> +       /* Opcode = 0x04 (Set Broadcast_Code) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x04, "Set Broadcast_Code",
> +                                       bcast_audio_scan_cp_set_bcode_cmd),
> +       /* Opcode = 0x05 (Remove Source) */
> +       BCAST_AUDIO_SCAN_CP_CMD(0x05, "Remove Source",
> +                                       bcast_audio_scan_cp_remove_src_cmd),
> +};
> +
> +static struct bcast_audio_scan_cp_cmd *bcast_audio_scan_cp_get_cmd(uint8_t op)
> +{
> +       if (op > ARRAY_SIZE(bcast_audio_scan_cp_cmd_table))
> +               return NULL;
> +
> +       return &bcast_audio_scan_cp_cmd_table[op];
> +}
> +
> +static void print_bcast_audio_scan_cp_cmd(const struct l2cap_frame *frame)
> +{
> +       uint8_t op;
> +       struct bcast_audio_scan_cp_cmd *cmd;
> +
> +       if (!l2cap_frame_get_u8((void *)frame, &op)) {
> +               print_text(COLOR_ERROR, "Opcode: invalid size");
> +               goto done;
> +       }
> +
> +       cmd = bcast_audio_scan_cp_get_cmd(op);
> +       if (!cmd) {
> +               print_field("    Opcode: Reserved (0x%2.2x)", op);
> +               goto done;
> +       }
> +
> +       print_field("    Opcode: %s (0x%2.2x)", cmd->desc, op);
> +       if (cmd->func)
> +               cmd->func(frame);
> +
> +done:
> +       if (frame->size)
> +               print_hex_field("  Data", frame->data, frame->size);
> +}
> +
> +static void bcast_audio_scan_cp_write(const struct l2cap_frame *frame)
> +{
> +       print_bcast_audio_scan_cp_cmd(frame);
> +}
> +
>  #define GATT_HANDLER(_uuid, _read, _write, _notify) \
>  { \
>         .uuid = { \
> @@ -2568,6 +3025,10 @@ struct gatt_handler {
>         GATT_HANDLER(0x2ba5, media_cp_op_supported_read, NULL,
>                                         media_cp_op_supported_notify),
>         GATT_HANDLER(0x2bba, content_control_id_read, NULL, NULL),
> +
> +       GATT_HANDLER(0x2bc7, NULL, bcast_audio_scan_cp_write, NULL),
> +       GATT_HANDLER(0x2bc8, bcast_recv_state_read, NULL,
> +                                       bcast_recv_state_notify),
>  };
>
>  static struct gatt_handler *get_handler_uuid(const bt_uuid_t *uuid)
> --
> 2.34.1
>


-- 
Luiz Augusto von Dentz

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

* Re: [PATCH BlueZ 1/1] monitor/att: Add decoding support for BASS
  2023-04-04 18:13   ` [PATCH BlueZ 1/1] " Luiz Augusto von Dentz
@ 2023-04-05 11:46     ` Iulia Tanasescu
  0 siblings, 0 replies; 6+ messages in thread
From: Iulia Tanasescu @ 2023-04-05 11:46 UTC (permalink / raw)
  To: luiz.dentz; +Cc: iulia.tanasescu, linux-bluetooth

Hi Luiz,

Thank you, I resubmitted the patch.

Regards,
Iulia


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

* RE: monitor/att: Add decoding support for BASS
  2023-04-05 10:54 [PATCH BlueZ v2 " Iulia Tanasescu
@ 2023-04-05 12:21 ` bluez.test.bot
  0 siblings, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2023-04-05 12:21 UTC (permalink / raw)
  To: linux-bluetooth, iulia.tanasescu

[-- Attachment #1: Type: text/plain, Size: 1711 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=737147

---Test result---

Test Summary:
CheckPatch                    PASS      0.83 seconds
GitLint                       FAIL      0.60 seconds
BuildEll                      PASS      32.86 seconds
BluezMake                     PASS      986.54 seconds
MakeCheck                     PASS      12.82 seconds
MakeDistcheck                 PASS      177.75 seconds
CheckValgrind                 PASS      292.17 seconds
CheckSmatch                   WARNING   388.45 seconds
bluezmakeextell               PASS      115.23 seconds
IncrementalBuild              PASS      809.55 seconds
ScanBuild                     PASS      1209.26 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,1/1] monitor/att: Add decoding support for BASS

WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
33: B2 Line has trailing whitespace: "        Value: "
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
monitor/att.c: note: in included file:monitor/display.h:82:26: warning: Variable length array is used.


---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2023-04-05 12:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-04 14:30 [PATCH BlueZ 0/1] monitor/att: Add decoding support for BASS Iulia Tanasescu
2023-04-04 14:30 ` [PATCH BlueZ 1/1] " Iulia Tanasescu
2023-04-04 15:31   ` bluez.test.bot
2023-04-04 18:13   ` [PATCH BlueZ 1/1] " Luiz Augusto von Dentz
2023-04-05 11:46     ` Iulia Tanasescu
2023-04-05 10:54 [PATCH BlueZ v2 " Iulia Tanasescu
2023-04-05 12:21 ` bluez.test.bot

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.