Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / qt / bluetooth_hci_summary_dialog.cpp
bloba86bf461624d360b61f9a57878cf752472e816b3
1 /* bluetooth_hci_summary_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include "bluetooth_hci_summary_dialog.h"
11 #include <ui_bluetooth_hci_summary_dialog.h>
13 #include "bluetooth_device_dialog.h"
15 #include <ui/qt/utils/color_utils.h>
17 #include "epan/epan.h"
18 #include "epan/addr_resolv.h"
19 #include "epan/to_str.h"
20 #include "epan/epan_dissect.h"
21 #include "epan/prefs.h"
22 #include "epan/dissectors/packet-bluetooth.h"
23 #include "epan/dissectors/packet-bthci_cmd.h"
24 #include "epan/dissectors/packet-bthci_evt.h"
26 #include <ui/qt/utils/variant_pointer.h>
28 #include "ui/simple_dialog.h"
29 #include "ui/qt/widgets/wireshark_file_dialog.h"
31 #include <QClipboard>
32 #include <QContextMenuEvent>
33 #include <QPushButton>
34 #include <QTreeWidget>
36 static const int column_number_name = 0;
37 static const int column_number_ogf = 1;
38 static const int column_number_ocf = 2;
39 static const int column_number_opcode = 3;
40 static const int column_number_event = 4;
41 static const int column_number_subevent = 5;
42 static const int column_number_status = 6;
43 static const int column_number_reason = 7;
44 static const int column_number_hardware_error = 8;
45 static const int column_number_occurrence = 9;
47 static tap_packet_status
48 bluetooth_hci_summary_tap_packet(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *edt, const void* data, tap_flags_t flags)
50 bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
52 if (tapinfo->tap_packet)
53 tapinfo->tap_packet(tapinfo, pinfo, edt, data, flags);
55 return TAP_PACKET_REDRAW;
58 static void
59 bluetooth_hci_summary_tap_reset(void *tapinfo_ptr)
61 bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
63 if (tapinfo->tap_reset)
64 tapinfo->tap_reset(tapinfo);
67 static void
68 bluetooth_hci_summary_tap_init(void *data)
70 GString *error_string;
72 error_string = register_tap_listener("bluetooth.hci_summary", data, NULL,
74 bluetooth_hci_summary_tap_reset,
75 bluetooth_hci_summary_tap_packet,
76 NULL,
77 NULL
80 if (error_string != NULL) {
81 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
82 "%s", error_string->str);
83 g_string_free(error_string, TRUE);
88 BluetoothHciSummaryDialog::BluetoothHciSummaryDialog(QWidget &parent, CaptureFile &cf) :
89 WiresharkDialog(parent, cf),
90 ui(new Ui::BluetoothHciSummaryDialog)
92 ui->setupUi(this);
93 loadGeometry(parent.width() * 4 / 5, parent.height() * 2 / 3);
95 connect(ui->tableTreeWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(tableContextMenu(const QPoint &)));
96 connect(ui->tableTreeWidget, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(tableItemExpanded(QTreeWidgetItem *)));
97 connect(ui->tableTreeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(tableItemCollapsed(QTreeWidgetItem *)));
99 connect(ui->interfaceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(interfaceCurrentIndexChanged(int)));
100 connect(ui->adapterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(adapterCurrentIndexChanged(int)));
101 connect(ui->displayFilterLineEdit, SIGNAL(returnPressed()), this, SLOT(displayFilterLineEditAccepted()));
102 connect(ui->resultsFilterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(resultsFilterLineEditChanged(const QString &)));
104 for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
105 ui->tableTreeWidget->resizeColumnToContents(i);
108 ui->tableTreeWidget->setStyleSheet("QTreeView::item:hover{background-color:lightyellow; color:black;}");
110 context_menu_.addActions(QList<QAction *>() << ui->actionMark_Unmark_Cell);
111 context_menu_.addActions(QList<QAction *>() << ui->actionMark_Unmark_Row);
112 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Cell);
113 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Rows);
114 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_All);
115 context_menu_.addActions(QList<QAction *>() << ui->actionSave_as_image);
117 tapinfo_.tap_packet = tapPacket;
118 tapinfo_.tap_reset = tapReset;
119 tapinfo_.ui = this;
121 item_link_control_ = ui->tableTreeWidget->topLevelItem(0);
122 item_link_policy_ = ui->tableTreeWidget->topLevelItem(1);
123 item_controller_and_baseband_ = ui->tableTreeWidget->topLevelItem(2);
124 item_informational_ = ui->tableTreeWidget->topLevelItem(3);
125 item_status_parameters_ = ui->tableTreeWidget->topLevelItem(4);
126 item_testing_ = ui->tableTreeWidget->topLevelItem(5);
127 item_low_energy_ = ui->tableTreeWidget->topLevelItem(6);
128 item_logo_testing_ = ui->tableTreeWidget->topLevelItem(7);
129 item_vendor_ = ui->tableTreeWidget->topLevelItem(8);
130 item_unknown_ogf_ = ui->tableTreeWidget->topLevelItem(9);
131 item_events_ = ui->tableTreeWidget->topLevelItem(10);
132 item_status_ = ui->tableTreeWidget->topLevelItem(11);
133 item_reason_ = ui->tableTreeWidget->topLevelItem(12);
134 item_hardware_errors_ = ui->tableTreeWidget->topLevelItem(13);
136 bluetooth_hci_summary_tap_init(&tapinfo_);
138 cap_file_.retapPackets();
142 BluetoothHciSummaryDialog::~BluetoothHciSummaryDialog()
144 delete ui;
146 remove_tap_listener(&tapinfo_);
150 void BluetoothHciSummaryDialog::captureFileClosing()
152 remove_tap_listener(&tapinfo_);
154 WiresharkDialog::captureFileClosing();
158 void BluetoothHciSummaryDialog::captureFileClosed()
160 ui->interfaceComboBox->setEnabled(false);
161 ui->adapterComboBox->setEnabled(false);
163 WiresharkDialog::captureFileClosed();
167 void BluetoothHciSummaryDialog::changeEvent(QEvent *event)
169 if (0 != event)
171 switch (event->type())
173 case QEvent::LanguageChange:
174 ui->retranslateUi(this);
175 break;
176 default:
177 break;
180 QDialog::changeEvent(event);
184 void BluetoothHciSummaryDialog::keyPressEvent(QKeyEvent *event)
186 /* NOTE: Do nothing*, but in real it "takes focus" from button_box so allow user
187 * to use Enter button to jump to frame from tree widget */
188 /* * - reimplement shortcuts from context menu */
190 if (event->modifiers() & Qt::ControlModifier && event->key()== Qt::Key_M)
191 on_actionMark_Unmark_Row_triggered();
195 void BluetoothHciSummaryDialog::tableContextMenu(const QPoint &pos)
197 context_menu_.popup(ui->tableTreeWidget->viewport()->mapToGlobal(pos));
200 void BluetoothHciSummaryDialog::tableItemExpanded(QTreeWidgetItem *)
202 for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
203 ui->tableTreeWidget->resizeColumnToContents(i);
207 void BluetoothHciSummaryDialog::tableItemCollapsed(QTreeWidgetItem *)
209 for (int i = 0; i < ui->tableTreeWidget->columnCount(); i++) {
210 ui->tableTreeWidget->resizeColumnToContents(i);
214 void BluetoothHciSummaryDialog::on_actionMark_Unmark_Cell_triggered()
216 QBrush fg;
217 QBrush bg;
219 if (ui->tableTreeWidget->currentItem()->background(ui->tableTreeWidget->currentColumn()) == QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg))) {
220 fg = QBrush();
221 bg = QBrush();
222 } else {
223 fg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_fg));
224 bg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg));
227 ui->tableTreeWidget->currentItem()->setForeground(ui->tableTreeWidget->currentColumn(), fg);
228 ui->tableTreeWidget->currentItem()->setBackground(ui->tableTreeWidget->currentColumn(), bg);
231 void BluetoothHciSummaryDialog::on_actionMark_Unmark_Row_triggered()
233 QBrush fg;
234 QBrush bg;
235 bool is_marked = true;
237 for (int i = 0; i < ui->tableTreeWidget->columnCount(); i += 1) {
238 if (ui->tableTreeWidget->currentItem()->background(i) != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
239 is_marked = false;
242 if (is_marked) {
243 fg = QBrush();
244 bg = QBrush();
245 } else {
246 fg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_fg));
247 bg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg));
250 for (int i = 0; i < ui->tableTreeWidget->columnCount(); i += 1) {
251 ui->tableTreeWidget->currentItem()->setForeground(i, fg);
252 ui->tableTreeWidget->currentItem()->setBackground(i, bg);
256 void BluetoothHciSummaryDialog::on_actionCopy_Cell_triggered()
258 QClipboard *clipboard = QApplication::clipboard();
259 QString copy;
261 copy = QString(ui->tableTreeWidget->currentItem()->text(ui->tableTreeWidget->currentColumn()));
263 clipboard->setText(copy);
267 void BluetoothHciSummaryDialog::on_actionCopy_Rows_triggered()
269 QClipboard *clipboard = QApplication::clipboard();
270 QString copy;
271 QList<QTreeWidgetItem *> items;
272 QList<QTreeWidgetItem *>::iterator i_item;
274 items = ui->tableTreeWidget->selectedItems();
276 for (i_item = items.begin(); i_item != items.end(); ++i_item) {
277 copy += QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9\n")
278 .arg((*i_item)->text(column_number_name), -60)
279 .arg((*i_item)->text(column_number_ogf), -10)
280 .arg((*i_item)->text(column_number_ocf), -10)
281 .arg((*i_item)->text(column_number_opcode), -10)
282 .arg((*i_item)->text(column_number_event), -10)
283 .arg((*i_item)->text(column_number_subevent), -10)
284 .arg((*i_item)->text(column_number_status), -10)
285 .arg((*i_item)->text(column_number_reason), -10)
286 .arg((*i_item)->text(column_number_hardware_error), -15)
287 .arg((*i_item)->text(column_number_occurrence), -10);
290 clipboard->setText(copy);
293 void BluetoothHciSummaryDialog::tapReset(void *tapinfo_ptr)
295 bluetooth_hci_summary_tapinfo_t *tapinfo = (bluetooth_hci_summary_tapinfo_t *) tapinfo_ptr;
296 BluetoothHciSummaryDialog *dialog = static_cast<BluetoothHciSummaryDialog *>(tapinfo->ui);
298 dialog->item_link_control_->takeChildren();
299 dialog->item_link_control_->setText(column_number_occurrence, "0");
301 dialog->item_link_policy_->takeChildren();
302 dialog->item_link_policy_->setText(column_number_occurrence, "0");
304 dialog->item_controller_and_baseband_->takeChildren();
305 dialog->item_controller_and_baseband_->setText(column_number_occurrence, "0");
307 dialog->item_informational_->takeChildren();
308 dialog->item_informational_->setText(column_number_occurrence, "0");
310 dialog->item_status_parameters_->takeChildren();
311 dialog->item_status_parameters_->setText(column_number_occurrence, "0");
313 dialog->item_testing_->takeChildren();
314 dialog->item_testing_->setText(column_number_occurrence, "0");
316 dialog->item_low_energy_->takeChildren();
317 dialog->item_low_energy_->setText(column_number_occurrence, "0");
319 dialog->item_logo_testing_->takeChildren();
320 dialog->item_logo_testing_->setText(column_number_occurrence, "0");
322 dialog->item_vendor_->takeChildren();
323 dialog->item_vendor_->setText(column_number_occurrence, "0");
325 dialog->item_unknown_ogf_->takeChildren();
326 dialog->item_unknown_ogf_->setText(column_number_occurrence, "0");
328 dialog->item_events_->takeChildren();
329 dialog->item_events_->setText(column_number_occurrence, "0");
331 dialog->item_status_->takeChildren();
332 dialog->item_status_->setText(column_number_occurrence, "0");
334 dialog->item_reason_->takeChildren();
335 dialog->item_reason_->setText(column_number_occurrence, "0");
337 dialog->item_hardware_errors_->takeChildren();
338 dialog->item_hardware_errors_->setText(column_number_occurrence, "0");
341 tap_packet_status BluetoothHciSummaryDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data, tap_flags_t)
343 bluetooth_hci_summary_tapinfo_t *tapinfo = static_cast<bluetooth_hci_summary_tapinfo_t *>(tapinfo_ptr);
344 BluetoothHciSummaryDialog *dialog = static_cast<BluetoothHciSummaryDialog *>(tapinfo->ui);
345 bluetooth_hci_summary_tap_t *tap_hci = static_cast<bluetooth_hci_summary_tap_t *>(const_cast<void *>(data));
346 QTreeWidgetItem *main_item = NULL;
347 QTreeWidgetItem *item = NULL;
348 QTreeWidgetItem *frame_item = NULL;
349 QTreeWidgetItem *meta_item = NULL;
350 bluetooth_item_data_t *item_data = NULL;
351 QString adapter;
352 QString name;
354 if (dialog->file_closed_)
355 return TAP_PACKET_DONT_REDRAW;
357 if (pinfo->rec->rec_type != REC_TYPE_PACKET)
358 return TAP_PACKET_DONT_REDRAW;
360 name = tr("Unknown");
362 if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
363 char *interface;
364 const char *interface_name;
366 unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
367 interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
368 interface = wmem_strdup_printf(pinfo->pool, "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name);
370 if (dialog->ui->interfaceComboBox->findText(interface) == -1)
371 dialog->ui->interfaceComboBox->addItem(interface);
373 if (interface && dialog->ui->interfaceComboBox->currentIndex() > 0) {
374 if (dialog->ui->interfaceComboBox->currentText() != interface)
375 return TAP_PACKET_REDRAW;
379 adapter = tr("Adapter %1").arg(tap_hci->adapter_id);
381 if (dialog->ui->adapterComboBox->findText(adapter) == -1) {
382 dialog->ui->adapterComboBox->addItem(adapter);
385 if (dialog->ui->adapterComboBox->currentIndex() > 0) {
386 if (dialog->ui->adapterComboBox->currentText() != adapter)
387 return TAP_PACKET_REDRAW;
390 switch (tap_hci->type) {
391 case BLUETOOTH_HCI_SUMMARY_OPCODE:
392 case BLUETOOTH_HCI_SUMMARY_EVENT_OPCODE:
393 case BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE:
394 case BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE:
395 switch (tap_hci->ogf) {
396 case HCI_OGF_LINK_CONTROL:
397 main_item = dialog->item_link_control_;
398 break;
399 case HCI_OGF_LINK_POLICY:
400 main_item = dialog->item_link_policy_;
401 break;
402 case HCI_OGF_HOST_CONTROLLER:
403 main_item = dialog->item_controller_and_baseband_;
404 break;
405 case HCI_OGF_INFORMATIONAL:
406 main_item = dialog->item_informational_;
407 break;
408 case HCI_OGF_STATUS:
409 main_item = dialog->item_status_parameters_;
410 break;
411 case HCI_OGF_TESTING:
412 main_item = dialog->item_testing_;
413 break;
414 case HCI_OGF_LOW_ENERGY:
415 main_item = dialog->item_low_energy_;
416 break;
417 case HCI_OGF_LOGO_TESTING:
418 main_item = dialog->item_logo_testing_;
419 break;
420 case HCI_OGF_VENDOR_SPECIFIC:
421 main_item = dialog->item_vendor_;
422 break;
423 default:
424 main_item = dialog->item_unknown_ogf_;
427 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
428 if (main_item->child(i_item)->text(column_number_opcode) ==
429 QStringLiteral("0x%1").arg(tap_hci->ogf << 10 | tap_hci->ocf, 4, 16, QChar('0'))) {
430 item = main_item->child(i_item);
431 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE && tap_hci->name) {
432 item->setText(column_number_name, tap_hci->name);
433 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() - 1));
435 break;
439 if (!item) {
440 item = new QTreeWidgetItem();
441 if (tap_hci->name)
442 name = tap_hci->name;
444 item->setText(column_number_name, name);
445 item->setText(column_number_ogf, QStringLiteral("0x%1").arg(tap_hci->ogf, 2, 16, QChar('0')));
446 item->setText(column_number_ocf, QStringLiteral("0x%1").arg(tap_hci->ocf, 4, 16, QChar('0')));
447 item->setText(column_number_opcode,
448 QStringLiteral("0x%1").arg(tap_hci->ogf << 10 | tap_hci->ocf, 4, 16, QChar('0')));
449 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_OPCODE)
450 item->setText(column_number_occurrence, "0");
451 else
452 item->setText(column_number_occurrence, "1");
454 main_item->addChild(item);
455 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
456 main_item->sortChildren(column_number_opcode, Qt::AscendingOrder);
458 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
461 if (tap_hci->type != BLUETOOTH_HCI_SUMMARY_EVENT_OPCODE && tap_hci->type != BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE)
462 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
464 /* I believe bthci_cmd/bthci_evt already add frame item */
465 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_OPCODE ||
466 tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT_OPCODE)
467 break;
469 frame_item = new QTreeWidgetItem();
470 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
471 frame_item->setText(column_number_ogf, QStringLiteral("0x%1").arg(tap_hci->ogf, 2, 16, QChar('0')));
472 frame_item->setText(column_number_ocf, QStringLiteral("0x%1").arg(tap_hci->ocf, 4, 16, QChar('0')));
473 frame_item->setText(column_number_opcode, QStringLiteral("0x%1")
474 .arg(tap_hci->ogf << 10 | tap_hci->ocf, 4, 16, QChar('0')));
475 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_EVENT_OPCODE)
476 frame_item->setText(column_number_event, QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0')));
477 item->addChild(frame_item);
479 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
480 item_data->interface_id = tap_hci->interface_id;
481 item_data->adapter_id = tap_hci->adapter_id;
482 item_data->frame_number = pinfo->num;
483 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
485 break;
486 case BLUETOOTH_HCI_SUMMARY_EVENT:
487 case BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT:
488 main_item = dialog->item_events_;
490 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
491 if (main_item->child(i_item)->text(column_number_event) ==
492 QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0'))) {
493 item = main_item->child(i_item);
494 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT && tap_hci->name)
495 item->setText(column_number_name, tap_hci->name);
496 break;
500 if (!item) {
501 item = new QTreeWidgetItem();
502 if (tap_hci->name)
503 name = tap_hci->name;
505 item->setText(column_number_name, name);
506 item->setText(column_number_event, QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0')));
507 item->setText(column_number_occurrence, QString::number(0));
509 main_item->addChild(item);
510 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
511 main_item->sortChildren(column_number_event, Qt::AscendingOrder);
512 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
515 /* I believe bthci_cmd/bthci_evt already add frame item */
516 if (tap_hci->type == BLUETOOTH_HCI_SUMMARY_VENDOR_EVENT)
517 break;
519 if (tap_hci->event == 0x3E) { /* LE Meta */
520 int i_item;
521 for (i_item = 0; i_item < item->childCount(); i_item +=1) {
522 if (item->child(i_item)->text(column_number_name) != tr("Unknown"))
523 continue;
526 if (i_item >= item->childCount()) {
527 frame_item = new QTreeWidgetItem();
528 frame_item->setText(column_number_name, tr("Unknown"));
529 frame_item->setText(column_number_occurrence, QString::number(1));
530 item->addChild(frame_item);
531 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
533 item = frame_item;
534 } else {
535 item = item->child(i_item);
536 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
538 } else {
539 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
542 frame_item = new QTreeWidgetItem();
543 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
544 frame_item->setText(column_number_event, QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0')));
545 item->addChild(frame_item);
547 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
548 item_data->interface_id = tap_hci->interface_id;
549 item_data->adapter_id = tap_hci->adapter_id;
550 item_data->frame_number = pinfo->num;
551 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
553 break;
554 case BLUETOOTH_HCI_SUMMARY_SUBEVENT:
555 main_item = dialog->item_events_;
557 meta_item = NULL;
559 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
560 if (main_item->child(i_item)->text(column_number_event) !=
561 QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0'))) {
562 continue;
565 meta_item = main_item->child(i_item);
566 break;
569 if (meta_item == NULL)
570 break;
572 item = NULL;
574 for (int i_item = 0; i_item < meta_item->childCount(); i_item +=1) {
575 if (meta_item->child(i_item)->text(column_number_subevent) !=
576 QStringLiteral("0x%1").arg(tap_hci->subevent, 2, 16, QChar('0'))) {
577 continue;
580 item = meta_item->child(i_item);
581 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
583 break;
586 if (item == NULL) {
587 item = new QTreeWidgetItem();
588 item->setText(column_number_name, tap_hci->name);
589 item->setText(column_number_subevent, QStringLiteral("0x%1").arg(tap_hci->subevent, 2, 16, QChar('0')));
590 item->setText(column_number_occurrence, QString::number(1));
592 meta_item->addChild(item);
593 meta_item->setText(column_number_occurrence, QString::number(meta_item->text(column_number_occurrence).toInt() + 1));
594 meta_item->sortChildren(column_number_subevent, Qt::AscendingOrder);
597 frame_item = new QTreeWidgetItem();
598 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
599 frame_item->setText(column_number_event, QStringLiteral("0x%1").arg(tap_hci->event, 2, 16, QChar('0')));
600 frame_item->setText(column_number_subevent, QStringLiteral("0x%1").arg(tap_hci->subevent, 2, 16, QChar('0')));
602 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
603 item_data->interface_id = tap_hci->interface_id;
604 item_data->adapter_id = tap_hci->adapter_id;
605 item_data->frame_number = pinfo->num;
607 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
609 item->addChild(frame_item);
611 /* Remove item that is known now */
612 for (int i_item = 0; i_item < meta_item->childCount(); i_item +=1) {
613 if (meta_item->child(i_item)->text(column_number_name) != tr("Unknown"))
614 continue;
616 item = meta_item->child(i_item);
617 for (int ii_item = 0; ii_item < item->childCount(); ii_item +=1) {
618 if (item->child(ii_item)->text(column_number_name) != tr("Frame %1").arg(pinfo->num))
619 continue;
621 delete item->child(ii_item);
622 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() - 1));
623 if (item->childCount() == 0) {
624 delete item;
625 meta_item->setText(column_number_occurrence, QString::number(meta_item->text(column_number_occurrence).toInt() - 1));
628 break;
630 break;
633 break;
634 case BLUETOOTH_HCI_SUMMARY_STATUS:
635 main_item = dialog->item_status_;
637 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
638 if (main_item->child(i_item)->text(column_number_status) ==
639 QStringLiteral("0x%1").arg(tap_hci->status, 2, 16, QChar('0'))) {
640 item = main_item->child(i_item);
641 break;
645 if (!item) {
646 if (tap_hci->name)
647 name = tap_hci->name;
649 item = new QTreeWidgetItem();
650 item->setText(column_number_name, name);
651 item->setText(column_number_status, QStringLiteral("0x%1").arg(tap_hci->status, 2, 16, QChar('0')));
653 main_item->addChild(item);
654 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
655 main_item->sortChildren(column_number_event, Qt::AscendingOrder);
656 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
659 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
661 frame_item = new QTreeWidgetItem();
662 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
663 frame_item->setText(column_number_status, QStringLiteral("0x%1").arg(tap_hci->status, 2, 16, QChar('0')));
664 item->addChild(frame_item);
666 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
667 item_data->interface_id = tap_hci->interface_id;
668 item_data->adapter_id = tap_hci->adapter_id;
669 item_data->frame_number = pinfo->num;
670 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
672 break;
673 case BLUETOOTH_HCI_SUMMARY_STATUS_PENDING:
674 main_item = dialog->item_status_;
676 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
677 if (main_item->child(i_item)->text(column_number_status) == QString::number(tap_hci->status)) {
678 item = main_item->child(i_item);
679 break;
683 if (!item) {
684 item = new QTreeWidgetItem();
685 item->setText(column_number_name, tr("Pending"));
686 item->setText(column_number_status, QString::number(tap_hci->status));
688 main_item->addChild(item);
689 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
690 main_item->sortChildren(column_number_event, Qt::AscendingOrder);
691 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
694 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
696 frame_item = new QTreeWidgetItem();
697 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
698 frame_item->setText(column_number_status, QString::number(tap_hci->status));
699 item->addChild(frame_item);
701 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
702 item_data->interface_id = tap_hci->interface_id;
703 item_data->adapter_id = tap_hci->adapter_id;
704 item_data->frame_number = pinfo->num;
705 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
707 break;
708 case BLUETOOTH_HCI_SUMMARY_REASON:
709 main_item = dialog->item_reason_;
711 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
712 if (main_item->child(i_item)->text(column_number_reason) ==
713 QStringLiteral("0x%1").arg(tap_hci->reason, 2, 16, QChar('0'))) {
714 item = main_item->child(i_item);
715 break;
719 if (!item) {
720 if (tap_hci->name)
721 name = tap_hci->name;
723 item = new QTreeWidgetItem();
724 item->setText(column_number_name, name);
725 item->setText(column_number_reason, QStringLiteral("0x%1").arg(tap_hci->reason, 2, 16, QChar('0')));
727 main_item->addChild(item);
728 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
729 main_item->sortChildren(column_number_event, Qt::AscendingOrder);
730 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
733 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
735 frame_item = new QTreeWidgetItem();
736 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
737 frame_item->setText(column_number_reason, QStringLiteral("0x%1").arg(tap_hci->reason, 2, 16, QChar('0')));
738 item->addChild(frame_item);
740 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
741 item_data->interface_id = tap_hci->interface_id;
742 item_data->adapter_id = tap_hci->adapter_id;
743 item_data->frame_number = pinfo->num;
744 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
746 break;
747 case BLUETOOTH_HCI_SUMMARY_HARDWARE_ERROR:
748 main_item = dialog->item_hardware_errors_;
750 for (int i_item = 0; i_item < main_item->childCount(); i_item +=1) {
751 if (main_item->child(i_item)->text(column_number_hardware_error) ==
752 QStringLiteral("0x%1").arg(tap_hci->hardware_error, 2, 16, QChar('0'))) {
753 item = main_item->child(i_item);
754 break;
758 if (!item) {
759 item = new QTreeWidgetItem();
760 const QString error = QStringLiteral("0x%1").arg(tap_hci->hardware_error, 2, 16, QChar('0'));
761 item->setText(column_number_name, QStringLiteral("Hardware error %1").arg(error));
762 item->setText(column_number_hardware_error, error);
764 main_item->addChild(item);
765 item->setHidden(!name.contains(dialog->ui->resultsFilterLineEdit->text(), Qt::CaseInsensitive));
766 main_item->sortChildren(column_number_event, Qt::AscendingOrder);
767 main_item->setText(column_number_occurrence, QString::number(main_item->text(column_number_occurrence).toInt() + 1));
770 item->setText(column_number_occurrence, QString::number(item->text(column_number_occurrence).toInt() + 1));
772 frame_item = new QTreeWidgetItem();
773 frame_item->setText(column_number_name, tr("Frame %1").arg(pinfo->num));
774 frame_item->setText(column_number_hardware_error, QStringLiteral("0x%1").arg(tap_hci->hardware_error, 2, 16, QChar('0')));
775 item->addChild(frame_item);
777 item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
778 item_data->interface_id = tap_hci->interface_id;
779 item_data->adapter_id = tap_hci->adapter_id;
780 item_data->frame_number = pinfo->num;
781 frame_item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
783 break;
786 for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) {
787 dialog->ui->tableTreeWidget->resizeColumnToContents(i);
790 return TAP_PACKET_REDRAW;
793 void BluetoothHciSummaryDialog::interfaceCurrentIndexChanged(int)
795 cap_file_.retapPackets();
798 void BluetoothHciSummaryDialog::adapterCurrentIndexChanged(int)
800 cap_file_.retapPackets();
803 void BluetoothHciSummaryDialog::on_tableTreeWidget_itemActivated(QTreeWidgetItem *item, int)
805 if (file_closed_)
806 return;
808 bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(item->data(0, Qt::UserRole));
810 if (item_data)
811 emit goToPacket(item_data->frame_number);
815 void BluetoothHciSummaryDialog::recursiveCopyTreeItems(QTreeWidgetItem *item, QString &copy, int ident_level)
817 QTreeWidgetItem *child_item;
819 if (!item->isExpanded()) return;
821 for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
822 child_item = item->child(i_item);
824 copy.append(QStringLiteral(" ").repeated(ident_level));
825 copy += QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9\n")
826 .arg(child_item->text(column_number_name), -60 + 4 * ident_level)
827 .arg(child_item->text(column_number_ogf), -10)
828 .arg(child_item->text(column_number_ocf), -10)
829 .arg(child_item->text(column_number_opcode), -10)
830 .arg(child_item->text(column_number_event), -10)
831 .arg(child_item->text(column_number_subevent), -10)
832 .arg(child_item->text(column_number_status), -10)
833 .arg(child_item->text(column_number_reason), -10)
834 .arg(child_item->text(column_number_hardware_error), -15)
835 .arg(child_item->text(column_number_occurrence), -10);
837 recursiveCopyTreeItems(child_item, copy, ident_level + 1);
841 void BluetoothHciSummaryDialog::on_actionCopy_All_triggered()
843 QClipboard *clipboard = QApplication::clipboard();
844 QString copy;
845 QTreeWidgetItem *item;
847 item = ui->tableTreeWidget->headerItem();
849 copy += QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10\n")
850 .arg(item->text(column_number_name), -60)
851 .arg(item->text(column_number_ogf), -10)
852 .arg(item->text(column_number_ocf), -10)
853 .arg(item->text(column_number_opcode), -10)
854 .arg(item->text(column_number_event), -10)
855 .arg(item->text(column_number_subevent), -10)
856 .arg(item->text(column_number_status), -10)
857 .arg(item->text(column_number_reason), -10)
858 .arg(item->text(column_number_hardware_error), -15)
859 .arg(item->text(column_number_occurrence), -10);
861 for (int i_item = 0; i_item < ui->tableTreeWidget->topLevelItemCount(); ++i_item) {
862 item = ui->tableTreeWidget->topLevelItem(i_item);
864 copy += QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10\n")
865 .arg(item->text(column_number_name), -60)
866 .arg(item->text(column_number_ogf), -10)
867 .arg(item->text(column_number_ocf), -10)
868 .arg(item->text(column_number_opcode), -10)
869 .arg(item->text(column_number_event), -10)
870 .arg(item->text(column_number_subevent), -10)
871 .arg(item->text(column_number_status), -10)
872 .arg(item->text(column_number_reason), -10)
873 .arg(item->text(column_number_hardware_error), -15)
874 .arg(item->text(column_number_occurrence), -10);
876 recursiveCopyTreeItems(ui->tableTreeWidget->topLevelItem(i_item), copy, 1);
879 clipboard->setText(copy);
882 void BluetoothHciSummaryDialog::on_actionSave_as_image_triggered()
884 QPixmap image;
886 QString fileName = WiresharkFileDialog::getSaveFileName(this,
887 tr("Save Table Image"),
888 "bluetooth_hci_summary.png",
889 tr("PNG Image (*.png)"));
891 if (fileName.isEmpty()) return;
893 image = ui->tableTreeWidget->grab();
894 image.save(fileName, "PNG");
897 void BluetoothHciSummaryDialog::on_buttonBox_clicked(QAbstractButton *)
899 /* if (button == foo_button_) */
902 void BluetoothHciSummaryDialog::displayFilterLineEditAccepted()
904 GString *error_string;
906 remove_tap_listener(&tapinfo_);
907 error_string = register_tap_listener("bluetooth.hci_summary", &tapinfo_,
908 ui->displayFilterLineEdit->text().toUtf8().constData(),
910 bluetooth_hci_summary_tap_reset,
911 bluetooth_hci_summary_tap_packet,
912 NULL,
913 NULL
916 if (error_string != NULL) {
917 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
918 "%s", error_string->str);
919 g_string_free(error_string, TRUE);
922 cap_file_.retapPackets();
925 void BluetoothHciSummaryDialog::resultsFilterLineEditChanged(const QString &text)
927 for (int i_item = 0; i_item < ui->tableTreeWidget->topLevelItemCount(); ++i_item) {
928 QTreeWidgetItem *item = ui->tableTreeWidget->topLevelItem(i_item);
930 for (int i_child = 0; i_child < item->childCount(); i_child += 1) {
931 QTreeWidgetItem *child_item = item->child(i_child);
932 QString name = child_item->text(column_number_name);
933 child_item->setHidden(!name.contains(text, Qt::CaseInsensitive));