monitor/att: Decode attribute type
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 18 May 2022 00:45:22 +0000 (17:45 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 15 May 2023 09:25:54 +0000 (14:55 +0530)
This attempt to decode the attribute type if its gatt_db can be loaded:

< ACL Data TX: Handle 3585 flags 0x00 dlen 9
      ATT: Write Request (0x12) len 4
        Handle: 0x000b Type: Client Characteristic Configuration (0x2902)
          Data: 0200

Change-Id: I7c35c3e872237c82763a65b5f22a450684eb8cd7
Signed-off-by: Manika Shrivastava <manika.sh@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
Makefile.tools
monitor/att.c
monitor/packet.c

index d780780..1eb2eb2 100755 (executable)
@@ -46,10 +46,13 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
                                monitor/msft.h monitor/msft.c \
                                monitor/jlink.h monitor/jlink.c \
                                monitor/tty.h monitor/emulator.h \
-                               monitor/att.h monitor/att.c
+                               monitor/att.h monitor/att.c \
+                               src/log.h src/bluez-log.c src/log.c \
+                               src/textfile.h src/textfile.c \
+                               src/settings.h src/settings.c
 monitor_btmon_LDADD = lib/libbluetooth-internal.la \
                                src/libshared-mainloop.la \
-                               $(GLIB_LIBS) $(UDEV_LIBS) -ldl
+                               $(GLIB_LIBS) $(UDEV_LIBS) -ldl @LIBXML_LIBS@
 if MANPAGES
 man_MANS += monitor/btmon.1
 endif
index fd3b4e7..1c1e8d2 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <linux/limits.h>
 
 #include "lib/bluetooth.h"
 #include "lib/uuid.h"
+#include "lib/hci.h"
+#include "lib/hci_lib.h"
 
 #include "src/shared/util.h"
+#include "src/shared/queue.h"
+#include "src/shared/att.h"
+#include "src/shared/gatt-db.h"
+#include "src/textfile.h"
+#include "src/settings.h"
 #include "bt.h"
 #include "packet.h"
 #include "display.h"
@@ -315,11 +325,123 @@ static void att_read_type_rsp(const struct l2cap_frame *frame)
                                        frame->data + 1, frame->size - 1);
 }
 
+struct att_conn_data {
+       struct gatt_db *ldb;
+       struct gatt_db *rdb;
+};
+
+static void att_conn_data_free(void *data)
+{
+       struct att_conn_data *att_data = data;
+
+       gatt_db_unref(att_data->rdb);
+       gatt_db_unref(att_data->ldb);
+       free(att_data);
+}
+
+static void load_gatt_db(struct packet_conn_data *conn)
+{
+       struct att_conn_data *data;
+       char filename[PATH_MAX];
+       bdaddr_t src;
+       char local[18];
+       char peer[18];
+
+       if (hci_devba(conn->index, &src) < 0)
+               return;
+
+       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(&src, local);
+
+       create_filename(filename, PATH_MAX, "/%s/attributes", local);
+
+       btd_settings_gatt_db_load(data->ldb, filename);
+
+       ba2str((bdaddr_t *)conn->dst, peer);
+
+       create_filename(filename, PATH_MAX, "/%s/cache/%s", local, peer);
+
+       btd_settings_gatt_db_load(data->rdb, filename);
+}
+
+static struct gatt_db_attribute *get_attribute(const struct l2cap_frame *frame,
+                                               uint16_t handle, bool rsp)
+{
+       struct packet_conn_data *conn;
+       struct att_conn_data *data;
+       struct gatt_db *db;
+
+       conn = packet_get_conn_data(frame->handle);
+       if (!conn)
+               return NULL;
+
+       data = conn->data;
+       /* Try loading local and remote gatt_db if not loaded yet */
+       if (!data) {
+               load_gatt_db(conn);
+               data = conn->data;
+               if (!data)
+                       return NULL;
+       }
+
+       if (frame->in) {
+               if (rsp)
+                       db = data->rdb;
+               else
+                       db = data->ldb;
+       } else {
+               if (rsp)
+                       db = data->ldb;
+               else
+                       db = data->rdb;
+       }
+
+       return gatt_db_get_attribute(db, handle);
+}
+
+static void print_handle(const struct l2cap_frame *frame, uint16_t handle,
+                                                               bool rsp)
+{
+       struct gatt_db_attribute *attr;
+       const bt_uuid_t *uuid;
+       char label[21];
+
+       attr = get_attribute(frame, handle, rsp);
+       if (!attr)
+               goto done;
+
+       uuid = gatt_db_attribute_get_type(attr);
+       if (!uuid)
+               goto done;
+
+       switch (uuid->type) {
+       case BT_UUID16:
+               sprintf(label, "Handle: 0x%4.4x Type", handle);
+               print_uuid(label, &cpu_to_le16(uuid->value.u16), 2);
+               return;
+       case BT_UUID128:
+               sprintf(label, "Handle: 0x%4.4x Type", handle);
+               print_uuid(label, &uuid->value.u128, 16);
+               return;
+       case BT_UUID_UNSPEC:
+       case BT_UUID32:
+               break;
+       }
+
+done:
+       print_field("Handle: 0x%4.4x", handle);
+}
+
 static void att_read_req(const struct l2cap_frame *frame)
 {
        const struct bt_l2cap_att_read_req *pdu = frame->data;
 
-       print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle));
+       print_handle(frame, le16_to_cpu(pdu->handle), false);
 }
 
 static void att_read_rsp(const struct l2cap_frame *frame)
@@ -329,7 +451,7 @@ static void att_read_rsp(const struct l2cap_frame *frame)
 
 static void att_read_blob_req(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), false);
        print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
 }
 
@@ -345,8 +467,7 @@ static void att_read_multiple_req(const struct l2cap_frame *frame)
        count = frame->size / 2;
 
        for (i = 0; i < count; i++)
-               print_field("Handle: 0x%4.4x",
-                                       get_le16(frame->data + (i * 2)));
+               print_handle(frame, get_le16(frame->data + (i * 2)), false);
 }
 
 static void att_read_group_type_req(const struct l2cap_frame *frame)
@@ -389,7 +510,7 @@ static void att_read_group_type_rsp(const struct l2cap_frame *frame)
 
 static void att_write_req(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), false);
        print_hex_field("  Data", frame->data + 2, frame->size - 2);
 }
 
@@ -399,14 +520,14 @@ static void att_write_rsp(const struct l2cap_frame *frame)
 
 static void att_prepare_write_req(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), false);
        print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
        print_hex_field("  Data", frame->data + 4, frame->size - 4);
 }
 
 static void att_prepare_write_rsp(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), true);
        print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
        print_hex_field("  Data", frame->data + 4, frame->size - 4);
 }
@@ -435,7 +556,7 @@ static void att_handle_value_notify(const struct l2cap_frame *frame)
 {
        const struct bt_l2cap_att_handle_value_notify *pdu = frame->data;
 
-       print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle));
+       print_handle(frame, le16_to_cpu(pdu->handle), true);
        print_hex_field("  Data", frame->data + 2, frame->size - 2);
 }
 
@@ -443,7 +564,7 @@ static void att_handle_value_ind(const struct l2cap_frame *frame)
 {
        const struct bt_l2cap_att_handle_value_ind *pdu = frame->data;
 
-       print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle));
+       print_handle(frame, le16_to_cpu(pdu->handle), true);
        print_hex_field("  Data", frame->data + 2, frame->size - 2);
 }
 
@@ -462,7 +583,7 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame)
                if (!l2cap_frame_get_le16(f, &handle))
                        return;
 
-               print_field("Handle: 0x%4.4x", handle);
+               print_handle(frame, get_le16(frame->data), true);
 
                if (!l2cap_frame_get_le16(f, &len))
                        return;
@@ -483,13 +604,13 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame)
 
 static void att_write_command(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), false);
        print_hex_field("  Data", frame->data + 2, frame->size - 2);
 }
 
 static void att_signed_write_command(const struct l2cap_frame *frame)
 {
-       print_field("Handle: 0x%4.4x", get_le16(frame->data));
+       print_handle(frame, get_le16(frame->data), false);
        print_hex_field("  Data", frame->data + 2, frame->size - 2 - 12);
        print_hex_field("  Signature", frame->data + frame->size - 12, 12);
 }
index 11198cf..4fc659b 100755 (executable)
@@ -764,7 +764,7 @@ static void print_handle_native(uint16_t handle)
        }
 
        sprintf(label, "Handle: %d Address", handle);
-       print_addr("  Address", conn->dst, conn->dst_type);
+       print_addr(label, conn->dst, conn->dst_type);
 }
 
 static void print_handle(uint16_t handle)