1 /* bluetooth_device_dialog.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "bluetooth_device_dialog.h"
11 #include <ui_bluetooth_device_dialog.h>
12
13 #include <ui/qt/utils/color_utils.h>
14
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"
22
23 #include "ui/simple_dialog.h"
24
25 #include <ui/qt/utils/variant_pointer.h>
26 #include "ui/qt/widgets/wireshark_file_dialog.h"
27
28 #include <QClipboard>
29 #include <QContextMenuEvent>
30 #include <QPushButton>
31 #include <QTreeWidget>
32
33 static const int column_number_value = 0;
34 static const int column_number_changes = 1;
35
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;
60
61 static tap_packet_status
bluetooth_device_tap_packet(void * tapinfo_ptr,packet_info * pinfo,epan_dissect_t * edt,const void * data)62 bluetooth_device_tap_packet(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *edt, const void* data)
63 {
64 bluetooth_device_tapinfo_t *tapinfo = (bluetooth_device_tapinfo_t *) tapinfo_ptr;
65
66 if (tapinfo->tap_packet)
67 tapinfo->tap_packet(tapinfo, pinfo, edt, data);
68
69 return TAP_PACKET_REDRAW;
70 }
71
72 static void
bluetooth_device_tap_reset(void * tapinfo_ptr)73 bluetooth_device_tap_reset(void *tapinfo_ptr)
74 {
75 bluetooth_device_tapinfo_t *tapinfo = (bluetooth_device_tapinfo_t *) tapinfo_ptr;
76
77 if (tapinfo->tap_reset)
78 tapinfo->tap_reset(tapinfo);
79 }
80
81
82 static void
bluetooth_devices_tap(void * data)83 bluetooth_devices_tap(void *data)
84 {
85 GString *error_string;
86
87 error_string = register_tap_listener("bluetooth.device", data, NULL,
88 0,
89 bluetooth_device_tap_reset,
90 bluetooth_device_tap_packet,
91 NULL,
92 NULL
93 );
94
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);
99 }
100 }
101
102
BluetoothDeviceDialog(QWidget & parent,CaptureFile & cf,QString bdAddr,QString name,guint32 interface_id,guint32 adapter_id,gboolean is_local)103 BluetoothDeviceDialog::BluetoothDeviceDialog(QWidget &parent, CaptureFile &cf, QString bdAddr, QString name, guint32 interface_id, guint32 adapter_id, gboolean is_local) :
104 WiresharkDialog(parent, cf),
105 ui(new Ui::BluetoothDeviceDialog)
106 {
107 QString titleBdAddr;
108 QString titleName;
109
110 ui->setupUi(this);
111 resize(parent.width() * 4 / 10, parent.height() * 2 / 2);
112
113 setTitle(bdAddr, name);
114
115 connect(ui->tableWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(tableContextMenu(const QPoint &)));
116
117 ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
118
119 ui->tableWidget->setStyleSheet("QTableView::item:hover{background-color:lightyellow; color:black;}");
120
121 context_menu_.addActions(QList<QAction *>() << ui->actionMark_Unmark_Cell);
122 context_menu_.addActions(QList<QAction *>() << ui->actionMark_Unmark_Row);
123 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Cell);
124 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_Rows);
125 context_menu_.addActions(QList<QAction *>() << ui->actionCopy_All);
126 context_menu_.addActions(QList<QAction *>() << ui->actionSave_as_image);
127
128 changes_ = 0;
129
130 tapinfo_.tap_packet = tapPacket;
131 tapinfo_.tap_reset = tapReset;
132 tapinfo_.ui = this;
133 tapinfo_.is_local = is_local;
134 tapinfo_.bdAddr = bdAddr;
135 tapinfo_.interface_id = interface_id;
136 tapinfo_.adapter_id = adapter_id;
137 tapinfo_.changes = &changes_;
138
139 ui->hintLabel->setText(ui->hintLabel->text().arg(changes_));
140
141 for (int i_row = 0; i_row < ui->tableWidget->rowCount(); i_row += 1) {
142 for (int i_column = 0; i_column < ui->tableWidget->columnCount(); i_column += 1) {
143 QTableWidgetItem *item = new QTableWidgetItem();
144 ui->tableWidget->setItem(i_row, i_column, item);
145 }
146 }
147
148 bluetooth_devices_tap(&tapinfo_);
149
150 cap_file_.retapPackets();
151 }
152
153
~BluetoothDeviceDialog()154 BluetoothDeviceDialog::~BluetoothDeviceDialog()
155 {
156 delete ui;
157
158 remove_tap_listener(&tapinfo_);
159 }
160
setTitle(QString bdAddr,QString name)161 void BluetoothDeviceDialog::setTitle(QString bdAddr, QString name)
162 {
163 QString titleBdAddr;
164 QString titleName;
165
166 if (bdAddr.isEmpty())
167 titleBdAddr = QString(tr("Unknown"));
168 else
169 titleBdAddr = bdAddr;
170
171 if (name.isEmpty())
172 titleName = "";
173 else
174 titleName = " ("+name+")";
175
176 setWindowTitle(tr("Bluetooth Device - %1%2").arg(titleBdAddr).arg(titleName));
177 }
178
captureFileClosing()179 void BluetoothDeviceDialog::captureFileClosing()
180 {
181 remove_tap_listener(&tapinfo_);
182
183 WiresharkDialog::captureFileClosing();
184 }
185
186
changeEvent(QEvent * event)187 void BluetoothDeviceDialog::changeEvent(QEvent *event)
188 {
189 if (0 != event)
190 {
191 switch (event->type())
192 {
193 case QEvent::LanguageChange:
194 ui->retranslateUi(this);
195 break;
196 default:
197 break;
198 }
199 }
200 QDialog::changeEvent(event);
201 }
202
203
keyPressEvent(QKeyEvent * event)204 void BluetoothDeviceDialog::keyPressEvent(QKeyEvent *event)
205 {
206 /* NOTE: Do nothing*, but in real it "takes focus" from button_box so allow user
207 * to use Enter button to jump to frame from tree widget */
208 /* * - reimplement shortcuts from contex menu */
209
210 if (event->modifiers() & Qt::ControlModifier && event->key()== Qt::Key_M)
211 on_actionMark_Unmark_Row_triggered();
212 }
213
on_actionMark_Unmark_Cell_triggered()214 void BluetoothDeviceDialog::on_actionMark_Unmark_Cell_triggered()
215 {
216 QTableWidgetItem *current_item = ui->tableWidget->currentItem();
217 if (!current_item)
218 return;
219
220 QBrush fg;
221 QBrush bg;
222
223 if (current_item->background() == QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg))) {
224 fg = QBrush();
225 bg = QBrush();
226 } else {
227 fg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_fg));
228 bg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg));
229 }
230
231 current_item->setForeground(fg);
232 current_item->setBackground(bg);
233 }
234
235
on_actionMark_Unmark_Row_triggered()236 void BluetoothDeviceDialog::on_actionMark_Unmark_Row_triggered()
237 {
238 QBrush fg;
239 QBrush bg;
240 bool is_marked = TRUE;
241
242 QTableWidgetItem *current_item = ui->tableWidget->currentItem();
243 if (!current_item)
244 return;
245
246 for (int i = 0; i < ui->tableWidget->columnCount(); i += 1) {
247 QTableWidgetItem *item = ui->tableWidget->item(current_item->row(), i);
248 if (item->background() != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
249 is_marked = FALSE;
250 }
251
252 if (is_marked) {
253 fg = QBrush();
254 bg = QBrush();
255 } else {
256 fg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_fg));
257 bg = QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg));
258 }
259
260 for (int i = 0; i < ui->tableWidget->columnCount(); i += 1) {
261 QTableWidgetItem *item = ui->tableWidget->item(current_item->row(), i);
262 item->setForeground(fg);
263 item->setBackground(bg);
264 }
265 }
266
267
tableContextMenu(const QPoint & pos)268 void BluetoothDeviceDialog::tableContextMenu(const QPoint &pos)
269 {
270 context_menu_.exec(ui->tableWidget->viewport()->mapToGlobal(pos));
271 }
272
on_actionCopy_Cell_triggered()273 void BluetoothDeviceDialog::on_actionCopy_Cell_triggered()
274 {
275 QTableWidgetItem *current_item = ui->tableWidget->currentItem();
276 if (!current_item)
277 return;
278
279 QClipboard *clipboard = QApplication::clipboard();
280 QString copy;
281
282 copy = QString(current_item->text());
283
284 clipboard->setText(copy);
285 }
286
on_actionCopy_Rows_triggered()287 void BluetoothDeviceDialog::on_actionCopy_Rows_triggered()
288 {
289 QClipboard *clipboard = QApplication::clipboard();
290 QString copy;
291 QList<QTableWidgetItem *> items;
292 QList<QTableWidgetItem *>::iterator i_item;
293
294 items = ui->tableWidget->selectedItems();
295
296 for (i_item = items.begin(); i_item != items.end(); ++i_item) {
297 copy += QString("%1 %2 %3\n")
298 .arg(ui->tableWidget->verticalHeaderItem((*i_item)->row())->text(), -40)
299 .arg(ui->tableWidget->item((*i_item)->row(), column_number_value)->text(), -50)
300 .arg(ui->tableWidget->item((*i_item)->row(), column_number_changes)->text(), -10);
301 }
302
303 clipboard->setText(copy);
304 }
305
on_actionCopy_All_triggered()306 void BluetoothDeviceDialog::on_actionCopy_All_triggered()
307 {
308 QClipboard *clipboard = QApplication::clipboard();
309 QString copy;
310
311 copy += QString("%1 %2 %3\n")
312 .arg("Headers", -40)
313 .arg(ui->tableWidget->horizontalHeaderItem(column_number_value)->text(), -50)
314 .arg(ui->tableWidget->horizontalHeaderItem(column_number_changes)->text(), -10);
315
316 for (int i_row = 0; i_row < ui->tableWidget->rowCount(); i_row += 1) {
317 for (int i_column = 0; i_column < ui->tableWidget->columnCount(); i_column += 1) {
318
319 copy += QString("%1 %2 %3\n")
320 .arg(ui->tableWidget->verticalHeaderItem(i_row)->text(), -40)
321 .arg(ui->tableWidget->item(i_row, column_number_value)->text(), -50)
322 .arg(ui->tableWidget->item(i_row, column_number_changes)->text(), -10);
323 }
324 }
325
326 clipboard->setText(copy);
327 }
328
329
330
tapReset(void * tapinfo_ptr)331 void BluetoothDeviceDialog::tapReset(void *tapinfo_ptr)
332 {
333 bluetooth_device_tapinfo_t *tapinfo = (bluetooth_device_tapinfo_t *) tapinfo_ptr;
334 BluetoothDeviceDialog *dialog = static_cast<BluetoothDeviceDialog *>(tapinfo->ui);
335
336 for (int i_row = 0; i_row < dialog->ui->tableWidget->rowCount(); i_row += 1) {
337 for (int i_column = 0; i_column < dialog->ui->tableWidget->columnCount(); i_column += 1) {
338 QTableWidgetItem *item = new QTableWidgetItem();
339 dialog->ui->tableWidget->setItem(i_row, i_column, item);
340 }
341 }
342 *tapinfo->changes = 0;
343 }
344
updateChanges(QTableWidget * tableWidget,QString value,const int row,guint * changes,packet_info * pinfo)345 void BluetoothDeviceDialog::updateChanges(QTableWidget *tableWidget, QString value, const int row, guint *changes, packet_info *pinfo)
346 {
347 QTableWidgetItem *item = tableWidget->item(row, column_number_value);
348 bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(item->data(Qt::UserRole));
349
350 if (item->text() == value)
351 return;
352
353 if (item_data->changes == -1) {
354 item_data->changes = 0;
355 } else {
356 *changes += 1;
357 item_data->changes += 1;
358 item_data->frame_number = pinfo->fd->num;
359 tableWidget->item(row, column_number_changes)->setText(QString::number(item_data->changes));
360 }
361 }
362
saveItemData(QTableWidgetItem * item,bluetooth_device_tap_t * tap_device,packet_info * pinfo)363 void BluetoothDeviceDialog::saveItemData(QTableWidgetItem *item,
364 bluetooth_device_tap_t *tap_device, packet_info *pinfo)
365 {
366 if (item->data(Qt::UserRole).isValid())
367 return;
368
369 bluetooth_item_data_t *item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
370 item_data->interface_id = tap_device->interface_id;
371 item_data->adapter_id = tap_device->adapter_id;
372 item_data->changes = -1;
373 item_data->frame_number = pinfo->fd->num;
374 item->setData(Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
375
376 }
377
tapPacket(void * tapinfo_ptr,packet_info * pinfo,epan_dissect_t *,const void * data)378 tap_packet_status BluetoothDeviceDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data)
379 {
380 bluetooth_device_tapinfo_t *tapinfo = static_cast<bluetooth_device_tapinfo_t *>(tapinfo_ptr);
381 BluetoothDeviceDialog *dialog = static_cast<BluetoothDeviceDialog *>(tapinfo->ui);
382 bluetooth_device_tap_t *tap_device = static_cast<bluetooth_device_tap_t *>(const_cast<void *>(data));
383 QString bd_addr;
384 QString bd_addr_oui;
385 QString name;
386 const gchar *manuf;
387 QTableWidget *tableWidget;
388 QTableWidgetItem *item;
389 QString field;
390
391 tableWidget = dialog->ui->tableWidget;
392
393 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))) {
394 return TAP_PACKET_REDRAW;
395 }
396
397 if (tap_device->has_bd_addr) {
398 for (int i = 0; i < 6; ++i) {
399 bd_addr += QString("%1:").arg(tap_device->bd_addr[i], 2, 16, QChar('0'));
400 }
401 bd_addr.chop(1); // remove extra character ":" from the end of the string
402 if (!tap_device->is_local && bd_addr != tapinfo->bdAddr)
403 return TAP_PACKET_REDRAW;
404
405 manuf = get_ether_name(tap_device->bd_addr);
406 if (manuf) {
407 int pos;
408
409 bd_addr_oui = QString(manuf);
410 pos = bd_addr_oui.indexOf('_');
411 if (pos < 0) {
412 manuf = NULL;
413 } else {
414 bd_addr_oui.remove(pos, bd_addr_oui.size());
415 }
416 }
417
418 if (!manuf)
419 bd_addr_oui = "";
420
421 item = tableWidget->item(row_number_bd_addr, column_number_value);
422 saveItemData(item, tap_device, pinfo);
423 updateChanges(tableWidget, bd_addr, row_number_bd_addr, tapinfo->changes, pinfo);
424 item->setText(bd_addr);
425
426 item = tableWidget->item(row_number_bd_addr_oui, column_number_value);
427 saveItemData(item, tap_device, pinfo);
428 updateChanges(tableWidget, bd_addr_oui, row_number_bd_addr_oui, tapinfo->changes, pinfo);
429 item->setText(bd_addr_oui);
430
431 dialog->setTitle(bd_addr, tableWidget->item(row_number_name, column_number_value)->text());
432 }
433
434 switch (tap_device->type) {
435 case BLUETOOTH_DEVICE_LOCAL_ADAPTER:
436 case BLUETOOTH_DEVICE_BD_ADDR:
437 break;
438 case BLUETOOTH_DEVICE_NAME:
439 item = tableWidget->item(row_number_name, column_number_value);
440 saveItemData(item, tap_device, pinfo);
441 updateChanges(tableWidget, QString(tap_device->data.name), row_number_name, tapinfo->changes, pinfo);
442
443 item->setText(tap_device->data.name);
444
445 dialog->setTitle(tableWidget->item(row_number_bd_addr, column_number_value)->text(), tap_device->data.name);
446
447 break;
448 case BLUETOOTH_DEVICE_RESET:
449 for (int i_row = 0; i_row < dialog->ui->tableWidget->rowCount(); i_row += 1) {
450 bluetooth_item_data_t *item_data;
451
452 item = dialog->ui->tableWidget->item(i_row, column_number_value);
453 saveItemData(item, tap_device, pinfo);
454
455 item_data = VariantPointer<bluetooth_item_data_t>::asPtr(item->data(Qt::UserRole));
456
457 if (item_data->changes > -1) {
458 item_data->changes += 1;
459 item_data->frame_number = pinfo->fd->num;
460 dialog->ui->tableWidget->item(i_row, column_number_changes)->setText(QString::number(item_data->changes));
461 } else {
462 item_data->changes = 0;
463 }
464 dialog->ui->tableWidget->item(i_row, column_number_value)->setText("");
465 }
466 *tapinfo->changes += 1;
467
468 break;
469 case BLUETOOTH_DEVICE_SCAN:
470 field = QString(val_to_str_const(tap_device->data.scan, bthci_cmd_scan_enable_values, "Unknown 0x%02x"));
471 item = tableWidget->item(row_number_scan, column_number_value);
472 saveItemData(item, tap_device, pinfo);
473 updateChanges(tableWidget, field, row_number_scan, tapinfo->changes, pinfo);
474 item->setText(field);
475 break;
476 case BLUETOOTH_DEVICE_LOCAL_VERSION:
477 field = QString(val_to_str_const(tap_device->data.local_version.hci_version, bthci_evt_hci_version, "Unknown 0x%02x"));
478 item = tableWidget->item(row_number_hci_version, column_number_value);
479 saveItemData(item, tap_device, pinfo);
480 updateChanges(tableWidget, field, row_number_hci_version, tapinfo->changes, pinfo);
481 item->setText(field);
482
483 field = QString::number(tap_device->data.local_version.hci_revision);
484 item = tableWidget->item(row_number_hci_revision, column_number_value);
485 saveItemData(item, tap_device, pinfo);
486 updateChanges(tableWidget, field, row_number_hci_revision, tapinfo->changes, pinfo);
487 item->setText(field);
488
489 field = QString(val_to_str_const(tap_device->data.local_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x"));
490 item = tableWidget->item(row_number_lmp_version, column_number_value);
491 saveItemData(item, tap_device, pinfo);
492 updateChanges(tableWidget, field, row_number_lmp_version, tapinfo->changes, pinfo);
493 item->setText(field);
494
495 field = QString(val_to_str_const(tap_device->data.local_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x"));
496 item = tableWidget->item(row_number_lmp_version, column_number_value);
497 saveItemData(item, tap_device, pinfo);
498 updateChanges(tableWidget, field, row_number_lmp_version, tapinfo->changes, pinfo);
499 item->setText(field);
500
501 field = QString::number(tap_device->data.local_version.lmp_subversion);
502 item = tableWidget->item(row_number_lmp_subversion, column_number_value);
503 saveItemData(item, tap_device, pinfo);
504 updateChanges(tableWidget, field, row_number_lmp_subversion, tapinfo->changes, pinfo);
505 item->setText(field);
506
507 field = QString(val_to_str_ext_const(tap_device->data.local_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x"));
508 item = tableWidget->item(row_number_manufacturer, column_number_value);
509 saveItemData(item, tap_device, pinfo);
510 updateChanges(tableWidget, field, row_number_manufacturer, tapinfo->changes, pinfo);
511 item->setText(field);
512
513 break;
514 case BLUETOOTH_DEVICE_REMOTE_VERSION:
515 field = QString(val_to_str_const(tap_device->data.remote_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x"));
516 item = tableWidget->item(row_number_lmp_version, column_number_value);
517 saveItemData(item, tap_device, pinfo);
518 updateChanges(tableWidget, field, row_number_lmp_version, tapinfo->changes, pinfo);
519 item->setText(field);
520
521 field = QString::number(tap_device->data.remote_version.lmp_subversion);
522 item = tableWidget->item(row_number_lmp_subversion, column_number_value);
523 saveItemData(item, tap_device, pinfo);
524 updateChanges(tableWidget, field, row_number_lmp_subversion, tapinfo->changes, pinfo);
525 item->setText(field);
526
527 field = QString(val_to_str_ext_const(tap_device->data.remote_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x"));
528 item = tableWidget->item(row_number_manufacturer, column_number_value);
529 saveItemData(item, tap_device, pinfo);
530 updateChanges(tableWidget, field, row_number_manufacturer, tapinfo->changes, pinfo);
531 item->setText(field);
532
533 break;
534 case BLUETOOTH_DEVICE_VOICE_SETTING:
535 field = QString("%1").arg(tap_device->data.voice_setting, 4, 16, QChar('0'));
536 item = tableWidget->item(row_number_voice_setting, column_number_value);
537 saveItemData(item, tap_device, pinfo);
538 updateChanges(tableWidget, field, row_number_voice_setting, tapinfo->changes, pinfo);
539 item->setText(field);
540
541 break;
542 case BLUETOOTH_DEVICE_CLASS_OF_DEVICE:
543 field = QString("%1").arg(tap_device->data.class_of_device, 6, 16, QChar('0'));
544 item = tableWidget->item(row_number_class_of_device, column_number_value);
545 saveItemData(item, tap_device, pinfo);
546 updateChanges(tableWidget, field, row_number_class_of_device, tapinfo->changes, pinfo);
547 item->setText(field);
548
549 break;
550 case BLUETOOTH_DEVICE_AUTHENTICATION:
551 field = QString(val_to_str_const(tap_device->data.authentication, bthci_cmd_authentication_enable_values, "Unknown 0x%02x"));
552 item = tableWidget->item(row_number_authentication, column_number_value);
553 saveItemData(item, tap_device, pinfo);
554 updateChanges(tableWidget, field, row_number_authentication, tapinfo->changes, pinfo);
555 item->setText(field);
556
557 break;
558 case BLUETOOTH_DEVICE_ENCRYPTION:
559 field = QString(val_to_str_const(tap_device->data.encryption, bthci_cmd_encrypt_mode_vals, "Unknown 0x%02x"));
560 item = tableWidget->item(row_number_encryption, column_number_value);
561 saveItemData(item, tap_device, pinfo);
562 updateChanges(tableWidget, field, row_number_encryption, tapinfo->changes, pinfo);
563 item->setText(field);
564
565 break;
566 case BLUETOOTH_DEVICE_SIMPLE_PAIRING_MODE:
567 field = QString(tap_device->data.encryption ? tr("enabled") : tr("disabled"));
568 item = tableWidget->item(row_number_simple_pairing_mode, column_number_value);
569 saveItemData(item, tap_device, pinfo);
570 updateChanges(tableWidget, field, row_number_simple_pairing_mode, tapinfo->changes, pinfo);
571 item->setText(field);
572
573 break;
574 case BLUETOOTH_DEVICE_PAGE_TIMEOUT:
575 field = QString(tr("%1 ms (%2 slots)")).arg(tap_device->data.page_timeout * 0.625).arg(tap_device->data.page_timeout);
576 item = tableWidget->item(row_number_page_timeout, column_number_value);
577 saveItemData(item, tap_device, pinfo);
578 updateChanges(tableWidget, field, row_number_page_timeout, tapinfo->changes, pinfo);
579 item->setText(field);
580
581 break;
582 case BLUETOOTH_DEVICE_INQUIRY_MODE:
583 field = QString(val_to_str_const(tap_device->data.inquiry_mode, bthci_cmd_inq_modes, "Unknown 0x%02x"));
584 item = tableWidget->item(row_number_inquiry_mode, column_number_value);
585 saveItemData(item, tap_device, pinfo);
586 updateChanges(tableWidget, field, row_number_inquiry_mode, tapinfo->changes, pinfo);
587 item->setText(field);
588
589 break;
590 case BLUETOOTH_DEVICE_MTUS:
591 field = QString::number(tap_device->data.mtus.acl_mtu);
592 item = tableWidget->item(row_number_acl_mtu, column_number_value);
593 saveItemData(item, tap_device, pinfo);
594 updateChanges(tableWidget, field, row_number_acl_mtu, tapinfo->changes, pinfo);
595 item->setText(field);
596
597 field = QString::number(tap_device->data.mtus.acl_packets);
598 item = tableWidget->item(row_number_acl_packets, column_number_value);
599 saveItemData(item, tap_device, pinfo);
600 updateChanges(tableWidget, field, row_number_acl_packets, tapinfo->changes, pinfo);
601 item->setText(field);
602
603 field = QString::number(tap_device->data.mtus.sco_mtu);
604 item = tableWidget->item(row_number_sco_mtu, column_number_value);
605 saveItemData(item, tap_device, pinfo);
606 updateChanges(tableWidget, field, row_number_sco_mtu, tapinfo->changes, pinfo);
607 item->setText(field);
608
609 field = QString::number(tap_device->data.mtus.sco_packets);
610 item = tableWidget->item(row_number_sco_packets, column_number_value);
611 saveItemData(item, tap_device, pinfo);
612 updateChanges(tableWidget, field, row_number_sco_packets, tapinfo->changes, pinfo);
613 item->setText(field);
614
615 break;
616 case BLUETOOTH_DEVICE_LE_MTU:
617 field = QString::number(tap_device->data.le_mtus.acl_mtu);
618 item = tableWidget->item(row_number_le_acl_mtu, column_number_value);
619 saveItemData(item, tap_device, pinfo);
620 updateChanges(tableWidget, field, row_number_le_acl_mtu, tapinfo->changes, pinfo);
621 item->setText(field);
622
623 field = QString::number(tap_device->data.le_mtus.acl_packets);
624 item = tableWidget->item(row_number_le_acl_packets, column_number_value);
625 saveItemData(item, tap_device, pinfo);
626 updateChanges(tableWidget, field, row_number_le_acl_packets, tapinfo->changes, pinfo);
627 item->setText(field);
628
629 field = QString::number(tap_device->data.le_mtus.iso_mtu);
630 item = tableWidget->item(row_number_le_iso_mtu, column_number_value);
631 saveItemData(item, tap_device, pinfo);
632 updateChanges(tableWidget, field, row_number_le_iso_mtu, tapinfo->changes, pinfo);
633 item->setText(field);
634
635 field = QString::number(tap_device->data.le_mtus.iso_packets);
636 item = tableWidget->item(row_number_le_iso_packets, column_number_value);
637 saveItemData(item, tap_device, pinfo);
638 updateChanges(tableWidget, field, row_number_le_iso_packets, tapinfo->changes, pinfo);
639 item->setText(field);
640
641 break;
642 }
643
644 dialog->ui->hintLabel->setText(QString(tr("%1 changes")).arg(*tapinfo->changes));
645
646 return TAP_PACKET_REDRAW;
647 }
648
interfaceCurrentIndexChanged(int)649 void BluetoothDeviceDialog::interfaceCurrentIndexChanged(int)
650 {
651 cap_file_.retapPackets();
652 }
653
showInformationStepsChanged(int)654 void BluetoothDeviceDialog::showInformationStepsChanged(int)
655 {
656 cap_file_.retapPackets();
657 }
658
659
on_tableWidget_itemActivated(QTableWidgetItem * item)660 void BluetoothDeviceDialog::on_tableWidget_itemActivated(QTableWidgetItem *item)
661 {
662 if (!cap_file_.isValid())
663 return;
664
665 if (!item->data(Qt::UserRole).isValid())
666 return;
667
668 bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(item->data(Qt::UserRole));
669
670 emit goToPacket(item_data->frame_number);
671
672 }
673
on_actionSave_as_image_triggered()674 void BluetoothDeviceDialog::on_actionSave_as_image_triggered()
675 {
676 QPixmap image;
677
678 QString fileName = WiresharkFileDialog::getSaveFileName(this,
679 tr("Save Table Image"),
680 "bluetooth_device_table.png",
681 tr("PNG Image (*.png)"));
682
683 if (fileName.isEmpty()) return;
684
685 image = ui->tableWidget->grab();
686 image.save(fileName, "PNG");
687 }
688
on_buttonBox_clicked(QAbstractButton *)689 void BluetoothDeviceDialog::on_buttonBox_clicked(QAbstractButton *)
690 {
691
692 }
693