aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2015-05-03 13:50:42 +0200
committerMichal Labedzki <michal.labedzki@tieto.com>2015-05-18 07:10:37 +0000
commitf837dab1b2be10eb70bacb8145492920c2f2ed44 (patch)
tree54ea9543b138172815901a659d0bc347ed7443b2 /epan/dissectors
parent21b41e89dc6476cc42337ceab3ab8a5d4978becf (diff)
Bluetooth: HCI: Add command-event tracking
HCI Commands in most cases generate response in Event queue, so try to map event to command and give user response time information. Change-Id: Ib4956829b7d0064ab528aa3202f8f959d8d371b7 Reviewed-on: https://code.wireshark.org/review/8514 Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/Makefile.common2
-rw-r--r--epan/dissectors/packet-bluetooth.h30
-rw-r--r--epan/dissectors/packet-bthci_cmd.c179
-rw-r--r--epan/dissectors/packet-bthci_cmd.h79
-rw-r--r--epan/dissectors/packet-bthci_evt.c382
-rw-r--r--epan/dissectors/packet-bthci_evt.h40
-rw-r--r--epan/dissectors/packet-bthci_vendor.c4
-rw-r--r--epan/dissectors/packet-btle.c1
8 files changed, 565 insertions, 152 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index 322b6f735d..89a89ff1cb 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -1417,6 +1417,8 @@ DISSECTOR_INCLUDES = \
packet-btavdtp.h \
packet-btavrcp.h \
packet-bthci_acl.h \
+ packet-bthci_cmd.h \
+ packet-bthci_evt.h \
packet-btl2cap.h \
packet-btle.h \
packet-btrfcomm.h \
diff --git a/epan/dissectors/packet-bluetooth.h b/epan/dissectors/packet-bluetooth.h
index 876ab20ffe..69e7a02965 100644
--- a/epan/dissectors/packet-bluetooth.h
+++ b/epan/dissectors/packet-bluetooth.h
@@ -58,36 +58,6 @@ extern "C" {
extern int proto_bluetooth;
-extern value_string_ext bthci_cmd_opcode_vals_ext;
-extern value_string_ext bthci_ogf_vals_ext;
-extern value_string_ext bthci_cmd_ocf_link_control_vals_ext;
-extern value_string_ext bthci_cmd_ocf_link_policy_vals_ext;
-extern value_string_ext bthci_cmd_ocf_host_controller_and_baseband_vals_ext;
-extern value_string_ext bthci_cmd_ocf_informational_vals_ext;
-extern value_string_ext bthci_cmd_ocf_status_vals_ext;
-extern value_string_ext bthci_cmd_ocf_testing_vals_ext;
-extern value_string_ext bthci_cmd_ocf_low_energy_vals_ext;
-
-extern value_string_ext bthci_cmd_input_coding_vals_ext;
-extern value_string_ext bthci_cmd_input_data_format_vals_ext;
-extern value_string_ext bthci_cmd_input_sample_size_vals_ext;
-extern value_string_ext bthci_cmd_air_coding_format_vals_ext;
-extern value_string_ext bthci_cmd_status_vals_ext;
-extern value_string_ext bthci_cmd_eir_data_type_vals_ext;
-extern value_string_ext bthci_cmd_auth_req_vals_ext;
-extern value_string_ext bthci_cmd_appearance_vals_ext;
-
-extern const value_string bthci_cmd_io_capability_vals[];
-extern const value_string bthci_cmd_oob_data_present_vals[];
-extern const value_string bthci_cmd_address_types_vals[];
-extern const value_string bthci_cmd_scan_enable_values[];
-extern const value_string bthci_cmd_page_scan_modes[];
-extern const value_string bthci_cmd_page_scan_repetition_modes[];
-extern const value_string bthci_cmd_page_scan_period_modes[];
-extern const value_string bthci_cmd_notification_types[];
-
-extern value_string_ext bthci_evt_evt_code_vals_ext;
-
extern const value_string bluetooth_address_type_vals[];
#define STATUS_SUCCESS 0x00
diff --git a/epan/dissectors/packet-bthci_cmd.c b/epan/dissectors/packet-bthci_cmd.c
index 9400689c8c..74bb0ffd7f 100644
--- a/epan/dissectors/packet-bthci_cmd.c
+++ b/epan/dissectors/packet-bthci_cmd.c
@@ -39,6 +39,7 @@
#include <epan/decode_as.h>
#include "packet-bluetooth.h"
+#include "packet-bthci_cmd.h"
#include "packet-btsdp.h"
static int proto_bthci_cmd = -1;
@@ -332,6 +333,10 @@ static int hf_bthci_cmd_tx_freqency = -1;
static int hf_bthci_cmd_test_data_length = -1;
static int hf_bthci_cmd_test_packet_payload = -1;
static int hf_bthci_cmd_parameter = -1;
+static int hf_response_in_frame = -1;
+static int hf_command_response_time_delta = -1;
+static int hf_pending_in_frame = -1;
+static int hf_command_pending_time_delta = -1;
static const int *hfx_bthci_cmd_le_event_mask[] = {
&hf_bthci_cmd_le_event_mask_le_reserved,
@@ -507,11 +512,13 @@ static dissector_handle_t btcommon_ad_handle;
static dissector_handle_t btcommon_le_channel_map_handle;
static dissector_handle_t bthci_cmd_handle;
+wmem_tree_t *bthci_cmds = NULL;
+
extern value_string_ext ext_usb_vendors_vals;
extern value_string_ext ext_usb_products_vals;
extern value_string_ext did_vendor_id_source_vals_ext;
-static const value_string bthci_ogf_vals[] = {
+static const value_string bthci_cmd_ogf_vals[] = {
{ 0x01, "Link Control Commands" },
{ 0x02, "Link Policy Commands" },
{ 0x03, "Host Controller & Baseband Commands" },
@@ -523,7 +530,7 @@ static const value_string bthci_ogf_vals[] = {
{ 0x3F, "Vendor-Specific Commands" },
{ 0, NULL }
};
-value_string_ext bthci_ogf_vals_ext = VALUE_STRING_EXT_INIT(bthci_ogf_vals);
+value_string_ext bthci_cmd_ogf_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_ogf_vals);
static const value_string bthci_cmd_ocf_link_control_vals[] = {
/* Bluetooth Core 4.0 */
@@ -3076,7 +3083,7 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
{
proto_item *ti_cmd;
proto_tree *bthci_cmd_tree;
- guint16 opcode;
+ guint32 opcode;
guint16 ocf;
guint8 param_length;
guint8 ogf;
@@ -3085,12 +3092,24 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
proto_tree *opcode_tree;
gint hfx;
bluetooth_data_t *bluetooth_data;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 frame_number;
+ wmem_tree_key_t key[5];
+ bthci_cmd_data_t *bthci_cmd_data;
+ proto_tree *sub_item;
+ wmem_tree_t *subtree;
+
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
bluetooth_data = (bluetooth_data_t *) data;
+ interface_id = bluetooth_data->interface_id;
+ adapter_id = bluetooth_data->adapter_id;
+ frame_number = pinfo->fd->num;
+
ti_cmd = proto_tree_add_item(tree, proto_bthci_cmd, tvb, offset, -1, ENC_NA);
bthci_cmd_tree = proto_item_add_subtree(ti_cmd, ett_bthci_cmd);
@@ -3161,7 +3180,6 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
proto_tree_add_item(opcode_tree, hfx, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset+=2;
-
proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_param_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
param_length = tvb_get_guint8(tvb, offset);
offset++;
@@ -3172,12 +3190,6 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
if (!dissector_try_uint_new(vendor_dissector_table, HCI_VENDOR_DEFAULT, tvb, pinfo, tree, TRUE, bluetooth_data)) {
if (bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
- wmem_tree_key_t key[3];
- guint32 interface_id;
- guint32 adapter_id;
-
- interface_id = bluetooth_data->interface_id;
- adapter_id = bluetooth_data->adapter_id;
key[0].length = 1;
key[0].key = &interface_id;
@@ -3193,54 +3205,109 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
}
proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_parameter, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
-
- return tvb_captured_length(tvb);
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(opcode, &bthci_cmd_opcode_vals_ext, "Unknown 0x%04x"));
- }
-
- if (param_length > 0) {
- switch (ogf) {
- case HCI_OGF_LINK_CONTROL:
- offset = dissect_link_control_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
- break;
- case HCI_OGF_LINK_POLICY:
- offset = dissect_link_policy_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
- break;
+ if (param_length > 0) {
+ switch (ogf) {
+ case HCI_OGF_LINK_CONTROL:
+ offset = dissect_link_control_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
+ break;
- case HCI_OGF_HOST_CONTROLLER:
- offset = dissect_host_controller_baseband_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
- break;
+ case HCI_OGF_LINK_POLICY:
+ offset = dissect_link_policy_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
+ break;
- case HCI_OGF_INFORMATIONAL:
- offset = dissect_informational_parameters_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
- break;
+ case HCI_OGF_HOST_CONTROLLER:
+ offset = dissect_host_controller_baseband_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
+ break;
- case HCI_OGF_STATUS:
- offset = dissect_status_parameters_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
- break;
+ case HCI_OGF_INFORMATIONAL:
+ offset = dissect_informational_parameters_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
+ break;
- case HCI_OGF_TESTING:
- offset = dissect_testing_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
- break;
+ case HCI_OGF_STATUS:
+ offset = dissect_status_parameters_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
+ break;
- case HCI_OGF_LOW_ENERGY:
- offset = dissect_le_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
- break;
+ case HCI_OGF_TESTING:
+ offset = dissect_testing_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf);
+ break;
- default:
- proto_tree_add_expert(bthci_cmd_tree, pinfo, &ei_command_unknown_command, tvb, 3, -1);
- offset += tvb_reported_length_remaining(tvb, offset);
- break;
+ case HCI_OGF_LOW_ENERGY:
+ offset = dissect_le_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf, bluetooth_data);
+ break;
+ default:
+ proto_tree_add_expert(bthci_cmd_tree, pinfo, &ei_command_unknown_command, tvb, 3, -1);
+ offset += tvb_reported_length_remaining(tvb, offset);
+ break;
+ }
}
}
- if (tvb_reported_length_remaining(tvb, offset) > 0) {
+ if (!pinfo->fd->flags.visited && bluetooth_data) {
+ key[0].length = 1;
+ key[0].key = &interface_id;
+ key[1].length = 1;
+ key[1].key = &adapter_id;
+ key[2].length = 1;
+ key[2].key = &opcode;
+ key[3].length = 1;
+ key[3].key = &frame_number;
+ key[4].length = 0;
+ key[4].key = NULL;
+
+ bthci_cmd_data = (bthci_cmd_data_t *) wmem_new(wmem_file_scope(), bthci_cmd_data_t);
+ bthci_cmd_data->opcode = opcode;
+ bthci_cmd_data->command_in_frame = frame_number;
+ bthci_cmd_data->command_abs_ts = pinfo->fd->abs_ts;
+ bthci_cmd_data->pending_in_frame = max_disconnect_in_frame;
+ bthci_cmd_data->pending_abs_ts = pinfo->fd->abs_ts;
+ bthci_cmd_data->response_in_frame = max_disconnect_in_frame;
+ bthci_cmd_data->response_abs_ts = pinfo->fd->abs_ts;
+
+ wmem_tree_insert32_array(bthci_cmds, key, bthci_cmd_data);
+ }
+
+ if (ogf != HCI_OGF_VENDOR_SPECIFIC && tvb_reported_length_remaining(tvb, offset) > 0) {
proto_tree_add_expert(bthci_cmd_tree, pinfo, &ei_command_parameter_unexpected, tvb, offset, -1);
offset += tvb_reported_length_remaining(tvb, offset);
}
+ key[0].length = 1;
+ key[0].key = &interface_id;
+ key[1].length = 1;
+ key[1].key = &adapter_id;
+ key[2].length = 1;
+ key[2].key = &opcode;
+ key[3].length = 0;
+ key[3].key = NULL;
+
+ subtree = (wmem_tree_t *) wmem_tree_lookup32_array(bthci_cmds, key);
+ bthci_cmd_data = (subtree) ? (bthci_cmd_data_t *) wmem_tree_lookup32_le(subtree, pinfo->fd->num) : NULL;
+ if (bthci_cmd_data && bthci_cmd_data->pending_in_frame < max_disconnect_in_frame) {
+ nstime_t delta;
+
+ sub_item = proto_tree_add_uint(bthci_cmd_tree, hf_pending_in_frame, tvb, 0, 0, bthci_cmd_data->pending_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ nstime_delta(&delta, &bthci_cmd_data->pending_abs_ts, &bthci_cmd_data->command_abs_ts);
+ sub_item = proto_tree_add_double(bthci_cmd_tree, hf_command_pending_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+ if (bthci_cmd_data && bthci_cmd_data->response_in_frame < max_disconnect_in_frame) {
+ nstime_t delta;
+
+ sub_item = proto_tree_add_uint(bthci_cmd_tree, hf_response_in_frame, tvb, 0, 0, bthci_cmd_data->response_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ nstime_delta(&delta, &bthci_cmd_data->response_abs_ts, &bthci_cmd_data->command_abs_ts);
+ sub_item = proto_tree_add_double(bthci_cmd_tree, hf_command_response_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+
return offset;
}
@@ -3268,7 +3335,7 @@ proto_register_bthci_cmd(void)
},
{ &hf_bthci_cmd_ogf,
{ "Opcode Group Field", "bthci_cmd.opcode.ogf",
- FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_ogf_vals_ext, 0xfc00,
+ FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_cmd_ogf_vals_ext, 0xfc00,
NULL, HFILL }
},
{ &hf_bthci_cmd_ocf_link_control,
@@ -3719,7 +3786,7 @@ proto_register_bthci_cmd(void)
{ &hf_bthci_cmd_input_coding,
{ "Input Coding", "bthci_cmd.voice.input_coding",
FT_UINT16, BASE_DEC, VALS(cmd_input_coding_values), 0x0300,
- "Authentication Enable", HFILL }
+ NULL, HFILL }
},
{ &hf_bthci_cmd_input_data_format,
{ "Input Data Format", "bthci_cmd.voice.input_data_format",
@@ -4032,7 +4099,7 @@ proto_register_bthci_cmd(void)
NULL, HFILL }
},
{ &hf_bthci_cmd_num_handles,
- { "Number of Handles", "bthci_cmd.num_handles",
+ { "Number of Connection Handles", "bthci_cmd.num_handles",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
@@ -4708,6 +4775,26 @@ proto_register_bthci_cmd(void)
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_response_in_frame,
+ { "Response in frame", "bthci_cmd.response_in_frame",
+ FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_command_response_time_delta,
+ { "Command-Response Delta", "bthci_cmd.command_response_delta",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_pending_in_frame,
+ { "Pending in frame", "bthci_cmd.pending_in_frame",
+ FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_command_pending_time_delta,
+ { "Command-Pending Delta", "bthci_cmd.command_pending_delta",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
};
static ei_register_info ei[] = {
@@ -4768,6 +4855,8 @@ proto_register_bthci_cmd(void)
expert_bthci_cmd = expert_register_protocol(proto_bthci_cmd);
expert_register_field_array(expert_bthci_cmd, ei, array_length(ei));
+ bthci_cmds = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
+
vendor_dissector_table = register_dissector_table("bthci_cmd.vendor", "BT HCI Vendor", FT_UINT16, BASE_HEX);
module = prefs_register_protocol(proto_bthci_cmd, NULL);
diff --git a/epan/dissectors/packet-bthci_cmd.h b/epan/dissectors/packet-bthci_cmd.h
new file mode 100644
index 0000000000..c9d3dd4f96
--- /dev/null
+++ b/epan/dissectors/packet-bthci_cmd.h
@@ -0,0 +1,79 @@
+/* packet-bthci_cmd.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 __PACKET_BTHCI_CMD_H__
+#define __PACKET_BTHCI_CMD_H__
+
+extern value_string_ext bthci_cmd_opcode_vals_ext;
+extern value_string_ext bthci_cmd_ogf_vals_ext;
+extern value_string_ext bthci_cmd_ocf_link_control_vals_ext;
+extern value_string_ext bthci_cmd_ocf_link_policy_vals_ext;
+extern value_string_ext bthci_cmd_ocf_host_controller_and_baseband_vals_ext;
+extern value_string_ext bthci_cmd_ocf_informational_vals_ext;
+extern value_string_ext bthci_cmd_ocf_status_vals_ext;
+extern value_string_ext bthci_cmd_ocf_testing_vals_ext;
+extern value_string_ext bthci_cmd_ocf_low_energy_vals_ext;
+
+extern value_string_ext bthci_cmd_input_coding_vals_ext;
+extern value_string_ext bthci_cmd_input_data_format_vals_ext;
+extern value_string_ext bthci_cmd_input_sample_size_vals_ext;
+extern value_string_ext bthci_cmd_air_coding_format_vals_ext;
+extern value_string_ext bthci_cmd_status_vals_ext;
+extern value_string_ext bthci_cmd_eir_data_type_vals_ext;
+extern value_string_ext bthci_cmd_auth_req_vals_ext;
+extern value_string_ext bthci_cmd_appearance_vals_ext;
+
+extern const value_string bthci_cmd_io_capability_vals[];
+extern const value_string bthci_cmd_oob_data_present_vals[];
+extern const value_string bthci_cmd_address_types_vals[];
+extern const value_string bthci_cmd_scan_enable_values[];
+extern const value_string bthci_cmd_page_scan_modes[];
+extern const value_string bthci_cmd_page_scan_repetition_modes[];
+extern const value_string bthci_cmd_page_scan_period_modes[];
+extern const value_string bthci_cmd_notification_types[];
+
+typedef struct _bthci_cmd_data_t {
+ guint32 opcode;
+
+ guint32 command_in_frame;
+ nstime_t command_abs_ts;
+ guint32 pending_in_frame;
+ nstime_t pending_abs_ts;
+ guint32 response_in_frame;
+ nstime_t response_abs_ts;
+} bthci_cmd_data_t;
+
+extern wmem_tree_t *bthci_cmds;
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c
index ad7fb5e543..cda764325a 100644
--- a/epan/dissectors/packet-bthci_evt.c
+++ b/epan/dissectors/packet-bthci_evt.c
@@ -40,6 +40,7 @@
#include "packet-bluetooth.h"
#include "packet-bthci_sco.h"
+#include "packet-bthci_cmd.h"
static dissector_handle_t bthci_cmd_handle;
static dissector_handle_t bthci_evt_handle;
@@ -348,6 +349,12 @@ static int hf_bthci_evt_le_states_33 = -1;
static int hf_bthci_evt_le_states_34 = -1;
static int hf_usable_packet_types = -1;
static int hf_changed_in_frame = -1;
+static int hf_command_in_frame = -1;
+static int hf_pending_in_frame = -1;
+static int hf_response_in_frame = -1;
+static int hf_command_pending_time_delta = -1;
+static int hf_command_response_time_delta = -1;
+static int hf_pending_response_time_delta = -1;
static expert_field ei_event_undecoded = EI_INIT;
static expert_field ei_event_unknown_event = EI_INIT;
@@ -370,19 +377,30 @@ extern value_string_ext ext_usb_vendors_vals;
extern value_string_ext ext_usb_products_vals;
extern value_string_ext did_vendor_id_source_vals_ext;
+enum command_status {
+ COMMAND_STATUS_NORMAL,
+ COMMAND_STATUS_PENDING,
+ COMMAND_STATUS_RESULT
+};
+
+typedef struct _opcode_list_data_t {
+ guint16 opcode;
+ enum command_status command_status;
+} opcode_list_data_t;
+
static const value_string evt_code_vals[] = {
{0x01, "Inquiry Complete"},
{0x02, "Inquiry Result"},
{0x03, "Connect Complete"},
{0x04, "Connect Request"},
{0x05, "Disconnect Complete"},
- {0x06, "Auth Complete"},
- {0x07, "Remote Name Req Complete"},
- {0x08, "Encrypt Change"},
+ {0x06, "Authentication Complete"},
+ {0x07, "Remote Name Request Complete"},
+ {0x08, "Encryption Change"},
{0x09, "Change Connection Link Key Complete"},
{0x0a, "Master Link Key Complete"},
{0x0b, "Read Remote Supported Features"},
- {0x0c, "Read Remote Ver Info Complete"},
+ {0x0c, "Read Remote Version Information Complete"},
{0x0d, "QoS Setup Complete"},
{0x0e, "Command Complete"},
{0x0f, "Command Status"},
@@ -719,6 +737,17 @@ static gpointer bthci_evt_vendor_value(packet_info *pinfo _U_)
return NULL;
}
+static void add_opcode(wmem_list_t *opcode_list, guint16 opcode, enum command_status command_status) {
+ opcode_list_data_t *opcode_list_data;
+
+ opcode_list_data = wmem_new(wmem_packet_scope(), opcode_list_data_t);
+ if (opcode_list_data) {
+ opcode_list_data->opcode = opcode;
+ opcode_list_data->command_status = command_status;
+ wmem_list_append(opcode_list, opcode_list_data);
+ }
+}
+
static void
save_remote_device_name(tvbuff_t *tvb, gint offset, packet_info *pinfo,
guint8 size, guint8 *bd_addr, bluetooth_data_t *bluetooth_data)
@@ -1479,7 +1508,8 @@ dissect_bthci_evt_conn_packet_type_changed(tvbuff_t *tvb, int offset, packet_inf
static int
dissect_bthci_evt_command_status(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *main_tree, proto_tree *tree, bluetooth_data_t *bluetooth_data)
+ proto_tree *main_tree, proto_tree *tree, wmem_list_t *opcode_list,
+ bluetooth_data_t *bluetooth_data)
{
proto_item *ti_opcode;
proto_tree *opcode_tree;
@@ -1504,6 +1534,11 @@ dissect_bthci_evt_command_status(tvbuff_t *tvb, int offset, packet_info *pinfo,
opcode = tvb_get_letohs(tvb, offset);
ogf = opcode >> 10;
+ if (status_code != 0)
+ add_opcode(opcode_list, opcode, COMMAND_STATUS_RESULT);
+ else
+ add_opcode(opcode_list, opcode, COMMAND_STATUS_PENDING);
+
ti_opcode = proto_tree_add_item(tree, hf_bthci_evt_opcode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
opcode_tree = proto_item_add_subtree(ti_opcode, ett_opcode);
proto_tree_add_item(opcode_tree, hf_bthci_evt_ogf, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -1715,7 +1750,7 @@ dissect_bthci_evt_remote_host_sup_feat_notification(tvbuff_t *tvb, int offset, p
static int
dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, bluetooth_data_t *bluetooth_data)
+ proto_tree *tree, wmem_list_t *opcode_list, bluetooth_data_t *bluetooth_data)
{
proto_item *item;
guint8 subevent_code;
@@ -1802,6 +1837,8 @@ dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo,
wmem_tree_insert32_array(bluetooth_data->chandle_sessions, key, chandle_session);
}
+ add_opcode(opcode_list, 0x200D, COMMAND_STATUS_NORMAL); /* LE Create Connection */
+
break;
case 0x02: /* LE Advertising Report */
{
@@ -1845,6 +1882,8 @@ dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo,
item = proto_tree_add_item(tree, hf_bthci_evt_le_supervision_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
proto_item_append_text(item, " (%g sec)", tvb_get_letohs(tvb, offset)*0.01);
offset += 2;
+
+ add_opcode(opcode_list, 0x2013, COMMAND_STATUS_NORMAL); /* LE Connection Update */
break;
case 0x04: /* LE Read Remote Used Features Complete */
proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -1853,6 +1892,8 @@ dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo,
offset += 2;
proto_tree_add_item(tree, hf_bthci_evt_le_feature_00, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 8;
+
+ add_opcode(opcode_list, 0x2016, COMMAND_STATUS_NORMAL); /* LE Read Remote Used Features */
break;
case 0x05: /* LE Long Term Key Request */
proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -2029,7 +2070,8 @@ dissect_bthci_evt_amp_status_change(tvbuff_t *tvb, int offset, packet_info *pinf
static int
dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *main_tree, proto_tree *tree, bluetooth_data_t *bluetooth_data)
+ packet_info *pinfo, proto_tree *main_tree, proto_tree *tree,
+ wmem_list_t *opcode_list, bluetooth_data_t *bluetooth_data)
{
proto_item *ti_opcode;
proto_tree *opcode_tree;
@@ -2037,13 +2079,17 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
gint16 timeout;
guint8 num8;
guint i;
- guint16 opcode;
guint8 ogf;
guint32 accuracy;
guint8 bd_addr[6];
gboolean local_addr = FALSE;
gint hfx;
guint16 status;
+ wmem_tree_key_t key[4];
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 frame_number;
+ guint32 opcode;
proto_tree_add_item(tree, hf_bthci_evt_num_command_packets, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -2051,6 +2097,10 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
opcode = tvb_get_letohs(tvb, offset);
ogf = opcode >> 10;
+ interface_id = bluetooth_data->interface_id;
+ adapter_id = bluetooth_data->adapter_id;
+ frame_number = pinfo->fd->num;
+
ti_opcode = proto_tree_add_item(tree, hf_bthci_evt_opcode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
opcode_tree = proto_item_add_subtree(ti_opcode, ett_opcode);
proto_tree_add_item(opcode_tree, hf_bthci_evt_ogf, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -2082,9 +2132,6 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
if (!dissector_try_uint_new(vendor_dissector_table, HCI_VENDOR_DEFAULT, tvb, pinfo, main_tree, TRUE, bluetooth_data)) {
if (bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
- wmem_tree_key_t key[3];
- guint32 interface_id;
- guint32 adapter_id;
interface_id = bluetooth_data->interface_id;
adapter_id = bluetooth_data->adapter_id;
@@ -2103,14 +2150,13 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
}
proto_tree_add_item(tree, hf_bthci_evt_ret_params, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
-
- return tvb_captured_length(tvb);
+ offset = tvb_captured_length(tvb);
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
val_to_str_ext(opcode, &bthci_cmd_opcode_vals_ext, "Unknown 0x%04x"));
}
- switch(opcode) {
+ if (ogf != HCI_OGF_VENDOR_SPECIFIC) switch(opcode) {
/* This is a list of Commands that all return just the status */
case 0x0402: /* Inquiry Cancel */
case 0x0403: /* Periodic Inquiry Mode */
@@ -2205,28 +2251,24 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
offset = dissect_bd_addr(hf_bthci_evt_bd_addr, tree, tvb, offset, bd_addr);
if (!pinfo->fd->flags.visited && bluetooth_data != NULL && local_addr) {
- wmem_tree_key_t key[4];
- guint32 k_interface_id;
- guint32 k_adapter_id;
- guint32 k_frame_number;
localhost_bdaddr_entry_t *localhost_bdaddr_entry;
- k_interface_id = bluetooth_data->interface_id;
- k_adapter_id = bluetooth_data->adapter_id;
- k_frame_number = pinfo->fd->num;
+ interface_id = bluetooth_data->interface_id;
+ adapter_id = bluetooth_data->adapter_id;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_frame_number;
+ key[2].key = &frame_number;
key[3].length = 0;
key[3].key = NULL;
localhost_bdaddr_entry = (localhost_bdaddr_entry_t *) wmem_new(wmem_file_scope(), localhost_bdaddr_entry_t);
- localhost_bdaddr_entry->interface_id = k_interface_id;
- localhost_bdaddr_entry->adapter_id = k_adapter_id;
+ localhost_bdaddr_entry->interface_id = interface_id;
+ localhost_bdaddr_entry->adapter_id = adapter_id;
memcpy(localhost_bdaddr_entry->bd_addr, bd_addr, 6);
wmem_tree_insert32_array(bluetooth_data->localhost_bdaddr, key, localhost_bdaddr_entry);
}
@@ -2403,31 +2445,23 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
proto_tree_add_item(tree, hf_bthci_evt_device_name, tvb, offset, 248, ENC_ASCII|ENC_NA);
if (!pinfo->fd->flags.visited && bluetooth_data != NULL) {
- wmem_tree_key_t key[4];
- guint32 k_interface_id;
- guint32 k_adapter_id;
- guint32 k_frame_number;
gchar *name;
localhost_name_entry_t *localhost_name_entry;
- k_interface_id = bluetooth_data->interface_id;
- k_adapter_id = bluetooth_data->adapter_id;
- k_frame_number = pinfo->fd->num;
-
name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 248, ENC_ASCII);
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_frame_number;
+ key[2].key = &frame_number;
key[3].length = 0;
key[3].key = NULL;
localhost_name_entry = (localhost_name_entry_t *) wmem_new(wmem_file_scope(), localhost_name_entry_t);
- localhost_name_entry->interface_id = k_interface_id;
- localhost_name_entry->adapter_id = k_adapter_id;
+ localhost_name_entry->interface_id = interface_id;
+ localhost_name_entry->adapter_id = adapter_id;
localhost_name_entry->name = wmem_strdup(wmem_file_scope(), name);
wmem_tree_insert32_array(bluetooth_data->localhost_name, key, localhost_name_entry);
@@ -2720,16 +2754,10 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
if (status == STATUS_SUCCESS && bluetooth_data) {
hci_vendor_data_t *hci_vendor_data;
- wmem_tree_key_t key[3];
- guint32 interface_id;
- guint32 adapter_id;
guint16 hci_revision;
guint16 manufacturer;
guint16 lmp_subversion;
- interface_id = bluetooth_data->interface_id;
- adapter_id = bluetooth_data->adapter_id;
-
key[0].length = 1;
key[0].key = &interface_id;
key[1].length = 1;
@@ -2744,8 +2772,8 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
lmp_subversion = tvb_get_letohs(tvb, offset - 2);
if (hci_vendor_data) {
- proto_item *sub_item;
proto_tree *sub_tree;
+ proto_item *sub_item;
if (manufacturer != hci_vendor_data->manufacturer) {
expert_add_info(pinfo, manufacturer_item, &ei_manufacturer_data_changed);
@@ -3036,8 +3064,8 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
case 0x2015: /* LE Read Channel Map */
{
- proto_item *sub_item;
proto_tree *sub_tree;
+ proto_item *sub_item;
proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -3133,6 +3161,8 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset,
break;
}
+ add_opcode(opcode_list, opcode, COMMAND_STATUS_NORMAL);
+
return offset;
}
@@ -3236,9 +3266,14 @@ dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, bluetooth_data_t *bluetooth_data)
{
proto_item *item;
- guint16 connection_handle;
+ guint32 connection_handle;
guint8 bd_addr[6];
guint8 status;
+ wmem_tree_key_t key[5];
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 frame_number;
+ wmem_tree_t *subtree;
proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
status = tvb_get_guint8(tvb, offset);
@@ -3270,32 +3305,25 @@ dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset,
proto_tree_add_item(tree, hf_bthci_evt_air_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
+ interface_id = bluetooth_data->interface_id;
+ adapter_id = bluetooth_data->adapter_id;
+ frame_number = pinfo->fd->num;
if (!pinfo->fd->flags.visited && status == 0x00) {
- wmem_tree_key_t key[5];
- guint32 k_interface_id;
- guint32 k_adapter_id;
- guint32 k_connection_handle;
- guint32 k_frame_number;
remote_bdaddr_t *remote_bdaddr;
chandle_session_t *chandle_session;
bthci_sco_stream_number_t *sco_stream_number;
guint32 stream_number;
- k_interface_id = bluetooth_data->interface_id;
- k_adapter_id = bluetooth_data->adapter_id;
- k_connection_handle = connection_handle;
- k_frame_number = pinfo->fd->num;
-
/* chandle to bdaddr */
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_connection_handle;
+ key[2].key = &connection_handle;
key[3].length = 1;
- key[3].key = &k_frame_number;
+ key[3].key = &frame_number;
key[4].length = 0;
key[4].key = NULL;
@@ -3309,7 +3337,7 @@ dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset,
/* chandle session */
chandle_session = (chandle_session_t *) wmem_new(wmem_file_scope(), chandle_session_t);
- chandle_session->connect_in_frame = k_frame_number;
+ chandle_session->connect_in_frame = frame_number;
chandle_session->disconnect_in_frame = max_disconnect_in_frame;
wmem_tree_insert32_array(bluetooth_data->chandle_sessions, key, chandle_session);
@@ -3501,19 +3529,25 @@ dissect_bthci_evt_inquire_result(tvbuff_t *tvb, int offset, packet_info *pinfo,
static gint
dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- proto_item *ti;
- proto_tree *bthci_evt_tree;
- guint8 param_length, evt_code;
- guint8 bd_addr[6];
- gint offset = 0;
- gint previous_offset = 0;
- bluetooth_data_t *bluetooth_data;
+ proto_item *ti;
+ proto_tree *bthci_evt_tree;
+ guint8 param_length, evt_code;
+ guint8 bd_addr[6];
+ gint offset = 0;
+ gint previous_offset = 0;
+ bluetooth_data_t *bluetooth_data;
+ wmem_list_t *opcode_list;
+ wmem_list_frame_t *opcode_list_frame;
+ bthci_cmd_data_t *lastest_bthci_cmd_data = NULL;
+ opcode_list_data_t *opcode_list_data;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
bluetooth_data = (bluetooth_data_t *) data;
+ opcode_list = wmem_list_new(wmem_packet_scope());
+
ti = proto_tree_add_item(tree, proto_bthci_evt, tvb, offset, -1, ENC_NA);
bthci_evt_tree = proto_item_add_subtree(ti, ett_bthci_evt);
@@ -3565,6 +3599,8 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
switch(evt_code) {
case 0x01: /* Inquiry Complete */
offset = dissect_bthci_evt_inquire_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x0401, COMMAND_STATUS_NORMAL); /* Inquiry */
+ add_opcode(opcode_list, 0x0403, COMMAND_STATUS_NORMAL); /* Periodic Inquiry Mode */
break;
case 0x02: /* Inquiry result event */
@@ -3573,6 +3609,10 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x03: /* Connection Complete */
offset = dissect_bthci_evt_connect_complete(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x0405, COMMAND_STATUS_NORMAL); /* Create Connection */
+ add_opcode(opcode_list, 0x0409, COMMAND_STATUS_NORMAL); /* Accept Connection Request */
+ add_opcode(opcode_list, 0x040A, COMMAND_STATUS_NORMAL); /* Reject Connection Request */
+ add_opcode(opcode_list, 0x043E, COMMAND_STATUS_NORMAL); /* Enhanced Accept Synchronous Connection Request */
break;
case 0x04: /* Connection Request */
@@ -3581,18 +3621,23 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x05: /* Disconnection Complete */
offset = dissect_bthci_evt_disconnect_complete(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x0406, COMMAND_STATUS_NORMAL); /* Disconnection Connection */
break;
case 0x06: /* Authentication Complete */
offset = dissect_bthci_evt_auth_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x0411, COMMAND_STATUS_NORMAL); /* Authentication Requested */
break;
case 0x07: /* Remote Name Request Complete */
offset = dissect_bthci_evt_remote_name_req_complete(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x0419, COMMAND_STATUS_NORMAL); /* Remote Name Request */
break;
case 0x08: /* Encryption Change */
offset = dissect_bthci_evt_encryption_change(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x0413, COMMAND_STATUS_NORMAL); /* Encryption Requested */
+ add_opcode(opcode_list, 0x2019, COMMAND_STATUS_NORMAL); /* LE Start Encryption */
break;
case 0x09: /* Change Connection Link Key Complete */
@@ -3605,10 +3650,12 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x0b: /* Read Remote Support Features Complete */
offset = dissect_bthci_evt_read_remote_support_features_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x41B, COMMAND_STATUS_NORMAL); /* Read Remote Supported Features */
break;
case 0x0c: /* Read Remote Version Information Complete */
offset = dissect_bthci_evt_read_remote_version_information_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x41D, COMMAND_STATUS_NORMAL); /* Read Remote Version Information */
break;
case 0x0d: /* QoS Setup Complete */
@@ -3616,11 +3663,12 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
break;
case 0x0e: /* Command Complete */
- offset = dissect_bthci_evt_command_complete(tvb, offset, pinfo, tree, bthci_evt_tree, bluetooth_data);
+ offset = dissect_bthci_evt_command_complete(tvb, offset, pinfo, tree, bthci_evt_tree, opcode_list, bluetooth_data);
+ add_opcode(opcode_list, 0x0429, COMMAND_STATUS_NORMAL); /* Accept Synchronous Connection Request */
break;
case 0x0f: /* Command Status */
- offset = dissect_bthci_evt_command_status(tvb, offset, pinfo, tree, bthci_evt_tree, bluetooth_data);
+ offset = dissect_bthci_evt_command_status(tvb, offset, pinfo, tree, bthci_evt_tree, opcode_list, bluetooth_data);
break;
case 0x10: /* Hardware Error */
@@ -3633,6 +3681,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x12: /* Role Change */
offset = dissect_bthci_evt_role_change(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x080B, COMMAND_STATUS_NORMAL); /* Switch Role */
break;
case 0x13: /* Number Of Completed Packets */
@@ -3641,6 +3690,8 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x14: /* Mode Change */
offset = dissect_bthci_evt_mode_change(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x0803, COMMAND_STATUS_NORMAL); /* Sniff Mode */
+ add_opcode(opcode_list, 0x0804, COMMAND_STATUS_NORMAL); /* Exit Sniff Mode */
break;
case 0x15: /* Return Link Keys */
@@ -3677,6 +3728,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x1d: /* Connection Packet Type Changed */
offset = dissect_bthci_evt_conn_packet_type_changed(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x040F, COMMAND_STATUS_NORMAL); /* Change Connection Packet Type */
break;
case 0x1e: /* QoS Violation */
@@ -3701,14 +3753,20 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x23: /* Read Remote Extended Features Complete */
offset = dissect_bthci_evt_read_remote_ext_features_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x41C, COMMAND_STATUS_NORMAL); /* Read Remote Supported Features */
break;
case 0x2c: /* Synchronous Connection Complete */
offset = dissect_bthci_evt_sync_connection_complete(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ add_opcode(opcode_list, 0x0429, COMMAND_STATUS_NORMAL); /* Accept Synchronous Connection Request */
+ add_opcode(opcode_list, 0x0428, COMMAND_STATUS_NORMAL); /* Setup Synchronous Connection */
+ add_opcode(opcode_list, 0x043D, COMMAND_STATUS_NORMAL); /* Enhanced Setup Synchronous Connection */
+ add_opcode(opcode_list, 0x043E, COMMAND_STATUS_NORMAL); /* Enhanced Accept Synchronous Connection Request */
break;
case 0x2d: /* Synchronous Connection Changed */
offset = dissect_bthci_evt_sync_connection_changed(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x043D, COMMAND_STATUS_NORMAL); /* Enhanced Setup Synchronous Connection */
break;
case 0x2e: /* Sniff Subrating */
@@ -3727,6 +3785,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case 0x30: /* Encryption Key Refresh Complete */
offset = dissect_bthci_evt_encryption_key_refresh_complete(tvb, offset, pinfo, bthci_evt_tree);
+ add_opcode(opcode_list, 0x2019, COMMAND_STATUS_NORMAL); /* LE Start Encryption */
break;
case 0x31: /* IO Capability Request */
@@ -3774,7 +3833,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
break;
case 0x3e: /* LE Meta */
- offset = dissect_bthci_evt_le_meta(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data);
+ offset = dissect_bthci_evt_le_meta(tvb, offset, pinfo, bthci_evt_tree, opcode_list, bluetooth_data);
break;
case 0x40: /* Physical Link Complete */
@@ -3878,6 +3937,147 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
}
+ opcode_list_frame = wmem_list_head(opcode_list);
+
+ while (opcode_list_frame) {
+ wmem_tree_key_t key[4];
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 opcode;
+ guint32 frame_number;
+ bthci_cmd_data_t *bthci_cmd_data;
+ wmem_tree_t *subtree;
+ gint i_frame_number;
+
+ interface_id = bluetooth_data->interface_id;
+ adapter_id = bluetooth_data->adapter_id;
+ frame_number = pinfo->fd->num;
+
+ opcode_list_data = (opcode_list_data_t *) wmem_list_frame_data(opcode_list_frame);
+ opcode = opcode_list_data->opcode;
+
+ key[0].length = 1;
+ key[0].key = &interface_id;
+ key[1].length = 1;
+ key[1].key = &adapter_id;
+ key[2].length = 1;
+ key[2].key = &opcode;
+ key[3].length = 0;
+ key[3].key = NULL;
+
+ subtree = (wmem_tree_t *) wmem_tree_lookup32_array(bthci_cmds, key);
+
+ i_frame_number = frame_number;
+
+ do {
+ bthci_cmd_data = (subtree) ? (bthci_cmd_data_t *) wmem_tree_lookup32_le(subtree, i_frame_number) : NULL;
+ if (bthci_cmd_data && bthci_cmd_data->command_in_frame < frame_number && (
+ (opcode_list_data->command_status == COMMAND_STATUS_NORMAL &&
+ (bthci_cmd_data->response_in_frame == frame_number ||
+ bthci_cmd_data->response_in_frame == max_disconnect_in_frame)) ||
+ (opcode_list_data->command_status == COMMAND_STATUS_PENDING &&
+ (bthci_cmd_data->pending_in_frame == frame_number ||
+ ((bthci_cmd_data->response_in_frame == max_disconnect_in_frame ||
+ bthci_cmd_data->response_in_frame > frame_number) &&
+ bthci_cmd_data->pending_in_frame == max_disconnect_in_frame))) ||
+ (opcode_list_data->command_status == COMMAND_STATUS_RESULT &&
+ (bthci_cmd_data->response_in_frame == frame_number ||
+ ((bthci_cmd_data->response_in_frame == max_disconnect_in_frame &&
+ bthci_cmd_data->pending_in_frame == max_disconnect_in_frame))))
+ )) {
+ lastest_bthci_cmd_data = bthci_cmd_data;
+ if (((opcode_list_data->command_status == COMMAND_STATUS_RESULT ||
+ opcode_list_data->command_status == COMMAND_STATUS_NORMAL) &&
+ bthci_cmd_data->response_in_frame == frame_number) ||
+ (opcode_list_data->command_status == COMMAND_STATUS_PENDING &&
+ bthci_cmd_data->pending_in_frame == frame_number)) {
+ opcode_list_frame = NULL;
+ break;
+ }
+ }
+
+ if (bthci_cmd_data && bthci_cmd_data->command_in_frame < frame_number) {
+ i_frame_number = bthci_cmd_data->command_in_frame - 1;
+ if (i_frame_number < 1)
+ bthci_cmd_data = NULL;
+ } else {
+ bthci_cmd_data = NULL;
+ }
+ } while (bthci_cmd_data);
+
+ if (opcode_list_frame)
+ opcode_list_frame = wmem_list_frame_next(opcode_list_frame);
+ }
+
+ if (lastest_bthci_cmd_data) {
+ proto_item *sub_item;
+ guint32 frame_number;
+ nstime_t delta;
+
+ frame_number = pinfo->fd->num;
+
+ if (!pinfo->fd->flags.visited && opcode_list_data->command_status == COMMAND_STATUS_PENDING &&
+ lastest_bthci_cmd_data->pending_in_frame == max_disconnect_in_frame) {
+ lastest_bthci_cmd_data->pending_in_frame = frame_number;
+ lastest_bthci_cmd_data->pending_abs_ts = pinfo->fd->abs_ts;
+ }
+
+ if (!pinfo->fd->flags.visited && opcode_list_data->command_status == COMMAND_STATUS_NORMAL &&
+ lastest_bthci_cmd_data->response_in_frame == max_disconnect_in_frame) {
+ lastest_bthci_cmd_data->response_in_frame = frame_number;
+ lastest_bthci_cmd_data->response_abs_ts = pinfo->fd->abs_ts;
+ }
+
+ if (!pinfo->fd->flags.visited && opcode_list_data->command_status == COMMAND_STATUS_RESULT &&
+ lastest_bthci_cmd_data->response_in_frame == max_disconnect_in_frame &&
+ lastest_bthci_cmd_data->pending_in_frame == max_disconnect_in_frame) {
+ lastest_bthci_cmd_data->response_in_frame = frame_number;
+ lastest_bthci_cmd_data->response_abs_ts = pinfo->fd->abs_ts;
+ }
+
+ if (lastest_bthci_cmd_data->pending_in_frame == frame_number) {
+ sub_item = proto_tree_add_uint(bthci_evt_tree, hf_command_in_frame, tvb, 0, 0, lastest_bthci_cmd_data->command_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ if (lastest_bthci_cmd_data->response_in_frame < max_disconnect_in_frame) {
+ sub_item = proto_tree_add_uint(bthci_evt_tree, hf_response_in_frame, tvb, 0, 0, lastest_bthci_cmd_data->response_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+
+ nstime_delta(&delta, &lastest_bthci_cmd_data->pending_abs_ts, &lastest_bthci_cmd_data->command_abs_ts);
+ sub_item = proto_tree_add_double(bthci_evt_tree, hf_command_pending_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ if (lastest_bthci_cmd_data->response_in_frame < max_disconnect_in_frame) {
+ nstime_delta(&delta, &lastest_bthci_cmd_data->response_abs_ts, &lastest_bthci_cmd_data->pending_abs_ts);
+ sub_item = proto_tree_add_double(bthci_evt_tree, hf_pending_response_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+ }
+
+ if (lastest_bthci_cmd_data->response_in_frame == frame_number) {
+ sub_item = proto_tree_add_uint(bthci_evt_tree, hf_command_in_frame, tvb, 0, 0, lastest_bthci_cmd_data->command_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ if (lastest_bthci_cmd_data->pending_in_frame < max_disconnect_in_frame) {
+ sub_item = proto_tree_add_uint(bthci_evt_tree, hf_pending_in_frame, tvb, 0, 0, lastest_bthci_cmd_data->pending_in_frame);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ nstime_delta(&delta, &lastest_bthci_cmd_data->response_abs_ts, &lastest_bthci_cmd_data->pending_abs_ts);
+ sub_item = proto_tree_add_double(bthci_evt_tree, hf_pending_response_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+
+ nstime_delta(&delta, &lastest_bthci_cmd_data->response_abs_ts, &lastest_bthci_cmd_data->command_abs_ts);
+ sub_item = proto_tree_add_double(bthci_evt_tree, hf_command_response_time_delta, tvb, 0, 0, nstime_to_msec(&delta));
+ proto_item_append_text(sub_item, " ms");
+ PROTO_ITEM_SET_GENERATED(sub_item);
+ }
+ }
+
return offset;
}
@@ -3931,7 +4131,7 @@ proto_register_bthci_evt(void)
},
{ &hf_bthci_evt_ogf,
{ "Opcode Group Field", "bthci_evt.opcode.ogf",
- FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_ogf_vals_ext, 0xfc00,
+ FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_cmd_ogf_vals_ext, 0xfc00,
NULL, HFILL }
},
{ &hf_bthci_evt_ocf_link_control,
@@ -4642,7 +4842,7 @@ proto_register_bthci_evt(void)
{ &hf_bthci_evt_input_coding,
{ "Input Coding", "bthci_evt.voice.input_coding",
FT_UINT16, BASE_DEC | BASE_EXT_STRING, &bthci_cmd_input_coding_vals_ext, 0x0300,
- "Authentication Enable", HFILL }
+ NULL, HFILL }
},
{ &hf_bthci_evt_input_data_format,
{ "Input Data Format", "bthci_evt.voice.input_data_format",
@@ -5383,7 +5583,37 @@ proto_register_bthci_evt(void)
{ "Change in Frame", "bthci_evt.change_in_frame",
FT_FRAMENUM, BASE_NONE, NULL, 0x0,
NULL, HFILL }
- }
+ },
+ { &hf_command_in_frame,
+ { "Command in frame", "bthci_evt.command_in_frame",
+ FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pending_in_frame,
+ { "Pending in frame", "bthci_evt.pending_in_frame",
+ FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_response_in_frame,
+ { "Response in frame", "bthci_evt.response_in_frame",
+ FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_command_response_time_delta,
+ { "Command-Response Delta", "bthci_evt.command_response_delta",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_command_pending_time_delta,
+ { "Command-Pending Delta", "bthci_evt.command_pending_delta",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_pending_response_time_delta,
+ { "Pending-Response Delta", "bthci_evt.pending_response_delta",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
};
static ei_register_info ei[] = {
diff --git a/epan/dissectors/packet-bthci_evt.h b/epan/dissectors/packet-bthci_evt.h
new file mode 100644
index 0000000000..5df9dad563
--- /dev/null
+++ b/epan/dissectors/packet-bthci_evt.h
@@ -0,0 +1,40 @@
+/* packet-bthci_evt.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 __PACKET_BTHCI_EVT_H__
+#define __PACKET_BTHCI_EVT_H__
+
+extern value_string_ext bthci_evt_evt_code_vals_ext;
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/dissectors/packet-bthci_vendor.c b/epan/dissectors/packet-bthci_vendor.c
index e4bd4c26fe..d2fbcc43da 100644
--- a/epan/dissectors/packet-bthci_vendor.c
+++ b/epan/dissectors/packet-bthci_vendor.c
@@ -28,6 +28,8 @@
#include <epan/expert.h>
#include "packet-bluetooth.h"
+#include "packet-bthci_cmd.h"
+#include "packet-bthci_evt.h"
static int proto_bthci_vendor_broadcom = -1;
@@ -934,7 +936,7 @@ proto_register_bthci_vendor_broadcom(void)
},
{ &hf_opcode_ogf,
{ "Opcode Group Field", "bthci_vendor.broadcom.opcode.ogf",
- FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_ogf_vals_ext, 0xfc00,
+ FT_UINT16, BASE_HEX|BASE_EXT_STRING, &bthci_cmd_ogf_vals_ext, 0xfc00,
NULL, HFILL }
},
{ &hf_opcode_ocf,
diff --git a/epan/dissectors/packet-btle.c b/epan/dissectors/packet-btle.c
index 4f286dedae..91fd6d7f8d 100644
--- a/epan/dissectors/packet-btle.c
+++ b/epan/dissectors/packet-btle.c
@@ -33,6 +33,7 @@
#include <wiretap/wtap.h>
#include "packet-btle.h"
+#include "packet-bthci_cmd.h"
#include "packet-bthci_acl.h"
static int proto_btle = -1;