diff options
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/CMakeLists.txt | 3 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 4 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 3 | ||||
-rw-r--r-- | ui/qt/bluetooth_hci_summary_dialog.cpp | 727 | ||||
-rw-r--r-- | ui/qt/bluetooth_hci_summary_dialog.h | 124 | ||||
-rw-r--r-- | ui/qt/bluetooth_hci_summary_dialog.ui | 661 | ||||
-rw-r--r-- | ui/qt/main_window.h | 1 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 6 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 11 |
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 ©, 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 ©, 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 & 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 &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() { |