Bluetooth/GUI: ATT: Add Server Attribute Table
authorMichal Labedzki <michal.labedzki@tieto.com>
Thu, 22 Jan 2015 11:27:23 +0000 (12:27 +0100)
committerMichal Labedzki <michal.labedzki@tieto.com>
Sat, 7 Feb 2015 16:35:39 +0000 (16:35 +0000)
It is a GUI+QT feature that introduce Bluetooth menu and
"ATT Server Attributes" that present all handle+UUID pairs
as table. User may copy cell value, row, selected rows or whole
table within header. On activate user will go to packet that
introduce UUID for specified handle.

Change-Id: If17e53aff5feb89ededc740a595ba5882b90be5e
Reviewed-on: https://code.wireshark.org/review/6911
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
19 files changed:
debian/libwireshark0.symbols
epan/dissectors/Makefile.common
epan/dissectors/packet-bluetooth.c
epan/dissectors/packet-bluetooth.h
epan/dissectors/packet-btatt.c
epan/dissectors/packet-btatt.h [new file with mode: 0644]
epan/dissectors/packet-bthci_cmd.c
epan/dissectors/packet-btsdp.c
epan/epan.h
ui/qt/CMakeLists.txt
ui/qt/Makefile.am
ui/qt/Makefile.common
ui/qt/Wireshark.pro
ui/qt/bluetooth_att_server_attributes_dialog.cpp [new file with mode: 0644]
ui/qt/bluetooth_att_server_attributes_dialog.h [new file with mode: 0644]
ui/qt/bluetooth_att_server_attributes_dialog.ui [new file with mode: 0644]
ui/qt/main_window.h
ui/qt/main_window.ui
ui/qt/main_window_slots.cpp

index fd1c5f466a9f16d3e50e4904e98ff5313c2966b7..f9e56c1fa5f952055d130e3ade872dd8032d44b6 100644 (file)
@@ -69,6 +69,9 @@ libwireshark.so.0 libwireshark0 #MINVER#
  ber_decode_as@Base 1.9.1
  ber_decode_as_foreach@Base 1.9.1
  ber_set_filename@Base 1.9.1
+ bluetooth_uuid_vals@Base 1.99.2
+ bluetooth_uuid_vals_ext@Base 1.99.2
+ bluetooth_uuid_custom@Base 1.99.2
  bssgp_cause_vals_ext@Base 1.9.1
  build_column_format_array@Base 1.9.1
  build_follow_conv_filter@Base 1.12.0~rc1
@@ -452,6 +455,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
  epan_dissect_run_with_taps@Base 1.9.1
  epan_free@Base 1.12.0~rc1
  epan_get_compiled_version_info@Base 1.9.1
+ epan_get_interface_name@Base 1.99.2
  epan_get_runtime_version_info@Base 1.9.1
  epan_get_user_comment@Base 1.99.2
  epan_get_version@Base 1.9.1
index b8e7ea01a7a532c7dc64acf99f423bcf4c1b794e..aa11d3e807b456fa810882e1f430441fd4b220f8 100644 (file)
@@ -1391,6 +1391,7 @@ DISSECTOR_INCLUDES =      \
        packet-bpq.h    \
        packet-bssap.h  \
        packet-bssgp.h  \
+       packet-btatt.h          \
        packet-btavctp.h        \
        packet-btavdtp.h        \
        packet-btavrcp.h        \
index c170d2043c40282f9e07326e3d0f240e6f3d52ed..6746c0d3a136b7b88e1d6d4b2175818048c20a57 100644 (file)
@@ -558,7 +558,7 @@ const value_string bluetooth_uuid_vals[] = {
 };
 value_string_ext bluetooth_uuid_vals_ext = VALUE_STRING_EXT_INIT(bluetooth_uuid_vals);
 
-const custom_uuid_t custom_uuid[] = {
+const bluetooth_uuid_custom_t bluetooth_uuid_custom[] = {
     { {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02}, 16, "SyncML Server" },
     { {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02}, 16, "SyncML Client" },
     { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, NULL},
@@ -1211,14 +1211,14 @@ print_uuid(uuid_t *uuid)
         guint i_uuid;
 
         i_uuid = 0;
-        while (custom_uuid[i_uuid].name) {
-            if (custom_uuid[i_uuid].size != uuid->size) {
+        while (bluetooth_uuid_custom[i_uuid].name) {
+            if (bluetooth_uuid_custom[i_uuid].size != uuid->size) {
                 i_uuid += 1;
                 continue;
             }
 
-            if (memcmp(uuid->data, custom_uuid[i_uuid].uuid, uuid->size) == 0) {
-                return wmem_strdup(wmem_packet_scope(), custom_uuid[i_uuid].name);
+            if (memcmp(uuid->data, bluetooth_uuid_custom[i_uuid].uuid, uuid->size) == 0) {
+                return wmem_strdup(wmem_packet_scope(), bluetooth_uuid_custom[i_uuid].name);
             }
 
             i_uuid += 1;
index a02a535a3f62499bbadc360fbd850314786561f6..18e69e5493b1b476a21388576b24ddb3ba85ade7 100644 (file)
 #ifndef __PACKET_BLUETOOTH_H__
 #define __PACKET_BLUETOOTH_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 #include <epan/wmem/wmem.h>
 
 #include "packet-usb.h"
@@ -203,16 +207,16 @@ typedef struct _uuid_t {
     guint8   data[16];
 } uuid_t;
 
-typedef struct _custom_uuid_t {
+typedef struct _bluetooth_uuid_custom {
     const guint8  uuid[16];
     const guint8  size;
     const gchar  *name;
-} custom_uuid_t;
+} bluetooth_uuid_custom_t;
 
-extern const value_string   bluetooth_uuid_vals[];
-extern const custom_uuid_t  custom_uuid[];
+WS_DLL_PUBLIC const value_string   bluetooth_uuid_vals[];
+WS_DLL_PUBLIC const bluetooth_uuid_custom_t  bluetooth_uuid_custom[];
 
-extern value_string_ext  bluetooth_uuid_vals_ext;
+WS_DLL_PUBLIC value_string_ext  bluetooth_uuid_vals_ext;
 extern value_string_ext  bluetooth_company_id_vals_ext;
 extern guint32           max_disconnect_in_frame;
 
@@ -226,6 +230,10 @@ extern gchar  *print_numeric_uuid(uuid_t *uuid);
 extern void save_local_device_name_from_eir_ad(tvbuff_t *tvb, gint offset,
         packet_info *pinfo, guint8 size, bluetooth_data_t *bluetooth_data);
 
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
 #endif
 
 /*
index 6142716e3d8a5def9c512bdd452e1e50178e341a..b27be548feea7e747326271c12a7161b78c54cc3 100644 (file)
 #include <epan/expert.h>
 #include <epan/oui.h>
 #include <epan/decode_as.h>
+#include <epan/tap.h>
 
 #include "packet-bluetooth.h"
+#include "packet-btatt.h"
 #include "packet-btl2cap.h"
 #include "packet-btsdp.h"
 #include "packet-usb-hid.h"
@@ -305,6 +307,8 @@ static int hf_btatt_central_address_resolution = -1;
 static int hf_request_in_frame = -1;
 static int hf_response_in_frame = -1;
 
+static int btatt_tap_handles = -1;
+
 static const int *hfx_btatt_opcode[] = {
     &hf_btatt_opcode_authentication_signature,
     &hf_btatt_opcode_command,
@@ -1571,27 +1575,41 @@ static void
 save_handle(packet_info *pinfo, uuid_t uuid, guint32 handle,
         bluetooth_data_t *bluetooth_data)
 {
-    wmem_tree_key_t  key[5];
-    guint32          frame_number;
-    handle_data_t   *handle_data;
+    if (!handle && uuid.size != 2 && uuid.size != 16)
+        return;
 
-    frame_number = pinfo->fd->num;
+    if (have_tap_listener(btatt_tap_handles)) {
+        tap_handles_t  *tap_handles;
 
-    key[0].length = 1;
-    key[0].key    = &bluetooth_data->interface_id;
-    key[1].length = 1;
-    key[1].key    = &bluetooth_data->adapter_id;
-    key[2].length = 1;
-    key[2].key    = &handle;
-    key[3].length = 1;
-    key[3].key    = &frame_number;
-    key[4].length = 0;
-    key[4].key    = NULL;
+        tap_handles = wmem_new(wmem_packet_scope(), tap_handles_t);
+        tap_handles->handle = handle;
+        tap_handles->uuid = uuid;
+        tap_queue_packet(btatt_tap_handles, pinfo, tap_handles);
+    }
+
+    if (!pinfo->fd->flags.visited && bluetooth_data) {
+        wmem_tree_key_t  key[5];
+        guint32          frame_number;
+        handle_data_t   *handle_data;
+
+        frame_number = pinfo->fd->num;
+
+        key[0].length = 1;
+        key[0].key    = &bluetooth_data->interface_id;
+        key[1].length = 1;
+        key[1].key    = &bluetooth_data->adapter_id;
+        key[2].length = 1;
+        key[2].key    = &handle;
+        key[3].length = 1;
+        key[3].key    = &frame_number;
+        key[4].length = 0;
+        key[4].key    = NULL;
 
-    handle_data = wmem_new(wmem_file_scope(), handle_data_t);
-    handle_data->uuid = uuid;
+        handle_data = wmem_new(wmem_file_scope(), handle_data_t);
+        handle_data->uuid = uuid;
 
-    wmem_tree_insert32_array(handle_to_uuid, key, handle_data);
+        wmem_tree_insert32_array(handle_to_uuid, key, handle_data);
+    }
 }
 
 static uuid_t
@@ -1767,16 +1785,14 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info *
             proto_item_append_text(patron_item, ", UUID: %s", print_uuid(&sub_uuid));
             offset += 2;
 
-            if (!pinfo->fd->flags.visited && bluetooth_data && handle)
-                save_handle(pinfo, sub_uuid, handle, bluetooth_data);
+            save_handle(pinfo, sub_uuid, handle, bluetooth_data);
         } else if (tvb_reported_length_remaining(tvb, offset) == 16) {
             proto_tree_add_item(tree, hf_btatt_uuid128, tvb, offset, 16, ENC_NA);
             sub_uuid = get_uuid(tvb, offset, 16);
             proto_item_append_text(patron_item, ", UUID128: %s", print_uuid(&sub_uuid));
             offset += 16;
 
-            if (!pinfo->fd->flags.visited && bluetooth_data && handle)
-                save_handle(pinfo, sub_uuid, handle, bluetooth_data);
+            save_handle(pinfo, sub_uuid, handle, bluetooth_data);
         } else {
             proto_tree_add_item(tree, hf_btatt_value, tvb, offset, -1, ENC_NA);
             offset = tvb_captured_length(tvb);
@@ -1795,8 +1811,7 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info *
         proto_item_append_text(patron_item, ", Included Handle: 0x%04x, UUID: %s", sub_handle, print_uuid(&sub_uuid));
         offset += 2;
 
-        if (!pinfo->fd->flags.visited && bluetooth_data)
-            save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
+        save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
 
         break;
     case 0x2803: /* GATT Characteristic Declaration*/
@@ -1812,16 +1827,14 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info *
             proto_item_append_text(patron_item, ", Characteristic Handle: 0x%04x, UUID128: %s", tvb_get_guint16(tvb, offset - 2, ENC_LITTLE_ENDIAN), print_uuid(&sub_uuid));
             offset += 16;
 
-            if (!pinfo->fd->flags.visited && bluetooth_data)
-                save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
+            save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
         } else if (tvb_reported_length_remaining(tvb, offset) == 2) {
             proto_tree_add_item(tree, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
             sub_uuid = get_uuid(tvb, offset, 2);
             proto_item_append_text(patron_item, ", Characteristic Handle: 0x%04x, UUID: %s", sub_handle, print_uuid(&sub_uuid));
             offset += 2;
 
-            if (!pinfo->fd->flags.visited && bluetooth_data)
-                save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
+            save_handle(pinfo, sub_uuid, sub_handle, bluetooth_data);
         } else {
             proto_tree_add_item(tree, hf_btatt_value, tvb, offset, -1, ENC_NA);
             offset = tvb_captured_length(tvb);
@@ -3042,8 +3055,7 @@ dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
                             tvb_get_letohs(tvb, offset - 4),
                             print_uuid(&uuid));
 
-                    if (!pinfo->fd->flags.visited && bluetooth_data)
-                        save_handle(pinfo, uuid, handle, bluetooth_data);
+                    save_handle(pinfo, uuid, handle, bluetooth_data);
                 }
             }
             else if (format == 2) {
@@ -3062,8 +3074,7 @@ dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
                             tvb_get_letohs(tvb, offset - 4),
                             print_uuid(&uuid));
 
-                    if (!pinfo->fd->flags.visited && bluetooth_data)
-                        save_handle(pinfo, uuid, handle, bluetooth_data);
+                    save_handle(pinfo, uuid, handle, bluetooth_data);
                 }
             }
             else {
@@ -3116,7 +3127,7 @@ dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
             proto_tree_add_item(sub_tree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
             offset += 2;
 
-            if (!pinfo->fd->flags.visited && bluetooth_data && request_data)
+            if (request_data)
                 save_handle(pinfo, request_data->parameters.read_by_type.uuid,
                         tvb_get_guint16(tvb, offset - 4, ENC_LITTLE_ENDIAN),
                         bluetooth_data);
@@ -3189,8 +3200,7 @@ dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
                     sub_tree = proto_item_add_subtree(sub_item, ett_btatt_list);
 
                     if (request_data) {
-                        if (!pinfo->fd->flags.visited && bluetooth_data)
-                            save_handle(pinfo, request_data->parameters.read_by_type.uuid, tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN), bluetooth_data);
+                        save_handle(pinfo, request_data->parameters.read_by_type.uuid, tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN), bluetooth_data);
                     }
 
                     offset = dissect_handle(sub_tree, pinfo, hf_btatt_handle, tvb, offset, bluetooth_data, NULL);
@@ -4909,6 +4919,8 @@ proto_reg_handoff_btatt(void)
     dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_ATT, btatt_handle);
     dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_ATT, btatt_handle);
 
+    btatt_tap_handles = register_tap("btatt.handles");
+
     for (i_array = 0; bluetooth_uuid_vals[i_array].strptr != NULL; i_array += 1) {
         gchar *name;
         gchar *short_name;
diff --git a/epan/dissectors/packet-btatt.h b/epan/dissectors/packet-btatt.h
new file mode 100644 (file)
index 0000000..a8ccdf0
--- /dev/null
@@ -0,0 +1,46 @@
+/* packet-btaatt.h
+ * Headers for ATT
+ *
+ * Copyright 2015, Michal Labedzki for Tieto Corporation
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __PACKET_BTATT_H__
+#define __PACKET_BTATT_H__
+
+typedef struct _tap_handles_t {
+    guint32   handle;
+    uuid_t    uuid;
+} tap_handles_t;
+
+#endif
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
index e07c542f8dd369fa807e13dccd07f61b16a85abb..2da7f1ed94d22a86068780dfd211bc1e7328d7b7 100644 (file)
@@ -4792,14 +4792,14 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                     sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_custom_uuid, tvb, offset, 4, ENC_NA);
 
                     i_uuid = 0;
-                    while (custom_uuid[i_uuid].name) {
-                        if (custom_uuid[i_uuid].size != 4) {
+                    while (bluetooth_uuid_custom[i_uuid].name) {
+                        if (bluetooth_uuid_custom[i_uuid].size != 4) {
                             i_uuid += 1;
                             continue;
                         }
 
-                        if (tvb_memeql(tvb, offset, custom_uuid[i_uuid].uuid, 4) == 0) {
-                            proto_item_append_text(sub_item, " (%s)", custom_uuid[i_uuid].name);
+                        if (tvb_memeql(tvb, offset, bluetooth_uuid_custom[i_uuid].uuid, 4) == 0) {
+                            proto_item_append_text(sub_item, " (%s)", bluetooth_uuid_custom[i_uuid].name);
                             break;
                         }
 
@@ -4825,14 +4825,14 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                     sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_custom_uuid, tvb, offset, 16, ENC_NA);
 
                     i_uuid = 0;
-                    while (custom_uuid[i_uuid].name) {
-                        if (custom_uuid[i_uuid].size != 16) {
+                    while (bluetooth_uuid_custom[i_uuid].name) {
+                        if (bluetooth_uuid_custom[i_uuid].size != 16) {
                             i_uuid += 1;
                             continue;
                         }
 
-                        if (tvb_memeql(tvb, offset, custom_uuid[i_uuid].uuid, 16) == 0) {
-                            proto_item_append_text(sub_item, " (%s)", custom_uuid[i_uuid].name);
+                        if (tvb_memeql(tvb, offset, bluetooth_uuid_custom[i_uuid].uuid, 16) == 0) {
+                            proto_item_append_text(sub_item, " (%s)", bluetooth_uuid_custom[i_uuid].name);
                             break;
                         }
 
@@ -4965,14 +4965,14 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_custom_uuid, tvb, offset, 4, ENC_NA);
 
                 i_uuid = 0;
-                while (custom_uuid[i_uuid].name) {
-                    if (custom_uuid[i_uuid].size != 4) {
+                while (bluetooth_uuid_custom[i_uuid].name) {
+                    if (bluetooth_uuid_custom[i_uuid].size != 4) {
                         i_uuid += 1;
                         continue;
                     }
 
-                    if (tvb_memeql(tvb, offset, custom_uuid[i_uuid].uuid, 4) == 0) {
-                        proto_item_append_text(sub_item, " (%s)", custom_uuid[i_uuid].name);
+                    if (tvb_memeql(tvb, offset, bluetooth_uuid_custom[i_uuid].uuid, 4) == 0) {
+                        proto_item_append_text(sub_item, " (%s)", bluetooth_uuid_custom[i_uuid].name);
                         break;
                     }
 
@@ -4996,14 +4996,14 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_custom_uuid, tvb, offset, 16, ENC_NA);
 
                 i_uuid = 0;
-                while (custom_uuid[i_uuid].name) {
-                    if (custom_uuid[i_uuid].size != 16) {
+                while (bluetooth_uuid_custom[i_uuid].name) {
+                    if (bluetooth_uuid_custom[i_uuid].size != 16) {
                         i_uuid += 1;
                         continue;
                     }
 
-                    if (tvb_memeql(tvb, offset, custom_uuid[i_uuid].uuid, 16) == 0) {
-                        proto_item_append_text(sub_item, " (%s)", custom_uuid[i_uuid].name);
+                    if (tvb_memeql(tvb, offset, bluetooth_uuid_custom[i_uuid].uuid, 16) == 0) {
+                        proto_item_append_text(sub_item, " (%s)", bluetooth_uuid_custom[i_uuid].name);
                         break;
                     }
 
index 50282f986ae8fe345a9af73ec6a7ac52057ce731..9f712ebfc179a4d90186a3d4174922d662a7365b 100644 (file)
@@ -1301,14 +1301,14 @@ dissect_uuid(proto_tree *tree, tvbuff_t *tvb, gint offset, gint size, uuid_t *uu
         item = proto_tree_add_item(tree, hf_data_element_value_uuid, tvb, offset, size, ENC_NA);
 
         i_uuid = 0;
-        while (custom_uuid[i_uuid].name) {
-            if (custom_uuid[i_uuid].size != size) {
+        while (bluetooth_uuid_custom[i_uuid].name) {
+            if (bluetooth_uuid_custom[i_uuid].size != size) {
                 i_uuid += 1;
                 continue;
             }
 
-            if (tvb_memeql(tvb, offset, custom_uuid[i_uuid].uuid, 4) == 0) {
-                proto_item_append_text(item, " (%s)", custom_uuid[i_uuid].name);
+            if (tvb_memeql(tvb, offset, bluetooth_uuid_custom[i_uuid].uuid, 4) == 0) {
+                proto_item_append_text(item, " (%s)", bluetooth_uuid_custom[i_uuid].name);
                 break;
             }
 
index cf431e34fb78c7de6de9cabaa4656c7ac45fa78c..6c17964b65d8d864c561be35410b7e3c34d5b7ff 100644 (file)
@@ -134,7 +134,7 @@ WS_DLL_PUBLIC epan_t *epan_new(void);
 
 WS_DLL_PUBLIC const char *epan_get_user_comment(const epan_t *session, const frame_data *fd);
 
-const char *epan_get_interface_name(const epan_t *session, guint32 interface_id);
+WS_DLL_PUBLIC const char *epan_get_interface_name(const epan_t *session, guint32 interface_id);
 
 const nstime_t *epan_get_frame_ts(const epan_t *session, guint32 frame_num);
 
index abd33f61fa99f544ebb970ea3637fd048f5f6c89..22f4615179caf5ea4b3334c65c978bbcae7ebad6 100644 (file)
@@ -23,6 +23,7 @@
 # need to go here.
 set(WIRESHARK_QT_HEADERS
        about_dialog.h
+       bluetooth_att_server_attributes_dialog.h
        accordion_frame.h
        byte_view_tab.h
        byte_view_text.h
@@ -125,6 +126,7 @@ file(GLOB EXTRA_QT_HEADERS
 set(WIRESHARK_QT_SRC
        about_dialog.cpp
        accordion_frame.cpp
+       bluetooth_att_server_attributes_dialog.cpp
        byte_view_tab.cpp
        byte_view_text.cpp
        capture_file.cpp
@@ -234,6 +236,7 @@ set(DIRTY_FILES
 
 set(WIRESHARK_QT_UI
        about_dialog.ui
+       bluetooth_att_server_attributes_dialog.ui
        capture_file_properties_dialog.ui
        capture_interfaces_dialog.ui
        capture_preferences_frame.ui
index 725cf9fbbd9659478ee9b96dee4db5a2b43d6238..dca950b8c81d302295254e755a5894008a8ba5af 100644 (file)
@@ -224,6 +224,8 @@ uat_dialog.cpp uat_dialog.h: ui_uat_dialog.h
 
 voip_calls_dialog.cpp voip_calls_dialog.h: ui_voip_calls_dialog.h
 
+bluetooth_att_server_attributes_dialog.cpp bluetooth_att_server_attributes_dialog.h: ui_bluetooth_att_server_attributes_dialog.h
+
 doxygen:
 if HAVE_DOXYGEN
        $(DOXYGEN) doxygen.cfg
index 8106e8882155e02cccf214fe2edf033fe83af30d..f2b5d16bdba55151f4dd6fcfa49f5a8ac42e83a5 100644 (file)
@@ -30,6 +30,7 @@ GENERATED_HEADER_FILES =
 # Generated header files that we don't want in the distribution.
 NODIST_GENERATED_HEADER_FILES =        \
        ui_about_dialog.h       \
+       ui_bluetooth_att_server_attributes_dialog.h     \
        ui_capture_file_properties_dialog.h     \
        ui_capture_interfaces_dialog.h  \
        ui_capture_preferences_frame.h  \
@@ -118,6 +119,7 @@ GENERATOR_FILES =
 MOC_HDRS =     \
        about_dialog.h  \
        accordion_frame.h       \
+       bluetooth_att_server_attributes_dialog.h        \
        byte_view_tab.h \
        byte_view_text.h        \
        capture_file.h  \
@@ -209,6 +211,7 @@ MOC_HDRS =  \
 #
 UI_FILES =     \
        about_dialog.ui \
+       bluetooth_att_server_attributes_dialog.ui       \
        capture_file_properties_dialog.ui       \
        capture_interfaces_dialog.ui    \
        capture_preferences_frame.ui    \
@@ -320,6 +323,7 @@ QRC_SRC = $(QRC_FILES:.qrc=.rcc.cpp)
 WIRESHARK_QT_SRC =     \
        about_dialog.cpp        \
        accordion_frame.cpp     \
+       bluetooth_att_server_attributes_dialog.cpp      \
        byte_view_tab.cpp       \
        byte_view_text.cpp      \
        capture_file.cpp        \
index fedcd037197c50789c211d8b6c2f98607faaffc1..778e14f1f3351d015e4b5aa9b98b147ee68f4766 100644 (file)
@@ -206,6 +206,7 @@ HEADERS_WS_C  = \
 
 FORMS += \
     about_dialog.ui \
+    bluetooth_att_server_attributes_dialog.ui \
     capture_file_properties_dialog.ui \
     capture_interfaces_dialog.ui \
     capture_preferences_frame.ui \
@@ -262,6 +263,7 @@ FORMS += \
 HEADERS += $$HEADERS_WS_C \
     about_dialog.h \
     accordion_frame.h \
+    bluetooth_att_server_attributes_dialog.h \
     capture_file_properties_dialog.h \
     capture_interfaces_dialog.h \
     capture_preferences_frame.h \
@@ -595,6 +597,7 @@ HEADERS += \
 SOURCES += \
     about_dialog.cpp \
     accordion_frame.cpp \
+    bluetooth_att_server_attributes_dialog.cpp \
     byte_view_tab.cpp \
     byte_view_text.cpp \
     capture_file.cpp \
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.cpp b/ui/qt/bluetooth_att_server_attributes_dialog.cpp
new file mode 100644 (file)
index 0000000..c887726
--- /dev/null
@@ -0,0 +1,365 @@
+/* bluetooth_att_server_attributes_dialog.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "bluetooth_att_server_attributes_dialog.h"
+#include "ui_bluetooth_att_server_attributes_dialog.h"
+
+#include "epan/epan.h"
+#include "epan/to_str.h"
+#include "epan/epan_dissect.h"
+#include "epan/dissectors/packet-bluetooth.h"
+#include "epan/dissectors/packet-btatt.h"
+
+#include "ui/simple_dialog.h"
+
+#include <QContextMenuEvent>
+#include <QClipboard>
+
+static const int column_number_handle = 0;
+static const int column_number_uuid = 1;
+static const int column_number_uuid_name = 2;
+
+
+static const gchar *
+bt_print_uuid(uuid_t *uuid)
+{
+    if (uuid->bt_uuid) {
+        return val_to_str_ext_const(uuid->bt_uuid, &bluetooth_uuid_vals_ext, "Unknown");
+    } else {
+        guint i_uuid;
+
+        i_uuid = 0;
+        while (bluetooth_uuid_custom[i_uuid].name) {
+            if (bluetooth_uuid_custom[i_uuid].size != uuid->size) {
+                i_uuid += 1;
+                continue;
+            }
+
+            if (memcmp(uuid->data, bluetooth_uuid_custom[i_uuid].uuid, uuid->size) == 0) {
+                return wmem_strdup(wmem_packet_scope(), bluetooth_uuid_custom[i_uuid].name);
+            }
+
+            i_uuid += 1;
+        }
+
+        return bytes_to_str(wmem_packet_scope(), uuid->data, uuid->size);
+    }
+}
+
+
+static gchar *
+bt_print_numeric_uuid(uuid_t *uuid)
+{
+    if (uuid && uuid->size > 0)
+        return bytes_to_str(wmem_packet_scope(), uuid->data, uuid->size);
+
+    return NULL;
+}
+
+
+static gboolean
+btatt_handle_tap_packet(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *edt, const void* data)
+{
+    tapinfo_t *tapinfo = (tapinfo_t *) tapinfo_ptr;
+
+    if (tapinfo->tap_packet)
+        tapinfo->tap_packet(tapinfo, pinfo, edt, data);
+
+    return TRUE;
+}
+
+static void
+btatt_handle_tap_reset(void *tapinfo_ptr)
+{
+    tapinfo_t *tapinfo = (tapinfo_t *) tapinfo_ptr;
+
+    if (tapinfo->tap_reset)
+        tapinfo->tap_reset(tapinfo);
+}
+
+
+static void
+bluetooth_att_server_attributes_tap(void *data)
+{
+    GString *error_string;
+
+    error_string = register_tap_listener("btatt.handles", data, NULL,
+            0,
+            btatt_handle_tap_reset,
+            btatt_handle_tap_packet,
+            NULL
+            );
+
+    if (error_string != NULL) {
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                "%s", error_string->str);
+        g_string_free(error_string, TRUE);
+    }
+}
+
+
+BluetoothAttServerAttributesDialog::BluetoothAttServerAttributesDialog(QWidget &parent, CaptureFile &cf) :
+    WiresharkDialog(parent, cf),
+    ui(new Ui::BluetoothAttServerAttributesDialog)
+{
+    ui->setupUi(this);
+    resize(parent.width() * 4 / 5, parent.height() * 2 / 3);
+
+    connect(ui->tableTreeWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(tableContextMenu(const QPoint &)));
+    connect(ui->interfaceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(interfaceCurrentIndexChanged(int)));
+    connect(ui->deviceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(deviceCurrentIndexChanged(int)));
+    connect(ui->removeDuplicatesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(removeDuplicatesStateChanged(int)));
+
+    ui->tableTreeWidget->sortByColumn(column_number_handle, Qt::AscendingOrder);
+
+    context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Cell);
+    context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Rows);
+
+    copy_all_button_ = ui->buttonBox->addButton(tr("Copy All"), QDialogButtonBox::ApplyRole);
+
+    tapinfo_.tap_packet = tapPacket;
+    tapinfo_.tap_reset  = tapReset;
+    tapinfo_.ui = this;
+
+    bluetooth_att_server_attributes_tap(&tapinfo_);
+
+    cap_file_.retapPackets();
+}
+
+
+BluetoothAttServerAttributesDialog::~BluetoothAttServerAttributesDialog()
+{
+    delete ui;
+
+    remove_tap_listener(&tapinfo_);
+}
+
+
+void BluetoothAttServerAttributesDialog::captureFileClosing()
+{
+    remove_tap_listener(&tapinfo_);
+
+    WiresharkDialog::captureFileClosing();
+}
+
+
+void BluetoothAttServerAttributesDialog::changeEvent(QEvent *event)
+{
+    if (0 != event)
+    {
+        switch (event->type())
+        {
+        case QEvent::LanguageChange:
+            ui->retranslateUi(this);
+            break;
+        default:
+            break;
+        }
+    }
+    QDialog::changeEvent(event);
+}
+
+
+void BluetoothAttServerAttributesDialog::tableContextMenu(const QPoint &pos)
+{
+    context_menu_.exec(ui->tableTreeWidget->viewport()->mapToGlobal(pos));
+}
+
+
+void BluetoothAttServerAttributesDialog::on_actionCopy_Cell_triggered()
+{
+    QClipboard             *clipboard = QApplication::clipboard();
+    QString                 copy;
+
+    copy = QString(ui->tableTreeWidget->currentItem()->text(ui->tableTreeWidget->currentColumn()));
+
+    clipboard->setText(copy);
+}
+
+
+void BluetoothAttServerAttributesDialog::on_actionCopy_Rows_triggered()
+{
+    QClipboard                         *clipboard = QApplication::clipboard();
+    QString                             copy;
+    QList<QTreeWidgetItem *>            items;
+    QList<QTreeWidgetItem *>::iterator  i_item;
+
+    items =  ui->tableTreeWidget->selectedItems();
+
+    for (i_item = items.begin(); i_item != items.end(); ++i_item) {
+        copy += QString("%1  %2  %3\n")
+                .arg((*i_item)->text(column_number_handle), -6)
+                .arg((*i_item)->text(column_number_uuid), -32)
+                .arg((*i_item)->text(column_number_uuid_name));
+
+    }
+
+    clipboard->setText(copy);
+}
+
+void BluetoothAttServerAttributesDialog::tapReset(void *tapinfo_ptr )
+{
+    tapinfo_t *tapinfo = (tapinfo_t *) tapinfo_ptr;
+    BluetoothAttServerAttributesDialog  *bluetooth_att_server_attributes_dialog = static_cast<BluetoothAttServerAttributesDialog *>(tapinfo->ui);
+
+
+    bluetooth_att_server_attributes_dialog->ui->tableTreeWidget->clear();
+}
+
+
+gboolean BluetoothAttServerAttributesDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data)
+{
+    tapinfo_t                           *tapinfo     = static_cast<tapinfo_t *>(tapinfo_ptr);
+    BluetoothAttServerAttributesDialog  *dialog      = static_cast<BluetoothAttServerAttributesDialog *>(tapinfo->ui);
+    tap_handles_t                       *tap_handles = static_cast<tap_handles_t *>(const_cast<void *>(data));
+    QString                              handle;
+    QString                              uuid;
+    QString                              uuid_name;
+    gchar                               *addr = NULL;
+
+    if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
+        gchar       *interface;
+        const char  *interface_name;
+
+        interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id);
+        interface = wmem_strdup_printf(wmem_packet_scope(), "%u: %s", pinfo->phdr->interface_id, interface_name);
+
+        if (dialog->ui->interfaceComboBox->findText(interface) == -1)
+            dialog->ui->interfaceComboBox->addItem(interface);
+
+        if (interface && dialog->ui->interfaceComboBox->currentIndex() > 0) {
+            if (dialog->ui->interfaceComboBox->currentText() != interface)
+            return TRUE;
+        }
+    }
+
+    if (pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV)
+        addr = address_to_str(wmem_packet_scope(), &pinfo->src);
+
+    if (addr && dialog->ui->deviceComboBox->findText(addr) == -1) {
+        dialog->ui->deviceComboBox->addItem(addr);
+    }
+
+    if (addr && dialog->ui->deviceComboBox->currentIndex() > 0) {
+        if (dialog->ui->deviceComboBox->currentText() != addr)
+        return TRUE;
+    }
+
+    handle.sprintf("0x%04x", tap_handles->handle);
+    uuid.sprintf("0x%s", bt_print_numeric_uuid(&tap_handles->uuid));
+    uuid_name = QString(bt_print_uuid(&tap_handles->uuid));
+
+    if (dialog->ui->removeDuplicatesCheckBox->checkState() == Qt::Checked) {
+        QTreeWidgetItemIterator i_item(dialog->ui->tableTreeWidget);
+
+        while (*i_item) {
+            QTreeWidgetItem *item = static_cast<QTreeWidgetItem*>(*i_item);
+
+            if (item->text(column_number_handle) == handle &&
+                    item->text(column_number_uuid) == uuid &&
+                    item->text(column_number_uuid_name) == uuid_name)
+                return TRUE;
+            i_item += 1;
+        }
+    }
+
+    QTreeWidgetItem *item = new QTreeWidgetItem(dialog->ui->tableTreeWidget);
+    item->setText(column_number_handle, handle);
+    item->setText(column_number_uuid, uuid);
+    item->setText(column_number_uuid_name,  uuid_name);
+    item->setData(0, Qt::UserRole, qVariantFromValue(pinfo->fd->num));
+
+    for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) {
+        dialog->ui->tableTreeWidget->resizeColumnToContents(i);
+    }
+
+    return TRUE;
+}
+
+void BluetoothAttServerAttributesDialog::interfaceCurrentIndexChanged(int)
+{
+    cap_file_.retapPackets();
+}
+
+
+void BluetoothAttServerAttributesDialog::deviceCurrentIndexChanged(int)
+{
+    cap_file_.retapPackets();
+}
+
+
+void BluetoothAttServerAttributesDialog::removeDuplicatesStateChanged(int)
+{
+    cap_file_.retapPackets();
+}
+
+
+
+void BluetoothAttServerAttributesDialog::on_tableTreeWidget_itemActivated(QTreeWidgetItem *item, int)
+{
+    guint32 frame_number = item->data(0, Qt::UserRole).value<guint32>();
+
+    emit goToPacket(frame_number);
+}
+
+
+void BluetoothAttServerAttributesDialog::copyAll()
+{
+    QClipboard             *clipboard = QApplication::clipboard();
+    QString                 copy;
+    QTreeWidgetItemIterator i_item(ui->tableTreeWidget);
+
+    copy = QString("%1  %2  %3\n")
+            .arg(ui->tableTreeWidget->headerItem()->text(column_number_handle), -6)
+            .arg(ui->tableTreeWidget->headerItem()->text(column_number_uuid), -32)
+            .arg(ui->tableTreeWidget->headerItem()->text(column_number_uuid_name));
+
+    while (*i_item) {
+        QTreeWidgetItem *item = static_cast<QTreeWidgetItem*>(*i_item);
+        copy += QString("%1  %2  %3\n")
+                .arg(item->text(column_number_handle), -6)
+                .arg(item->text(column_number_uuid), -32)
+                .arg(item->text(column_number_uuid_name));
+        i_item += 1;
+    }
+
+    clipboard->setText(copy);
+}
+
+
+void BluetoothAttServerAttributesDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+    if (button == copy_all_button_)
+        copyAll();
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.h b/ui/qt/bluetooth_att_server_attributes_dialog.h
new file mode 100644 (file)
index 0000000..25fc4d4
--- /dev/null
@@ -0,0 +1,108 @@
+/* bluetooth_att_server_attributes_dialog.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef BLUETOOTH_ATT_SERVER_ATTRIBUTES_DIALOG_H
+#define BLUETOOTH_ATT_SERVER_ATTRIBUTES_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "wireshark_dialog.h"
+#include "cfile.h"
+
+#include "epan/tap.h"
+
+#include <QMenu>
+#include <QPushButton>
+#include <QTreeWidget>
+
+class QAbstractButton;
+class QTreeWidgetItem;
+
+typedef struct _tapinfo_t {
+    tap_reset_cb    tap_reset;
+    tap_packet_cb   tap_packet;
+    void           *ui;
+} tapinfo_t;
+
+namespace Ui {
+class BluetoothAttServerAttributesDialog;
+}
+
+class QTreeWidgetItem;
+class BluetoothAttServerAttributesDialog : public WiresharkDialog
+{
+    Q_OBJECT
+
+public:
+    explicit BluetoothAttServerAttributesDialog(QWidget &parent, CaptureFile &cf);
+    ~BluetoothAttServerAttributesDialog();
+
+public slots:
+
+signals:
+    void updateFilter(QString &filter, bool force = false);
+    void captureFileChanged(capture_file *cf);
+    void goToPacket(int packet_num);
+
+protected:
+
+protected slots:
+    void changeEvent(QEvent* event);
+
+private:
+    Ui::BluetoothAttServerAttributesDialog *ui;
+
+    tapinfo_t    tapinfo_;
+    QPushButton *copy_all_button_;
+    QMenu        context_menu_;
+
+    static void     tapReset(void *tapinfo_ptr);
+    static gboolean tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data);
+    void copyAll();
+
+private slots:
+    void captureFileClosing();
+    void on_tableTreeWidget_itemActivated(QTreeWidgetItem *item, int);
+    void on_buttonBox_clicked(QAbstractButton *button);
+    void on_actionCopy_Cell_triggered();
+    void on_actionCopy_Rows_triggered();
+    void tableContextMenu(const QPoint &pos);
+    void interfaceCurrentIndexChanged(int index);
+    void deviceCurrentIndexChanged(int index);
+    void removeDuplicatesStateChanged(int state);
+};
+
+#endif // BLUETOOTH_ATT_SERVER_ATTRIBUTES_DIALOG_H
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.ui b/ui/qt/bluetooth_att_server_attributes_dialog.ui
new file mode 100644 (file)
index 0000000..77fe3c6
--- /dev/null
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BluetoothAttServerAttributesDialog</class>
+ <widget class="QDialog" name="BluetoothAttServerAttributesDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>880</width>
+    <height>477</height>
+   </rect>
+  </property>
+  <property name="baseSize">
+   <size>
+    <width>0</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Bluetooth ATT Server Attributes</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeWidget" name="tableTreeWidget">
+     <property name="contextMenuPolicy">
+      <enum>Qt::CustomContextMenu</enum>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::ExtendedSelection</enum>
+     </property>
+     <property name="textElideMode">
+      <enum>Qt::ElideMiddle</enum>
+     </property>
+     <property name="rootIsDecorated">
+      <bool>false</bool>
+     </property>
+     <property name="itemsExpandable">
+      <bool>false</bool>
+     </property>
+     <property name="sortingEnabled">
+      <bool>true</bool>
+     </property>
+     <attribute name="headerCascadingSectionResizes">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="headerHighlightSections">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="headerShowSortIndicator" stdset="0">
+      <bool>true</bool>
+     </attribute>
+     <column>
+      <property name="text">
+       <string>Handle</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>UUID</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>UUID Name</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
+     <property name="spacing">
+      <number>-1</number>
+     </property>
+     <property name="sizeConstraint">
+      <enum>QLayout::SetDefaultConstraint</enum>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QComboBox" name="interfaceComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>350</width>
+         <height>0</height>
+        </size>
+       </property>
+       <item>
+        <property name="text">
+         <string>All Interfaces</string>
+        </property>
+       </item>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="deviceComboBox">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>325</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="baseSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="mouseTracking">
+        <bool>false</bool>
+       </property>
+       <property name="focusPolicy">
+        <enum>Qt::WheelFocus</enum>
+       </property>
+       <property name="acceptDrops">
+        <bool>false</bool>
+       </property>
+       <property name="layoutDirection">
+        <enum>Qt::LeftToRight</enum>
+       </property>
+       <property name="currentIndex">
+        <number>0</number>
+       </property>
+       <property name="duplicatesEnabled">
+        <bool>false</bool>
+       </property>
+       <property name="frame">
+        <bool>true</bool>
+       </property>
+       <property name="modelColumn">
+        <number>0</number>
+       </property>
+       <item>
+        <property name="text">
+         <string>All Devices</string>
+        </property>
+       </item>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="removeDuplicatesCheckBox">
+       <property name="text">
+        <string>Remove duplicates</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+  <action name="actionCopy_Cell">
+   <property name="text">
+    <string>Copy Cell</string>
+   </property>
+  </action>
+  <action name="actionCopy_Rows">
+   <property name="text">
+    <string>Copy Rows</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>BluetoothAttServerAttributesDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>374</x>
+     <y>407</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>374</x>
+     <y>214</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>BluetoothAttServerAttributesDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>374</x>
+     <y>407</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>374</x>
+     <y>214</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index 3bdc9e4158cec9ec6414bdfa5966b07e8ef22219..b40bbd4c28948c71a5e59e64ea843cb216ce9a7f 100644 (file)
@@ -438,6 +438,8 @@ private slots:
     void on_actionTelephonyUCPMessages_triggered();
     void on_actionTelephonySipFlows_triggered();
 
+    void on_actionATT_Server_Attributes_triggered();
+
     void changeEvent(QEvent* event);
 };
 
index b2f945dd27112595ed48056a963904ed2c76e237..f6ef2fbc77336fede2e7276a6de45a2fffa96085 100644 (file)
     <addaction name="actionEditConfigurationProfiles"/>
     <addaction name="actionEditPreferences"/>
    </widget>
+   <widget class="QMenu" name="menuBluetooth">
+    <property name="title">
+     <string>Bluetooth</string>
+    </property>
+    <addaction name="actionATT_Server_Attributes"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menuEdit"/>
    <addaction name="menuView"/>
    <addaction name="menuAnalyze"/>
    <addaction name="menuStatistics"/>
    <addaction name="menuTelephony"/>
+   <addaction name="menuBluetooth"/>
    <addaction name="menuHelp"/>
   </widget>
   <widget class="QToolBar" name="mainToolBar">
     <string>Edit the packet list coloring rules.</string>
    </property>
   </action>
+  <action name="actionATT_Server_Attributes">
+   <property name="text">
+    <string>ATT Server Attributes</string>
+   </property>
+  </action>
+  <action name="actionDevices">
+   <property name="text">
+    <string>Devices</string>
+   </property>
+  </action>
+  <action name="actionServices">
+   <property name="text">
+    <string>Services</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
index b80478a584ec5ba312f2f8b976061a8f91f65b92..7a5edfb0017922534ce28de786c62cb71366ad38 100644 (file)
@@ -71,6 +71,7 @@
 #include "ui/software_update.h"
 #endif
 
+#include "bluetooth_att_server_attributes_dialog.h"
 #include "capture_file_dialog.h"
 #include "capture_file_properties_dialog.h"
 #include "coloring_rules_dialog.h"
@@ -2528,6 +2529,18 @@ void MainWindow::on_actionTelephonySipFlows_triggered()
     openVoipCallsDialog(true);
 }
 
+// Bluetooth Menu
+
+void MainWindow::on_actionATT_Server_Attributes_triggered()
+{
+    BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
+    connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
+            packet_list_, SLOT(goToPacket(int)));
+    connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString&, bool)),
+            this, SLOT(filterPackets(QString&, bool)));
+    bluetooth_att_sever_attributes_dialog->show();
+}
+
 // Help Menu
 void MainWindow::on_actionHelpContents_triggered() {