aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2015-06-08 19:38:48 +0200
committerMichal Labedzki <michal.labedzki@tieto.com>2015-07-17 13:54:43 +0000
commit3faec795e9c5b5f153f66960c11673c2f53e4243 (patch)
tree4df5f704a41290a0a0694c3896a8a7e6521001ac /ui
parent6514dece0c755854081a0a0ccb525e6bc9dbbaff (diff)
Qt/Bluetooth: Add HCI Summary dialogue
HCI Summary dialogue collect HCI Opcodes, HCI Events, Hardware Errors, Statuses and Reasons. Also show occurrence of them. The top level item is group of items (by OGF or types), the second level item is in real command, event, hardware error, status or reason. The third level items are direct link to packet that contains second level item type. Change-Id: I6b6bd02533c4605a2dd2c1f5dfee46f72a0f3fdc Reviewed-on: https://code.wireshark.org/review/9676 Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Petri-Dish: Michal Labedzki <michal.labedzki@tieto.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/CMakeLists.txt3
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common4
-rw-r--r--ui/qt/Wireshark.pro3
-rw-r--r--ui/qt/bluetooth_hci_summary_dialog.cpp727
-rw-r--r--ui/qt/bluetooth_hci_summary_dialog.h124
-rw-r--r--ui/qt/bluetooth_hci_summary_dialog.ui661
-rw-r--r--ui/qt/main_window.h1
-rw-r--r--ui/qt/main_window.ui6
-rw-r--r--ui/qt/main_window_slots.cpp11
10 files changed, 1542 insertions, 0 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 43bfd7bbd8..f5fc5b104d 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -26,6 +26,7 @@ set(WIRESHARK_QT_HEADERS
accordion_frame.h
bluetooth_att_server_attributes_dialog.h
bluetooth_devices_dialog.h
+ bluetooth_hci_summary_dialog.h
accordion_frame.h
byte_view_tab.h
byte_view_text.h
@@ -157,6 +158,7 @@ set(WIRESHARK_QT_SRC
accordion_frame.cpp
bluetooth_att_server_attributes_dialog.cpp
bluetooth_devices_dialog.cpp
+ bluetooth_hci_summary_dialog.cpp
byte_view_tab.cpp
byte_view_text.cpp
capture_file.cpp
@@ -291,6 +293,7 @@ set(WIRESHARK_QT_UI
about_dialog.ui
bluetooth_att_server_attributes_dialog.ui
bluetooth_devices_dialog.ui
+ bluetooth_hci_summary_dialog.ui
capture_file_progress_frame.ui
capture_file_properties_dialog.ui
capture_interfaces_dialog.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 0f045e182d..ddf6d4bc74 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -134,6 +134,8 @@ bluetooth_att_server_attributes_dialog.$(OBJEXT): ui_bluetooth_att_server_attrib
bluetooth_devices_dialog.$(OBJEXT): ui_bluetooth_devices_dialog.h
+bluetooth_hci_summary_dialog.$(OBJEXT): ui_bluetooth_hci_summary_dialog.h
+
capture_file_progress_frame.$(OBJEXT): ui_capture_file_progress_frame.h
capture_file_properties_dialog.$(OBJEXT): ui_capture_file_properties_dialog.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index 5264100aec..89d20a5c3e 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -32,6 +32,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_about_dialog.h \
ui_bluetooth_att_server_attributes_dialog.h \
ui_bluetooth_devices_dialog.h \
+ ui_bluetooth_hci_summary_dialog.h \
ui_capture_file_progress_frame.h \
ui_capture_file_properties_dialog.h \
ui_capture_interfaces_dialog.h \
@@ -135,6 +136,7 @@ MOC_HDRS = \
accordion_frame.h \
bluetooth_att_server_attributes_dialog.h \
bluetooth_devices_dialog.h \
+ bluetooth_hci_summary_dialog.h \
byte_view_tab.h \
byte_view_text.h \
capture_file.h \
@@ -248,6 +250,7 @@ UI_FILES = \
about_dialog.ui \
bluetooth_att_server_attributes_dialog.ui \
bluetooth_devices_dialog.ui \
+ bluetooth_hci_summary_dialog.ui \
capture_file_progress_frame.ui \
capture_file_properties_dialog.ui \
capture_interfaces_dialog.ui \
@@ -366,6 +369,7 @@ WIRESHARK_QT_SRC = \
accordion_frame.cpp \
bluetooth_att_server_attributes_dialog.cpp \
bluetooth_devices_dialog.cpp \
+ bluetooth_hci_summary_dialog.cpp \
byte_view_tab.cpp \
byte_view_text.cpp \
capture_file.cpp \
diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro
index d2fb545d02..4e70796b93 100644
--- a/ui/qt/Wireshark.pro
+++ b/ui/qt/Wireshark.pro
@@ -208,6 +208,7 @@ FORMS += \
about_dialog.ui \
bluetooth_att_server_attributes_dialog.ui \
bluetooth_devices_dialog.ui \
+ bluetooth_hci_summary_dialog.ui \
capture_file_progress_frame.ui \
capture_file_properties_dialog.ui \
capture_interfaces_dialog.ui \
@@ -278,6 +279,7 @@ HEADERS += $$HEADERS_WS_C \
accordion_frame.h \
bluetooth_att_server_attributes_dialog.h \
bluetooth_devices_dialog.h \
+ bluetooth_hci_summary_dialog.h \
capture_file_progress_frame.h \
capture_file_properties_dialog.h \
capture_interfaces_dialog.h \
@@ -636,6 +638,7 @@ SOURCES += \
accordion_frame.cpp \
bluetooth_att_server_attributes_dialog.cpp \
bluetooth_devices_dialog.cpp \
+ bluetooth_hci_summary_dialog.cpp \
byte_view_tab.cpp \
byte_view_text.cpp \
capture_file.cpp \
diff --git a/ui/qt/bluetooth_hci_summary_dialog.cpp b/ui/qt/bluetooth_hci_summary_dialog.cpp
new file mode 100644
index 0000000000..23d68e6e00
--- /dev/null
+++ b/ui/qt/bluetooth_hci_summary_dialog.cpp
@@ -0,0 +1,727 @@
+/* bluetooth_hci_summary_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_hci_summary_dialog.h"
+#include "ui_bluetooth_hci_summary_dialog.h"
+
+#include "epan/epan.h"
+#include "epan/addr_resolv.h"
+#include "epan/to_str.h"
+#include "epan/epan_dissect.h"
+#include "epan/dissectors/packet-bluetooth.h"
+#include "epan/dissectors/packet-bthci_cmd.h"
+#include "epan/dissectors/packet-bthci_evt.h"
+
+#include "ui/simple_dialog.h"
+
+#include <QClipboard>
+#include <QContextMenuEvent>
+#include <QPushButton>
+#include <QTreeWidget>
+#include <QFileDialog>
+
+static const int column_number_name = 0;
+static const int column_number_ogf = 1;
+static const int column_number_ocf = 2;
+static const int column_number_opcode = 3;
+static const int column_number_event = 4;
+static const int column_number_status = 5;
+static const int column_number_reason = 6;
+static const int column_number_hardware_error = 7;
+static const int column_number_occurrence = 8;
+
+typedef struct _item_data_t {
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 frame_number;
+} item_data_t;
+
+Q_DECLARE_METATYPE(item_data_t *)
+
+static gboolean
+bluetooth_device_tap_packet(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *edt, const void* data)
+{
+ bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
+
+ if (tapinfo->tap_packet)
+ tapinfo->tap_packet(tapinfo, pinfo, edt, data);
+
+ return TRUE;
+}
+
+static void
+bluetooth_device_tap_reset(void *tapinfo_ptr)
+{
+ bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
+
+ if (tapinfo->tap_reset)
+ tapinfo->tap_reset(tapinfo);
+}
+
+static void
+bluetooth_devices_tap(void *data)
+{
+ GString *error_string;
+
+ error_string = register_tap_listener("bluetooth.hci_summary", data, NULL,
+ 0,
+ bluetooth_device_tap_reset,
+ bluetooth_device_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);
+ }
+}
+
+
+BluetoothHciSummaryDialog::BluetoothHciSummaryDialog(QWidget &parent, CaptureFile &cf) :
+ WiresharkDialog(parent, cf),
+ ui(new Ui::BluetoothHciSummaryDialog)
+{
+ 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->tableTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(tableItemExpanded(QTreeWidgetItem *)));
+ connect(ui->tableTreeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(tableItemCollapsed(QTreeWidgetItem *)));
+
+ connect(ui->interfaceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(interfaceCurrentIndexChanged(int)));
+ connect(ui->adapterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(adapterCurrentIndexChanged(int)));
+
+ for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
+ ui->tableTreeWidget->resizeColumnToContents(i);
+ }
+
+ context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Cell);
+ context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Rows);
+ context_menu_.addActions(QList<QAction *>() << ui->actionCopy_All);
+ context_menu_.addActions(QList<QAction *>() << ui->actionSave_as_image);
+
+ tapinfo_.tap_packet = tapPacket;
+ tapinfo_.tap_reset = tapReset;
+ tapinfo_.ui = this;
+
+ item_link_control_ = ui->tableTreeWidget->topLevelItem(0);
+ item_link_policy_ = ui->tableTreeWidget->topLevelItem(1);
+ item_controller_and_baseband_ = ui->tableTreeWidget->topLevelItem(2);
+ item_informational_ = ui->tableTreeWidget->topLevelItem(3);
+ item_status_parameters_ = ui->tableTreeWidget->topLevelItem(4);
+ item_testing_ = ui->tableTreeWidget->topLevelItem(5);
+ item_low_energy_ = ui->tableTreeWidget->topLevelItem(6);
+ item_logo_testing_ = ui->tableTreeWidget->topLevelItem(7);
+ item_vendor_ = ui->tableTreeWidget->topLevelItem(8);
+ item_unknown_ogf_ = ui->tableTreeWidget->topLevelItem(9);
+ item_events_ = ui->tableTreeWidget->topLevelItem(10);
+ item_status_ = ui->tableTreeWidget->topLevelItem(11);
+ item_reason_ = ui->tableTreeWidget->topLevelItem(12);
+ item_hardware_errors_ = ui->tableTreeWidget->topLevelItem(13);
+
+ bluetooth_devices_tap(&tapinfo_);
+
+ cap_file_.retapPackets();
+}
+
+
+BluetoothHciSummaryDialog::~BluetoothHciSummaryDialog()
+{
+ delete ui;
+
+ remove_tap_listener(&tapinfo_);
+}
+
+
+void BluetoothHciSummaryDialog::captureFileClosing()
+{
+ remove_tap_listener(&tapinfo_);
+
+ ui->interfaceComboBox->setEnabled(FALSE);
+ ui->adapterComboBox->setEnabled(FALSE);
+
+ WiresharkDialog::captureFileClosing();
+}
+
+
+void BluetoothHciSummaryDialog::changeEvent(QEvent *event)
+{
+ if (0 != event)
+ {
+ switch (event->type())
+ {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+ }
+ QDialog::changeEvent(event);
+}
+
+
+void BluetoothHciSummaryDialog::tableContextMenu(const QPoint &pos)
+{
+ context_menu_.exec(ui->tableTreeWidget->viewport()->mapToGlobal(pos));
+}
+
+void BluetoothHciSummaryDialog::tableItemExpanded(QTreeWidgetItem *item)
+{
+ Q_UNUSED(item);
+
+ for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
+ ui->tableTreeWidget->resizeColumnToContents(i);
+ }
+}
+
+void BluetoothHciSummaryDialog::tableItemCollapsed(QTreeWidgetItem *item)
+{
+ Q_UNUSED(item);
+
+ for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
+ ui->tableTreeWidget->resizeColumnToContents(i);
+ }
+}
+
+void BluetoothHciSummaryDialog::on_actionCopy_Cell_triggered()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString copy;
+
+ copy = QString(ui->tableTreeWidget->currentItem()->text(ui->tableTreeWidget->currentColumn()));
+
+ clipboard->setText(copy);
+}
+
+
+void BluetoothHciSummaryDialog::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 %4 %5 %6 %7 %8 %9\n")
+ .arg((*i_item)->text(column_number_name), -60)
+ .arg((*i_item)->text(column_number_ogf), -10)
+ .arg((*i_item)->text(column_number_ocf), -10)
+ .arg((*i_item)->text(column_number_opcode), -10)
+ .arg((*i_item)->text(column_number_event), -10)
+ .arg((*i_item)->text(column_number_status), -10)
+ .arg((*i_item)->text(column_number_reason), -10)
+ .arg((*i_item)->text(column_number_hardware_error), -15)
+ .arg((*i_item)->text(column_number_occurrence), -10);
+ }
+
+ clipboard->setText(copy);
+}
+
+void BluetoothHciSummaryDialog::tapReset(void *tapinfo_ptr )
+{
+ bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
+ BluetoothHciSummaryDialog *dialog = static_cast<BluetoothHciSummaryDialog *>(tapinfo->ui);
+
+ dialog->item_link_control_->takeChildren();
+ dialog->item_link_control_->setText(column_number_occurrence, "0");
+
+ dialog->item_link_policy_->takeChildren();
+ dialog->item_link_policy_->setText(column_number_occurrence, "0");
+
+ dialog->item_controller_and_baseband_->takeChildren();
+ dialog->item_controller_and_baseband_->setText(column_number_occurrence, "0");
+
+ dialog->item_informational_->takeChildren();
+ dialog->item_informational_->setText(column_number_occurrence, "0");
+
+ dialog->item_status_parameters_->takeChildren();
+ dialog->item_status_parameters_->setText(column_number_occurrence, "0");
+
+ dialog->item_testing_->takeChildren();
+ dialog->item_testing_->setText(column_number_occurrence, "0");
+
+ dialog->item_low_energy_->takeChildren();
+ dialog->item_low_energy_->setText(column_number_occurrence, "0");
+
+ dialog->item_logo_testing_->takeChildren();
+ dialog->item_logo_testing_->setText(column_number_occurrence, "0");
+
+ dialog->item_vendor_->takeChildren();
+ dialog->item_vendor_->setText(column_number_occurrence, "0");
+
+ dialog->item_unknown_ogf_->takeChildren();
+ dialog->item_unknown_ogf_->setText(column_number_occurrence, "0");
+
+ dialog->item_events_->takeChildren();
+ dialog->item_events_->setText(column_number_occurrence, "0");
+
+ dialog->item_status_->takeChildren();
+ dialog->item_status_->setText(column_number_occurrence, "0");
+
+ dialog->item_reason_->takeChildren();
+ dialog->item_reason_->setText(column_number_occurrence, "0");
+
+ dialog->item_hardware_errors_->takeChildren();
+ dialog->item_hardware_errors_->setText(column_number_occurrence, "0");
+}
+
+gboolean BluetoothHciSummaryDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data)
+{
+ bluetooth_hci_summary_tapinfo_t *tapinfo = static_cast<bluetooth_hci_summary_tapinfo_t *>(tapinfo_ptr);
+ BluetoothHciSummaryDialog *dialog = static_cast<BluetoothHciSummaryDialog *>(tapinfo->ui);
+ bluetooth_hci_summary_tap_t *tap_hci = static_cast<bluetooth_hci_summary_tap_t *>(const_cast<void *>(data));
+ QTreeWidgetItem *main_item = NULL;
+ QTreeWidgetItem *item = NULL;
+ QTreeWidgetItem *frame_item = NULL;
+ item_data_t *item_data = NULL;
+ QString adapter;
+ QString name;
+
+ name = tr("Unknown");
+
+ 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;
+ }
+ }
+
+ adapter = QString(tr("Adapter %1")).arg(tap_hci->adapter_id);
+
+ if (dialog->ui->adapterComboBox->findText(adapter) == -1) {
+ dialog->ui->adapterComboBox->addItem(adapter);
+ }
+
+ if (dialog->ui->adapterComboBox->currentIndex() > 0) {
+ if (dialog->ui->adapterComboBox->currentText() != adapter)
+ return TRUE;
+ }
+
+ switch (tap_hci->type) {
+ case BLUETOOTH_HCI_SUMMARY_OPCODE:
+ case BLUETOOTH_HCI_SUMMARY_EVENT_OPCODE:
+ case BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE:
+ case BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE:
+ switch (tap_hci->ogf) {
+ case HCI_OGF_LINK_CONTROL:
+ main_item = dialog->item_link_control_;
+ break;
+ case HCI_OGF_LINK_POLICY:
+ main_item = dialog->item_link_policy_;
+ break;
+ case HCI_OGF_HOST_CONTROLLER:
+ main_item = dialog->item_controller_and_baseband_;
+ break;
+ case HCI_OGF_INFORMATIONAL:
+ main_item = dialog->item_informational_;
+ break;
+ case HCI_OGF_STATUS:
+ main_item = dialog->item_status_parameters_;
+ break;
+ case HCI_OGF_TESTING:
+ main_item = dialog->item_testing_;
+ break;
+ case HCI_OGF_LOW_ENERGY:
+ main_item = dialog->item_low_energy_;
+ break;
+ case HCI_OGF_LOGO_TESTING:
+ main_item = dialog->item_logo_testing_;
+ break;
+ case HCI_OGF_VENDOR_SPECIFIC:
+ main_item = dialog->item_vendor_;
+ break;
+ default:
+ main_item = dialog->item_unknown_ogf_;
+ }
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_opcode) == QString("").sprintf("0x%04X", tap_hci->ogf << 10 | tap_hci->ocf)) {
+ item = main_item->child(i_item);
+ if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE && tap_hci->name)
+ item->setText(column_number_name, tap_hci->name);
+ break;
+ }
+ }
+
+ if (!item) {
+ item = new QTreeWidgetItem();
+ if (tap_hci->name)
+ name = tap_hci->name;
+
+ item->setText(column_number_name, name);
+ item->setText(column_number_ogf, QString("").sprintf("0x%02X", tap_hci->ogf));
+ item->setText(column_number_ocf, QString("").sprintf("0x%04X", tap_hci->ocf));
+ item->setText(column_number_opcode, QString("").sprintf("0x%04X", tap_hci->ogf << 10 | tap_hci->ocf));
+ if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_OPCODE)
+ item->setText(column_number_occurrence, "0");
+ else
+ item->setText(column_number_occurrence, "1");
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_opcode, Qt::AscendingOrder);
+
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ if (tap_hci->type != BLUETOOTH_HCI_SUMMARY_EVENT_OPCODE && tap_hci->type != BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE)
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ /* I belive bthci_cmd/bthci_evt already add frame item */
+ if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE ||
+ tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE)
+ break;
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_ogf, QString("").sprintf("0x%02X", tap_hci->ogf));
+ frame_item->setText(column_number_ocf, QString("").sprintf("0x%04X", tap_hci->ocf));
+ frame_item->setText(column_number_opcode, QString("").sprintf("0x%04X", tap_hci->ogf << 10 | tap_hci->ocf));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ case BLUETOOTH_HCI_SUMMARY_EVENT:
+ case BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT:
+ main_item = dialog->item_events_;
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_event) == QString("").sprintf("0x%02X", tap_hci->event)) {
+ item = main_item->child(i_item);
+ if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT && tap_hci->name)
+ item->setText(column_number_name, tap_hci->name);
+ break;
+ }
+ }
+
+ if (!item) {
+ QString name;
+
+ item = new QTreeWidgetItem();
+ if (tap_hci->name)
+ name = tap_hci->name;
+
+ item->setText(column_number_name, name);
+ item->setText(column_number_event, QString("").sprintf("0x%02X", tap_hci->event));
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_event, Qt::AscendingOrder);
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ /* I belive bthci_cmd/bthci_evt already add frame item */
+ if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT)
+ break;
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_event, QString("").sprintf("0x%02X", tap_hci->event));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ case BLUETOOTH_HCI_SUMMARY_STATUS:
+ main_item = dialog->item_status_;
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_status) == QString("").sprintf("0x%02X", tap_hci->status)) {
+ item = main_item->child(i_item);
+ break;
+ }
+ }
+
+ if (!item) {
+ if (tap_hci->name)
+ name = tap_hci->name;
+
+ item = new QTreeWidgetItem();
+ item->setText(column_number_name, name);
+ item->setText(column_number_status, QString("").sprintf("0x%02X", tap_hci->status));
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_event, Qt::AscendingOrder);
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_status, QString("").sprintf("0x%02X", tap_hci->status));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ case BLUETOOTH_HCI_SUMMARY_STATUS_PENDING:
+ main_item = dialog->item_status_;
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_status) == QString("").sprintf("%u", tap_hci->status)) {
+ item = main_item->child(i_item);
+ break;
+ }
+ }
+
+ if (!item) {
+ item = new QTreeWidgetItem();
+ item->setText(column_number_name, tr("Pending"));
+ item->setText(column_number_status, QString("").sprintf("%u", tap_hci->status));
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_event, Qt::AscendingOrder);
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_status, QString("").sprintf("%u", tap_hci->status));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ case BLUETOOTH_HCI_SUMMARY_REASON:
+ main_item = dialog->item_reason_;
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_reason) == QString("").sprintf("0x%02X", tap_hci->reason)) {
+ item = main_item->child(i_item);
+ break;
+ }
+ }
+
+ if (!item) {
+ if (tap_hci->name)
+ name = tap_hci->name;
+
+ item = new QTreeWidgetItem();
+ item->setText(column_number_name, name);
+ item->setText(column_number_reason, QString("").sprintf("0x%02X", tap_hci->reason));
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_event, Qt::AscendingOrder);
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_reason, QString("").sprintf("0x%02X", tap_hci->reason));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ case BLUETOOTH_HCI_SUMMARY_HARDWARE_ERROR:
+ main_item = dialog->item_hardware_errors_;
+
+ for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
+ if (main_item->child(i_item)->text(column_number_hardware_error) == QString("").sprintf("0x%02X", tap_hci->hardware_error)) {
+ item = main_item->child(i_item);
+ break;
+ }
+ }
+
+ if (!item) {
+ item = new QTreeWidgetItem();
+ item->setText(column_number_name, QString("").sprintf("Hardware error 0x%02X", tap_hci->hardware_error));
+ item->setText(column_number_hardware_error, QString("").sprintf("0x%02X", tap_hci->hardware_error));
+
+ main_item->addChild(item);
+ main_item->sortChildren(column_number_event, Qt::AscendingOrder);
+ main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
+ }
+
+ item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
+
+ frame_item = new QTreeWidgetItem();
+ frame_item->setText(column_number_name, QString(tr("Frame %1")).arg(pinfo->fd->num));
+ frame_item->setText(column_number_hardware_error, QString("").sprintf("0x%02X", tap_hci->hardware_error));
+ item->addChild(frame_item);
+
+ item_data = wmem_new(wmem_file_scope(), item_data_t);
+ item_data->interface_id = tap_hci->interface_id;
+ item_data->adapter_id = tap_hci->adapter_id;
+ item_data->frame_number = pinfo->fd->num;
+ frame_item->setData(0, Qt::UserRole, QVariant::fromValue<item_data_t *>(item_data));
+
+ break;
+ }
+
+ for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) {
+ dialog->ui->tableTreeWidget->resizeColumnToContents(i);
+ }
+
+ return TRUE;
+}
+
+void BluetoothHciSummaryDialog::interfaceCurrentIndexChanged(int)
+{
+ cap_file_.retapPackets();
+}
+
+void BluetoothHciSummaryDialog::adapterCurrentIndexChanged(int)
+{
+ cap_file_.retapPackets();
+}
+
+void BluetoothHciSummaryDialog::on_tableTreeWidget_itemActivated(QTreeWidgetItem *item, int)
+{
+ if (!cap_file_.isValid())
+ return;
+
+ item_data_t *item_data = item->data(0, Qt::UserRole).value<item_data_t *>();
+
+ if (item_data)
+ emit goToPacket(item_data->frame_number);
+}
+
+
+void BluetoothHciSummaryDialog::recursiveCopyTreeItems(QTreeWidgetItem *item, QString &copy, int ident_level)
+{
+ if (!item->isExpanded()) return;
+
+ for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
+ copy.append(QString(" ").repeated(ident_level));
+ copy += QString("%1 %2 %3 %4 %5 %6 %7 %8 %9\n")
+ .arg(item->child(i_item)->text(column_number_name), -60 + 4 * ident_level)
+ .arg(item->child(i_item)->text(column_number_ogf), -10)
+ .arg(item->child(i_item)->text(column_number_ocf), -10)
+ .arg(item->child(i_item)->text(column_number_opcode), -10)
+ .arg(item->child(i_item)->text(column_number_event), -10)
+ .arg(item->child(i_item)->text(column_number_status), -10)
+ .arg(item->child(i_item)->text(column_number_reason), -10)
+ .arg(item->child(i_item)->text(column_number_hardware_error), -15)
+ .arg(item->child(i_item)->text(column_number_occurrence), -10);
+
+ recursiveCopyTreeItems(item->child(i_item), copy, ident_level + 1);
+ }
+}
+
+void BluetoothHciSummaryDialog::on_actionCopy_All_triggered()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString copy;
+ QTreeWidgetItemIterator i_item(ui->tableTreeWidget);
+
+ copy += QString("%1 %2 %3 %4 %5 %6 %7 %8 %9\n")
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_name), -60)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_ogf), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_ocf), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_opcode), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_event), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_status), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_reason), -10)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_hardware_error), -15)
+ .arg(ui->tableTreeWidget->headerItem()->text(column_number_occurrence), -10);
+
+ for (int i_item = 0; i_item < ui->tableTreeWidget->topLevelItemCount(); i_item += 1) {
+ QTreeWidgetItem *item = ui->tableTreeWidget->topLevelItem(i_item);
+
+ copy += QString("%1 %2 %3 %4 %5 %6 %7 %8 %9\n")
+ .arg(item->text(column_number_name), -60)
+ .arg(item->text(column_number_ogf), -10)
+ .arg(item->text(column_number_ocf), -10)
+ .arg(item->text(column_number_opcode), -10)
+ .arg(item->text(column_number_event), -10)
+ .arg(item->text(column_number_status), -10)
+ .arg(item->text(column_number_reason), -10)
+ .arg(item->text(column_number_hardware_error), -15)
+ .arg(item->text(column_number_occurrence), -10);
+
+ recursiveCopyTreeItems(ui->tableTreeWidget->topLevelItem(i_item), copy, 1);
+ }
+
+ clipboard->setText(copy);
+}
+
+void BluetoothHciSummaryDialog::on_actionSave_as_image_triggered()
+{
+ QPixmap image;
+
+ QString fileName = QFileDialog::getSaveFileName(this,
+ tr("Save Table Image"),
+ "bluetooth_hci_summary.png",
+ tr("PNG Image (*.png)"));
+
+ if (fileName.isEmpty()) return;
+
+ image = QPixmap::grabWidget(ui->tableTreeWidget);
+ image.save(fileName, "PNG");
+}
+
+void BluetoothHciSummaryDialog::on_buttonBox_clicked(QAbstractButton *)
+{
+/* if (button == foo_button_) */
+}
+
+/*
+ * 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_hci_summary_dialog.h b/ui/qt/bluetooth_hci_summary_dialog.h
new file mode 100644
index 0000000000..ee3b92259e
--- /dev/null
+++ b/ui/qt/bluetooth_hci_summary_dialog.h
@@ -0,0 +1,124 @@
+/* bluetooth_hci_summary_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_HCI_SUMMARY_DIALOG_H
+#define BLUETOOTH_HCI_SUMMARY_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "wireshark_dialog.h"
+#include "cfile.h"
+#include "packet_list.h"
+
+#include "epan/tap.h"
+
+#include <QMenu>
+
+class QAbstractButton;
+class QPushButton;
+class QTreeWidgetItem;
+
+typedef struct _bluetooth_hci_summary_tapinfo_t {
+ tap_reset_cb tap_reset;
+ tap_packet_cb tap_packet;
+ void *ui;
+} bluetooth_hci_summary_tapinfo_t;
+
+namespace Ui {
+class BluetoothHciSummaryDialog;
+}
+
+class BluetoothHciSummaryDialog : public WiresharkDialog
+{
+ Q_OBJECT
+
+public:
+ explicit BluetoothHciSummaryDialog(QWidget &parent, CaptureFile &cf);
+ ~BluetoothHciSummaryDialog();
+
+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::BluetoothHciSummaryDialog *ui;
+
+ bluetooth_hci_summary_tapinfo_t tapinfo_;
+ QMenu context_menu_;
+
+ QTreeWidgetItem *item_link_control_;
+ QTreeWidgetItem *item_link_policy_;
+ QTreeWidgetItem *item_controller_and_baseband_;
+ QTreeWidgetItem *item_informational_;
+ QTreeWidgetItem *item_status_parameters_;
+ QTreeWidgetItem *item_testing_;
+ QTreeWidgetItem *item_low_energy_;
+ QTreeWidgetItem *item_logo_testing_;
+ QTreeWidgetItem *item_vendor_;
+ QTreeWidgetItem *item_unknown_ogf_;
+ QTreeWidgetItem *item_events_;
+ QTreeWidgetItem *item_status_;
+ QTreeWidgetItem *item_reason_;
+ QTreeWidgetItem *item_hardware_errors_;
+
+ static void tapReset(void *tapinfo_ptr);
+ static gboolean tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data);
+
+private slots:
+ void captureFileClosing();
+ void recursiveCopyTreeItems(QTreeWidgetItem *item, QString &copy, int ident_level);
+ void on_tableTreeWidget_itemActivated(QTreeWidgetItem *item, int);
+ void on_buttonBox_clicked(QAbstractButton *button);
+ void on_actionCopy_Cell_triggered();
+ void on_actionCopy_Rows_triggered();
+ void on_actionCopy_All_triggered();
+ void on_actionSave_as_image_triggered();
+ void tableContextMenu(const QPoint &pos);
+ void tableItemExpanded(QTreeWidgetItem *item);
+ void tableItemCollapsed(QTreeWidgetItem *item);
+ void interfaceCurrentIndexChanged(int index);
+ void adapterCurrentIndexChanged(int index);
+};
+
+#endif // BLUETOOTH_HCI_SUMMARY_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_hci_summary_dialog.ui b/ui/qt/bluetooth_hci_summary_dialog.ui
new file mode 100644
index 0000000000..8e429f2c51
--- /dev/null
+++ b/ui/qt/bluetooth_hci_summary_dialog.ui
@@ -0,0 +1,661 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BluetoothHciSummaryDialog</class>
+ <widget class="QDialog" name="BluetoothHciSummaryDialog">
+ <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 HCI Summary</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeWidget" name="tableTreeWidget">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideMiddle</enum>
+ </property>
+ <property name="indentation">
+ <number>30</number>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>true</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>false</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>true</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="animated">
+ <bool>false</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>false</bool>
+ </property>
+ <property name="headerHidden">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>100</number>
+ </attribute>
+ <attribute name="headerHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>100</number>
+ </attribute>
+ <attribute name="headerShowSortIndicator" stdset="0">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>OGF</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>OCF</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Opcode</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Event</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Status</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Reason</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Hardware Error</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Occurrence</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>Link Control Commands</string>
+ </property>
+ <property name="text">
+ <string>0x01</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Link Policy Commands</string>
+ </property>
+ <property name="text">
+ <string>0x02</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Controller &amp; Baseband Commands</string>
+ </property>
+ <property name="text">
+ <string>0x03</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Informational Parameters</string>
+ </property>
+ <property name="text">
+ <string>0x04</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Status Parameters</string>
+ </property>
+ <property name="text">
+ <string>0x05</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Testing Commands</string>
+ </property>
+ <property name="text">
+ <string>0x06</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>LE Controller Commands</string>
+ </property>
+ <property name="text">
+ <string>0x08</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Bluetooth Logo Testing Commands</string>
+ </property>
+ <property name="text">
+ <string>0x3E</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Vendor-Specific Commands</string>
+ </property>
+ <property name="text">
+ <string>0x3F</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Unknown OGF</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Events</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Status</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Reason</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Hardware Errors</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="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="adapterComboBox">
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>All Adapters</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="hintLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </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>
+ <action name="actionCopy_All">
+ <property name="text">
+ <string>Copy All</string>
+ </property>
+ </action>
+ <action name="actionSave_as_image">
+ <property name="text">
+ <string>Save as image</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>BluetoothHciSummaryDialog</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>BluetoothHciSummaryDialog</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>
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 6f74cda8f6..1c238b7495 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -519,6 +519,7 @@ private slots:
void on_actionATT_Server_Attributes_triggered();
void on_actionDevices_triggered();
+ void on_actionHCI_Summary_triggered();
void externalMenuItem_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 6a334ef049..637dcd949a 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -566,6 +566,7 @@
</property>
<addaction name="actionATT_Server_Attributes"/>
<addaction name="actionDevices"/>
+ <addaction name="actionHCI_Summary"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
@@ -2347,6 +2348,11 @@
<string>Devices</string>
</property>
</action>
+ <action name="actionHCI_Summary">
+ <property name="text">
+ <string>HCI Summary</string>
+ </property>
+ </action>
<action name="actionViewShowPacketInNewWindow">
<property name="text">
<string>Show Packet in New &amp;Window</string>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index d62d91ccad..9f77bd487f 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -76,6 +76,7 @@
#include "about_dialog.h"
#include "bluetooth_att_server_attributes_dialog.h"
#include "bluetooth_devices_dialog.h"
+#include "bluetooth_hci_summary_dialog.h"
#include "capture_file_dialog.h"
#include "capture_file_properties_dialog.h"
#include "color_utils.h"
@@ -2959,6 +2960,16 @@ void MainWindow::on_actionDevices_triggered()
bluetooth_devices_dialog->show();
}
+void MainWindow::on_actionHCI_Summary_triggered()
+{
+ BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
+ connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
+ packet_list_, SLOT(goToPacket(int)));
+ connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString&, bool)),
+ this, SLOT(filterPackets(QString&, bool)));
+ bluetooth_hci_summary_dialog->show();
+}
+
// Help Menu
void MainWindow::on_actionHelpContents_triggered() {