1 /* bluetooth_device_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
10 #include "bluetooth_device_dialog.h"
11 #include <ui_bluetooth_device_dialog.h>
13 #include <ui/qt/utils/color_utils.h>
15 #include "epan/epan.h"
16 #include "epan/addr_resolv.h"
17 #include "epan/to_str.h"
18 #include "epan/epan_dissect.h"
19 #include "epan/prefs.h"
20 #include "epan/dissectors/packet-bthci_cmd.h"
21 #include "epan/dissectors/packet-bthci_evt.h"
23 #include "ui/simple_dialog.h"
25 #include <ui/qt/utils/variant_pointer.h>
26 #include "ui/qt/widgets/wireshark_file_dialog.h"
29 #include <QContextMenuEvent>
30 #include <QPushButton>
31 #include <QTreeWidget>
33 static const int column_number_value
= 0;
34 static const int column_number_changes
= 1;
36 static const int row_number_bd_addr
= 0;
37 static const int row_number_bd_addr_oui
= 1;
38 static const int row_number_name
= 2;
39 static const int row_number_class_of_device
= 3;
40 static const int row_number_lmp_version
= 4;
41 static const int row_number_lmp_subversion
= 5;
42 static const int row_number_manufacturer
= 6;
43 static const int row_number_hci_version
= 7;
44 static const int row_number_hci_revision
= 8;
45 static const int row_number_scan
= 9;
46 static const int row_number_authentication
= 10;
47 static const int row_number_encryption
= 11;
48 static const int row_number_acl_mtu
= 12;
49 static const int row_number_acl_packets
= 13;
50 static const int row_number_sco_mtu
= 14;
51 static const int row_number_sco_packets
= 15;
52 static const int row_number_le_acl_mtu
= 16;
53 static const int row_number_le_acl_packets
= 17;
54 static const int row_number_le_iso_mtu
= 18;
55 static const int row_number_le_iso_packets
= 19;
56 static const int row_number_inquiry_mode
= 20;
57 static const int row_number_page_timeout
= 21;
58 static const int row_number_simple_pairing_mode
= 22;
59 static const int row_number_voice_setting
= 23;
61 static tap_packet_status
62 bluetooth_device_tap_packet(void *tapinfo_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void* data
, tap_flags_t flags
)
64 bluetooth_device_tapinfo_t
*tapinfo
= (bluetooth_device_tapinfo_t
*) tapinfo_ptr
;
66 if (tapinfo
->tap_packet
)
67 tapinfo
->tap_packet(tapinfo
, pinfo
, edt
, data
, flags
);
69 return TAP_PACKET_REDRAW
;
73 bluetooth_device_tap_reset(void *tapinfo_ptr
)
75 bluetooth_device_tapinfo_t
*tapinfo
= (bluetooth_device_tapinfo_t
*) tapinfo_ptr
;
77 if (tapinfo
->tap_reset
)
78 tapinfo
->tap_reset(tapinfo
);
83 bluetooth_devices_tap(void *data
)
85 GString
*error_string
;
87 error_string
= register_tap_listener("bluetooth.device", data
, NULL
,
89 bluetooth_device_tap_reset
,
90 bluetooth_device_tap_packet
,
95 if (error_string
!= NULL
) {
96 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
97 "%s", error_string
->str
);
98 g_string_free(error_string
, TRUE
);
103 BluetoothDeviceDialog::BluetoothDeviceDialog(QWidget
&parent
, CaptureFile
&cf
, QString bdAddr
, QString name
, uint32_t interface_id
, uint32_t adapter_id
, bool is_local
) :
104 WiresharkDialog(parent
, cf
),
105 ui(new Ui::BluetoothDeviceDialog
)
108 resize(parent
.width() * 4 / 10, parent
.height() * 2 / 2);
110 setTitle(bdAddr
, name
);
112 connect(ui
->tableWidget
, &QTableWidget::customContextMenuRequested
, this, &BluetoothDeviceDialog::tableContextMenu
);
114 ui
->tableWidget
->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch
);
116 ui
->tableWidget
->setStyleSheet("QTableView::item:hover{background-color:lightyellow; color:black;}");
118 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionMark_Unmark_Cell
);
119 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionMark_Unmark_Row
);
120 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionCopy_Cell
);
121 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionCopy_Rows
);
122 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionCopy_All
);
123 context_menu_
.addActions(QList
<QAction
*>() << ui
->actionSave_as_image
);
127 tapinfo_
.tap_packet
= tapPacket
;
128 tapinfo_
.tap_reset
= tapReset
;
130 tapinfo_
.is_local
= is_local
;
131 tapinfo_
.bdAddr
= bdAddr
;
132 tapinfo_
.interface_id
= interface_id
;
133 tapinfo_
.adapter_id
= adapter_id
;
134 tapinfo_
.changes
= &changes_
;
136 ui
->hintLabel
->setText(ui
->hintLabel
->text().arg(changes_
));
138 for (int i_row
= 0; i_row
< ui
->tableWidget
->rowCount(); i_row
+= 1) {
139 for (int i_column
= 0; i_column
< ui
->tableWidget
->columnCount(); i_column
+= 1) {
140 QTableWidgetItem
*item
= new QTableWidgetItem();
141 ui
->tableWidget
->setItem(i_row
, i_column
, item
);
145 bluetooth_devices_tap(&tapinfo_
);
147 cap_file_
.retapPackets();
151 BluetoothDeviceDialog::~BluetoothDeviceDialog()
155 remove_tap_listener(&tapinfo_
);
158 void BluetoothDeviceDialog::setTitle(QString bdAddr
, QString name
)
163 if (bdAddr
.isEmpty())
164 titleBdAddr
= tr("Unknown");
166 titleBdAddr
= bdAddr
;
171 titleName
= " ("+name
+")";
173 setWindowTitle(tr("Bluetooth Device - %1%2").arg(titleBdAddr
).arg(titleName
));
176 void BluetoothDeviceDialog::captureFileClosing()
178 remove_tap_listener(&tapinfo_
);
180 WiresharkDialog::captureFileClosing();
184 void BluetoothDeviceDialog::changeEvent(QEvent
*event
)
188 switch (event
->type())
190 case QEvent::LanguageChange
:
191 ui
->retranslateUi(this);
197 QDialog::changeEvent(event
);
201 void BluetoothDeviceDialog::keyPressEvent(QKeyEvent
*event
)
203 /* NOTE: Do nothing*, but in real it "takes focus" from button_box so allow user
204 * to use Enter button to jump to frame from tree widget */
205 /* * - reimplement shortcuts from contex menu */
207 if (event
->modifiers() & Qt::ControlModifier
&& event
->key()== Qt::Key_M
)
208 on_actionMark_Unmark_Row_triggered();
211 void BluetoothDeviceDialog::on_actionMark_Unmark_Cell_triggered()
213 QTableWidgetItem
*current_item
= ui
->tableWidget
->currentItem();
220 if (current_item
->background() == QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_bg
))) {
224 fg
= QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_fg
));
225 bg
= QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_bg
));
228 current_item
->setForeground(fg
);
229 current_item
->setBackground(bg
);
233 void BluetoothDeviceDialog::on_actionMark_Unmark_Row_triggered()
237 bool is_marked
= true;
239 QTableWidgetItem
*current_item
= ui
->tableWidget
->currentItem();
243 for (int i
= 0; i
< ui
->tableWidget
->columnCount(); i
+= 1) {
244 QTableWidgetItem
*item
= ui
->tableWidget
->item(current_item
->row(), i
);
245 if (item
->background() != QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_bg
)))
253 fg
= QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_fg
));
254 bg
= QBrush(ColorUtils::fromColorT(&prefs
.gui_marked_bg
));
257 for (int i
= 0; i
< ui
->tableWidget
->columnCount(); i
+= 1) {
258 QTableWidgetItem
*item
= ui
->tableWidget
->item(current_item
->row(), i
);
259 item
->setForeground(fg
);
260 item
->setBackground(bg
);
265 void BluetoothDeviceDialog::tableContextMenu(const QPoint
&pos
)
267 context_menu_
.popup(ui
->tableWidget
->viewport()->mapToGlobal(pos
));
270 void BluetoothDeviceDialog::on_actionCopy_Cell_triggered()
272 QTableWidgetItem
*current_item
= ui
->tableWidget
->currentItem();
276 QClipboard
*clipboard
= QApplication::clipboard();
279 copy
= QString(current_item
->text());
281 clipboard
->setText(copy
);
284 void BluetoothDeviceDialog::on_actionCopy_Rows_triggered()
286 QClipboard
*clipboard
= QApplication::clipboard();
288 QList
<QTableWidgetItem
*> items
;
289 QList
<QTableWidgetItem
*>::iterator i_item
;
291 items
= ui
->tableWidget
->selectedItems();
293 for (i_item
= items
.begin(); i_item
!= items
.end(); ++i_item
) {
294 copy
+= QStringLiteral("%1 %2 %3\n")
295 .arg(ui
->tableWidget
->verticalHeaderItem((*i_item
)->row())->text(), -40)
296 .arg(ui
->tableWidget
->item((*i_item
)->row(), column_number_value
)->text(), -50)
297 .arg(ui
->tableWidget
->item((*i_item
)->row(), column_number_changes
)->text(), -10);
300 clipboard
->setText(copy
);
303 void BluetoothDeviceDialog::on_actionCopy_All_triggered()
305 QClipboard
*clipboard
= QApplication::clipboard();
308 copy
+= QStringLiteral("%1 %2 %3\n")
310 .arg(ui
->tableWidget
->horizontalHeaderItem(column_number_value
)->text(), -50)
311 .arg(ui
->tableWidget
->horizontalHeaderItem(column_number_changes
)->text(), -10);
313 for (int i_row
= 0; i_row
< ui
->tableWidget
->rowCount(); i_row
+= 1) {
314 for (int i_column
= 0; i_column
< ui
->tableWidget
->columnCount(); i_column
+= 1) {
316 copy
+= QStringLiteral("%1 %2 %3\n")
317 .arg(ui
->tableWidget
->verticalHeaderItem(i_row
)->text(), -40)
318 .arg(ui
->tableWidget
->item(i_row
, column_number_value
)->text(), -50)
319 .arg(ui
->tableWidget
->item(i_row
, column_number_changes
)->text(), -10);
323 clipboard
->setText(copy
);
328 void BluetoothDeviceDialog::tapReset(void *tapinfo_ptr
)
330 bluetooth_device_tapinfo_t
*tapinfo
= (bluetooth_device_tapinfo_t
*) tapinfo_ptr
;
331 BluetoothDeviceDialog
*dialog
= static_cast<BluetoothDeviceDialog
*>(tapinfo
->ui
);
333 for (int i_row
= 0; i_row
< dialog
->ui
->tableWidget
->rowCount(); i_row
+= 1) {
334 for (int i_column
= 0; i_column
< dialog
->ui
->tableWidget
->columnCount(); i_column
+= 1) {
335 QTableWidgetItem
*item
= new QTableWidgetItem();
336 dialog
->ui
->tableWidget
->setItem(i_row
, i_column
, item
);
339 *tapinfo
->changes
= 0;
342 void BluetoothDeviceDialog::updateChanges(QTableWidget
*tableWidget
, QString value
, const int row
, unsigned *changes
, packet_info
*pinfo
)
344 QTableWidgetItem
*item
= tableWidget
->item(row
, column_number_value
);
345 bluetooth_item_data_t
*item_data
= VariantPointer
<bluetooth_item_data_t
>::asPtr(item
->data(Qt::UserRole
));
347 if (item
->text() == value
)
350 if (item_data
->changes
== -1) {
351 item_data
->changes
= 0;
354 item_data
->changes
+= 1;
355 item_data
->frame_number
= pinfo
->fd
->num
;
356 tableWidget
->item(row
, column_number_changes
)->setText(QString::number(item_data
->changes
));
360 void BluetoothDeviceDialog::saveItemData(QTableWidgetItem
*item
,
361 bluetooth_device_tap_t
*tap_device
, packet_info
*pinfo
)
363 if (item
->data(Qt::UserRole
).isValid())
366 bluetooth_item_data_t
*item_data
= wmem_new(wmem_file_scope(), bluetooth_item_data_t
);
367 item_data
->interface_id
= tap_device
->interface_id
;
368 item_data
->adapter_id
= tap_device
->adapter_id
;
369 item_data
->changes
= -1;
370 item_data
->frame_number
= pinfo
->fd
->num
;
371 item
->setData(Qt::UserRole
, VariantPointer
<bluetooth_item_data_t
>::asQVariant(item_data
));
375 tap_packet_status
BluetoothDeviceDialog::tapPacket(void *tapinfo_ptr
, packet_info
*pinfo
, epan_dissect_t
*, const void *data
, tap_flags_t
)
377 bluetooth_device_tapinfo_t
*tapinfo
= static_cast<bluetooth_device_tapinfo_t
*>(tapinfo_ptr
);
378 BluetoothDeviceDialog
*dialog
= static_cast<BluetoothDeviceDialog
*>(tapinfo
->ui
);
379 bluetooth_device_tap_t
*tap_device
= static_cast<bluetooth_device_tap_t
*>(const_cast<void *>(data
));
383 QTableWidget
*tableWidget
;
384 QTableWidgetItem
*item
;
387 tableWidget
= dialog
->ui
->tableWidget
;
389 if (!((!tap_device
->is_local
&& tap_device
->has_bd_addr
) || (tap_device
->is_local
&& tapinfo
->is_local
&& tap_device
->interface_id
== tapinfo
->interface_id
&& tap_device
->adapter_id
== tapinfo
->adapter_id
))) {
390 return TAP_PACKET_REDRAW
;
393 if (tap_device
->has_bd_addr
) {
394 for (int i
= 0; i
< 6; ++i
) {
395 bd_addr
+= QStringLiteral("%1:").arg(tap_device
->bd_addr
[i
], 2, 16, QChar('0'));
397 bd_addr
.chop(1); // remove extra character ":" from the end of the string
398 if (!tap_device
->is_local
&& bd_addr
!= tapinfo
->bdAddr
)
399 return TAP_PACKET_REDRAW
;
401 manuf
= get_ether_name(tap_device
->bd_addr
);
405 bd_addr_oui
= QString(manuf
);
406 pos
= static_cast<int>(bd_addr_oui
.indexOf('_'));
410 bd_addr_oui
.remove(pos
, bd_addr_oui
.size());
417 item
= tableWidget
->item(row_number_bd_addr
, column_number_value
);
418 saveItemData(item
, tap_device
, pinfo
);
419 updateChanges(tableWidget
, bd_addr
, row_number_bd_addr
, tapinfo
->changes
, pinfo
);
420 item
->setText(bd_addr
);
422 item
= tableWidget
->item(row_number_bd_addr_oui
, column_number_value
);
423 saveItemData(item
, tap_device
, pinfo
);
424 updateChanges(tableWidget
, bd_addr_oui
, row_number_bd_addr_oui
, tapinfo
->changes
, pinfo
);
425 item
->setText(bd_addr_oui
);
427 dialog
->setTitle(bd_addr
, tableWidget
->item(row_number_name
, column_number_value
)->text());
430 switch (tap_device
->type
) {
431 case BLUETOOTH_DEVICE_LOCAL_ADAPTER
:
432 case BLUETOOTH_DEVICE_BD_ADDR
:
434 case BLUETOOTH_DEVICE_NAME
:
435 item
= tableWidget
->item(row_number_name
, column_number_value
);
436 saveItemData(item
, tap_device
, pinfo
);
437 updateChanges(tableWidget
, QString(tap_device
->data
.name
), row_number_name
, tapinfo
->changes
, pinfo
);
439 item
->setText(tap_device
->data
.name
);
441 dialog
->setTitle(tableWidget
->item(row_number_bd_addr
, column_number_value
)->text(), tap_device
->data
.name
);
444 case BLUETOOTH_DEVICE_RESET
:
445 for (int i_row
= 0; i_row
< dialog
->ui
->tableWidget
->rowCount(); i_row
+= 1) {
446 bluetooth_item_data_t
*item_data
;
448 item
= dialog
->ui
->tableWidget
->item(i_row
, column_number_value
);
449 saveItemData(item
, tap_device
, pinfo
);
451 item_data
= VariantPointer
<bluetooth_item_data_t
>::asPtr(item
->data(Qt::UserRole
));
453 if (item_data
->changes
> -1) {
454 item_data
->changes
+= 1;
455 item_data
->frame_number
= pinfo
->fd
->num
;
456 dialog
->ui
->tableWidget
->item(i_row
, column_number_changes
)->setText(QString::number(item_data
->changes
));
458 item_data
->changes
= 0;
460 dialog
->ui
->tableWidget
->item(i_row
, column_number_value
)->setText("");
462 *tapinfo
->changes
+= 1;
465 case BLUETOOTH_DEVICE_SCAN
:
466 field
= QString(val_to_str_const(tap_device
->data
.scan
, bthci_cmd_scan_enable_values
, "Unknown 0x%02x"));
467 item
= tableWidget
->item(row_number_scan
, column_number_value
);
468 saveItemData(item
, tap_device
, pinfo
);
469 updateChanges(tableWidget
, field
, row_number_scan
, tapinfo
->changes
, pinfo
);
470 item
->setText(field
);
472 case BLUETOOTH_DEVICE_LOCAL_VERSION
:
473 field
= QString(val_to_str_const(tap_device
->data
.local_version
.hci_version
, bthci_evt_hci_version
, "Unknown 0x%02x"));
474 item
= tableWidget
->item(row_number_hci_version
, column_number_value
);
475 saveItemData(item
, tap_device
, pinfo
);
476 updateChanges(tableWidget
, field
, row_number_hci_version
, tapinfo
->changes
, pinfo
);
477 item
->setText(field
);
479 field
= QString::number(tap_device
->data
.local_version
.hci_revision
);
480 item
= tableWidget
->item(row_number_hci_revision
, column_number_value
);
481 saveItemData(item
, tap_device
, pinfo
);
482 updateChanges(tableWidget
, field
, row_number_hci_revision
, tapinfo
->changes
, pinfo
);
483 item
->setText(field
);
485 field
= QString(val_to_str_const(tap_device
->data
.local_version
.lmp_version
, bthci_evt_lmp_version
, "Unknown 0x%02x"));
486 item
= tableWidget
->item(row_number_lmp_version
, column_number_value
);
487 saveItemData(item
, tap_device
, pinfo
);
488 updateChanges(tableWidget
, field
, row_number_lmp_version
, tapinfo
->changes
, pinfo
);
489 item
->setText(field
);
491 field
= QString(val_to_str_const(tap_device
->data
.local_version
.lmp_version
, bthci_evt_lmp_version
, "Unknown 0x%02x"));
492 item
= tableWidget
->item(row_number_lmp_version
, column_number_value
);
493 saveItemData(item
, tap_device
, pinfo
);
494 updateChanges(tableWidget
, field
, row_number_lmp_version
, tapinfo
->changes
, pinfo
);
495 item
->setText(field
);
497 field
= QString::number(tap_device
->data
.local_version
.lmp_subversion
);
498 item
= tableWidget
->item(row_number_lmp_subversion
, column_number_value
);
499 saveItemData(item
, tap_device
, pinfo
);
500 updateChanges(tableWidget
, field
, row_number_lmp_subversion
, tapinfo
->changes
, pinfo
);
501 item
->setText(field
);
503 field
= QString(val_to_str_ext_const(tap_device
->data
.local_version
.manufacturer
, &bluetooth_company_id_vals_ext
, "Unknown 0x%04x"));
504 item
= tableWidget
->item(row_number_manufacturer
, column_number_value
);
505 saveItemData(item
, tap_device
, pinfo
);
506 updateChanges(tableWidget
, field
, row_number_manufacturer
, tapinfo
->changes
, pinfo
);
507 item
->setText(field
);
510 case BLUETOOTH_DEVICE_REMOTE_VERSION
:
511 field
= QString(val_to_str_const(tap_device
->data
.remote_version
.lmp_version
, bthci_evt_lmp_version
, "Unknown 0x%02x"));
512 item
= tableWidget
->item(row_number_lmp_version
, column_number_value
);
513 saveItemData(item
, tap_device
, pinfo
);
514 updateChanges(tableWidget
, field
, row_number_lmp_version
, tapinfo
->changes
, pinfo
);
515 item
->setText(field
);
517 field
= QString::number(tap_device
->data
.remote_version
.lmp_subversion
);
518 item
= tableWidget
->item(row_number_lmp_subversion
, column_number_value
);
519 saveItemData(item
, tap_device
, pinfo
);
520 updateChanges(tableWidget
, field
, row_number_lmp_subversion
, tapinfo
->changes
, pinfo
);
521 item
->setText(field
);
523 field
= QString(val_to_str_ext_const(tap_device
->data
.remote_version
.manufacturer
, &bluetooth_company_id_vals_ext
, "Unknown 0x%04x"));
524 item
= tableWidget
->item(row_number_manufacturer
, column_number_value
);
525 saveItemData(item
, tap_device
, pinfo
);
526 updateChanges(tableWidget
, field
, row_number_manufacturer
, tapinfo
->changes
, pinfo
);
527 item
->setText(field
);
530 case BLUETOOTH_DEVICE_VOICE_SETTING
:
531 field
= QStringLiteral("%1").arg(tap_device
->data
.voice_setting
, 4, 16, QChar('0'));
532 item
= tableWidget
->item(row_number_voice_setting
, column_number_value
);
533 saveItemData(item
, tap_device
, pinfo
);
534 updateChanges(tableWidget
, field
, row_number_voice_setting
, tapinfo
->changes
, pinfo
);
535 item
->setText(field
);
538 case BLUETOOTH_DEVICE_CLASS_OF_DEVICE
:
539 field
= QStringLiteral("%1").arg(tap_device
->data
.class_of_device
, 6, 16, QChar('0'));
540 item
= tableWidget
->item(row_number_class_of_device
, column_number_value
);
541 saveItemData(item
, tap_device
, pinfo
);
542 updateChanges(tableWidget
, field
, row_number_class_of_device
, tapinfo
->changes
, pinfo
);
543 item
->setText(field
);
546 case BLUETOOTH_DEVICE_AUTHENTICATION
:
547 field
= QString(val_to_str_const(tap_device
->data
.authentication
, bthci_cmd_authentication_enable_values
, "Unknown 0x%02x"));
548 item
= tableWidget
->item(row_number_authentication
, column_number_value
);
549 saveItemData(item
, tap_device
, pinfo
);
550 updateChanges(tableWidget
, field
, row_number_authentication
, tapinfo
->changes
, pinfo
);
551 item
->setText(field
);
554 case BLUETOOTH_DEVICE_ENCRYPTION
:
555 field
= QString(val_to_str_const(tap_device
->data
.encryption
, bthci_cmd_encrypt_mode_vals
, "Unknown 0x%02x"));
556 item
= tableWidget
->item(row_number_encryption
, column_number_value
);
557 saveItemData(item
, tap_device
, pinfo
);
558 updateChanges(tableWidget
, field
, row_number_encryption
, tapinfo
->changes
, pinfo
);
559 item
->setText(field
);
562 case BLUETOOTH_DEVICE_SIMPLE_PAIRING_MODE
:
563 field
= QString(tap_device
->data
.encryption
? tr("enabled") : tr("disabled"));
564 item
= tableWidget
->item(row_number_simple_pairing_mode
, column_number_value
);
565 saveItemData(item
, tap_device
, pinfo
);
566 updateChanges(tableWidget
, field
, row_number_simple_pairing_mode
, tapinfo
->changes
, pinfo
);
567 item
->setText(field
);
570 case BLUETOOTH_DEVICE_PAGE_TIMEOUT
:
571 field
= tr("%1 ms (%2 slots)").arg(tap_device
->data
.page_timeout
* 0.625).arg(tap_device
->data
.page_timeout
);
572 item
= tableWidget
->item(row_number_page_timeout
, column_number_value
);
573 saveItemData(item
, tap_device
, pinfo
);
574 updateChanges(tableWidget
, field
, row_number_page_timeout
, tapinfo
->changes
, pinfo
);
575 item
->setText(field
);
578 case BLUETOOTH_DEVICE_INQUIRY_MODE
:
579 field
= QString(val_to_str_const(tap_device
->data
.inquiry_mode
, bthci_cmd_inq_modes
, "Unknown 0x%02x"));
580 item
= tableWidget
->item(row_number_inquiry_mode
, column_number_value
);
581 saveItemData(item
, tap_device
, pinfo
);
582 updateChanges(tableWidget
, field
, row_number_inquiry_mode
, tapinfo
->changes
, pinfo
);
583 item
->setText(field
);
586 case BLUETOOTH_DEVICE_MTUS
:
587 field
= QString::number(tap_device
->data
.mtus
.acl_mtu
);
588 item
= tableWidget
->item(row_number_acl_mtu
, column_number_value
);
589 saveItemData(item
, tap_device
, pinfo
);
590 updateChanges(tableWidget
, field
, row_number_acl_mtu
, tapinfo
->changes
, pinfo
);
591 item
->setText(field
);
593 field
= QString::number(tap_device
->data
.mtus
.acl_packets
);
594 item
= tableWidget
->item(row_number_acl_packets
, column_number_value
);
595 saveItemData(item
, tap_device
, pinfo
);
596 updateChanges(tableWidget
, field
, row_number_acl_packets
, tapinfo
->changes
, pinfo
);
597 item
->setText(field
);
599 field
= QString::number(tap_device
->data
.mtus
.sco_mtu
);
600 item
= tableWidget
->item(row_number_sco_mtu
, column_number_value
);
601 saveItemData(item
, tap_device
, pinfo
);
602 updateChanges(tableWidget
, field
, row_number_sco_mtu
, tapinfo
->changes
, pinfo
);
603 item
->setText(field
);
605 field
= QString::number(tap_device
->data
.mtus
.sco_packets
);
606 item
= tableWidget
->item(row_number_sco_packets
, column_number_value
);
607 saveItemData(item
, tap_device
, pinfo
);
608 updateChanges(tableWidget
, field
, row_number_sco_packets
, tapinfo
->changes
, pinfo
);
609 item
->setText(field
);
612 case BLUETOOTH_DEVICE_LE_MTU
:
613 field
= QString::number(tap_device
->data
.le_mtus
.acl_mtu
);
614 item
= tableWidget
->item(row_number_le_acl_mtu
, column_number_value
);
615 saveItemData(item
, tap_device
, pinfo
);
616 updateChanges(tableWidget
, field
, row_number_le_acl_mtu
, tapinfo
->changes
, pinfo
);
617 item
->setText(field
);
619 field
= QString::number(tap_device
->data
.le_mtus
.acl_packets
);
620 item
= tableWidget
->item(row_number_le_acl_packets
, column_number_value
);
621 saveItemData(item
, tap_device
, pinfo
);
622 updateChanges(tableWidget
, field
, row_number_le_acl_packets
, tapinfo
->changes
, pinfo
);
623 item
->setText(field
);
625 field
= QString::number(tap_device
->data
.le_mtus
.iso_mtu
);
626 item
= tableWidget
->item(row_number_le_iso_mtu
, column_number_value
);
627 saveItemData(item
, tap_device
, pinfo
);
628 updateChanges(tableWidget
, field
, row_number_le_iso_mtu
, tapinfo
->changes
, pinfo
);
629 item
->setText(field
);
631 field
= QString::number(tap_device
->data
.le_mtus
.iso_packets
);
632 item
= tableWidget
->item(row_number_le_iso_packets
, column_number_value
);
633 saveItemData(item
, tap_device
, pinfo
);
634 updateChanges(tableWidget
, field
, row_number_le_iso_packets
, tapinfo
->changes
, pinfo
);
635 item
->setText(field
);
640 dialog
->ui
->hintLabel
->setText(tr("%1 changes").arg(*tapinfo
->changes
));
642 return TAP_PACKET_REDRAW
;
645 void BluetoothDeviceDialog::interfaceCurrentIndexChanged(int)
647 cap_file_
.retapPackets();
650 void BluetoothDeviceDialog::showInformationStepsChanged(int)
652 cap_file_
.retapPackets();
656 void BluetoothDeviceDialog::on_tableWidget_itemActivated(QTableWidgetItem
*item
)
658 if (!cap_file_
.isValid())
661 if (!item
->data(Qt::UserRole
).isValid())
664 bluetooth_item_data_t
*item_data
= VariantPointer
<bluetooth_item_data_t
>::asPtr(item
->data(Qt::UserRole
));
666 emit
goToPacket(item_data
->frame_number
);
670 void BluetoothDeviceDialog::on_actionSave_as_image_triggered()
674 QString fileName
= WiresharkFileDialog::getSaveFileName(this,
675 tr("Save Table Image"),
676 "bluetooth_device_table.png",
677 tr("PNG Image (*.png)"));
679 if (fileName
.isEmpty()) return;
681 image
= ui
->tableWidget
->grab();
682 image
.save(fileName
, "PNG");
685 void BluetoothDeviceDialog::on_buttonBox_clicked(QAbstractButton
*)