diff options
author | Anders Broman <anders.broman@ericsson.com> | 2012-10-22 12:49:04 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2012-10-22 12:49:04 +0000 |
commit | 576b37ddd80ecb24ab713b78c9d8bc0b001e544a (patch) | |
tree | 917f53c818e60e5869565a97e218b82e6ff4d6dc | |
parent | 007a0b28aec261bf54559d5ac84672c67f82e8b0 (diff) |
from Allan M. Madsen:
Add support for HCI 3.0+HS and v4.0, Bluetooth Low Energy. This includes
dissection of additional HCI commands and events, Attribute Protocol and
Security Manager Protocol.
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7872
svn path=/trunk/; revision=45709
-rw-r--r-- | AUTHORS | 5 | ||||
-rw-r--r-- | epan/CMakeLists.txt | 2 | ||||
-rw-r--r-- | epan/dissectors/Makefile.common | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-btatt.c | 696 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_cmd.c | 1367 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_evt.c | 1484 | ||||
-rw-r--r-- | epan/dissectors/packet-btl2cap.c | 92 | ||||
-rw-r--r-- | epan/dissectors/packet-btl2cap.h | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-btsmp.c | 408 | ||||
-rw-r--r-- | epan/dissectors/packet-hci_h4.h | 9 |
10 files changed, 3911 insertions, 158 deletions
@@ -3116,8 +3116,11 @@ Levi Pearson <levi.pearson[AT]harman.com> { IEEE 1722(AVB Transport Protocol) dissector } -Allan M. Madsen <allan.m[AT]madsen.mail.dk> { +Allan M. Madsen <allan.m[AT]madsen.dk> { + Bluetooth HCI cmd/evt dissectors ver. 2.1-4.0 support + Bluetooth ATT dissector Bluetooth OBEX dissector + Bluetooth SMP dissector } Slava <slavak[AT]gmail.com> { diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 26663b98a3..204735782b 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -393,6 +393,7 @@ set(DISSECTOR_SRC dissectors/packet-bt-dht.c dissectors/packet-bt-utp.c dissectors/packet-btamp.c + dissectors/packet-btatt.c dissectors/packet-btbnep.c dissectors/packet-btavctp.c dissectors/packet-btavrcp.c @@ -407,6 +408,7 @@ set(DISSECTOR_SRC dissectors/packet-btrfcomm.c dissectors/packet-btsap.c dissectors/packet-btsdp.c + dissectors/packet-btsmp.c dissectors/packet-bvlc.c dissectors/packet-bzr.c dissectors/packet-calcappprotocol.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index c5b420450d..bdca81cdb5 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -313,6 +313,7 @@ DISSECTOR_SRC = \ packet-bt-dht.c \ packet-bt-utp.c \ packet-btamp.c \ + packet-btatt.c \ packet-btbnep.c \ packet-btavctp.c \ packet-btavrcp.c \ @@ -327,6 +328,7 @@ DISSECTOR_SRC = \ packet-btrfcomm.c \ packet-btsap.c \ packet-btsdp.c \ + packet-btsmp.c \ packet-bvlc.c \ packet-bzr.c \ packet-calcappprotocol.c \ diff --git a/epan/dissectors/packet-btatt.c b/epan/dissectors/packet-btatt.c new file mode 100644 index 0000000000..6c12f3b205 --- /dev/null +++ b/epan/dissectors/packet-btatt.c @@ -0,0 +1,696 @@ +/* packet-btatt.c + * Routines for Bluetooth Attribute Protocol dissection + * + * Copyright 2012, Allan M. Madsen <allan.m@madsen.dk> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <epan/packet.h> +#include <epan/prefs.h> +#include <epan/expert.h> +#include "packet-btl2cap.h" + +/* Initialize the protocol and registered fields */ +static int proto_btatt = -1; + +static int hf_btatt_opcode = -1; +static int hf_btatt_handle = -1; +static int hf_btatt_starting_handle = -1; +static int hf_btatt_ending_handle = -1; +static int hf_btatt_group_end_handle = -1; +static int hf_btatt_value = -1; +static int hf_btatt_req_opcode_in_error = -1; +static int hf_btatt_handle_in_error = -1; +static int hf_btatt_error_code = -1; +static int hf_btatt_uuid16 = -1; +static int hf_btatt_uuid128 = -1; +static int hf_btatt_client_rx_mtu = -1; +static int hf_btatt_server_rx_mtu = -1; +static int hf_btatt_uuid_format = -1; +static int hf_btatt_length = -1; +static int hf_btatt_offset = -1; +static int hf_btatt_flags = -1; +static int hf_btatt_sign_counter = -1; +static int hf_btatt_signature = -1; + +/* Initialize the subtree pointers */ +static gint ett_btatt = -1; +static gint ett_btatt_list = -1; + +/* Opcodes */ +static const value_string opcode_vals[] = { + {0x01, "Error Response"}, + {0x02, "Exchange MTU Request"}, + {0x03, "Exchange MTU Response"}, + {0x04, "Find Information Request"}, + {0x05, "Find Information Response"}, + {0x06, "Find By Type Value Request"}, + {0x07, "Find By Type Value Response"}, + {0x08, "Read By Type Request"}, + {0x09, "Read By Type Response"}, + {0x0a, "Read Request"}, + {0x0b, "Read Response"}, + {0x0c, "Read Blob Request"}, + {0x0d, "Read Blob Response"}, + {0x0e, "Read Multiple Request"}, + {0x0f, "Read Multiple Response"}, + {0x10, "Read By Group Type Request"}, + {0x11, "Read By Group Type Response"}, + {0x12, "Write Request"}, + {0x13, "Write Response"}, + {0x16, "Prepare Write Request"}, + {0x17, "Prepare Write Response"}, + {0x18, "Execute Write Request"}, + {0x19, "Execute Write Response"}, + {0x1B, "Handle Value Notification"}, + {0x1D, "Handle Value Indication"}, + {0x1E, "Handle Value Confirmation"}, + {0x52, "Write Command"}, + {0xD2, "Signed Write Command"}, + {0x0, NULL} +}; + +/* Error codes */ +static const value_string error_vals[] = { + {0x01, "Invalid Handle"}, + {0x02, "Read Not Permitted"}, + {0x03, "Write Not Permitted"}, + {0x04, "Invalid PDU"}, + {0x05, "Insufficient Authentication"}, + {0x06, "Request Not Supported"}, + {0x07, "Invalid Offset"}, + {0x08, "Insufficient Authorization"}, + {0x09, "Prepare Queue Full"}, + {0x0a, "Attribute Not Found"}, + {0x0b, "Attribute Not Long"}, + {0x0c, "Insufficient Encryption Key Size"}, + {0x0d, "Invalid Attribute Value Length"}, + {0x0e, "Unlikely Error"}, + {0x0f, "Insufficient Encryption"}, + {0x10, "Unsupported Group Type"}, + {0x11, "Insufficient Resources"}, + {0x80, "Application Error"}, + {0xfd, "Improper Client Characteristic Configuration Descriptor"}, + {0xfe, "Procedure Already In Progress"}, + {0xff, "Out of Range"}, + {0x0, NULL} +}; + +static const value_string uuid_vals[] = { + /* Services - http://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ + {0x1800, "Generic Access"}, + {0x1801, "Generic Attribute"}, + {0x1802, "Immediate Alert"}, + {0x1803, "Link Loss"}, + {0x1804, "Tx Power"}, + {0x1805, "Current Time Service"}, + {0x1806, "Reference Time Update Service"}, + {0x1807, "Next DST Change Service"}, + {0x1808, "Glucose"}, + {0x1809, "Health Thermometer"}, + {0x180a, "Device Information"}, + {0x180d, "Heart Rate"}, + {0x180e, "Phone Alert Status Service"}, + {0x180f, "Battery Service"}, + {0x1810, "Blood Pressure"}, + {0x1811, "Alert Notification Service"}, + {0x1812, "Human Interface Device"}, + {0x1813, "Scan Parameters"}, + {0x1814, "Running Speed and Cadence"}, + {0x1816, "Cycling Speed and Cadence"}, + /* Declarations - http://developer.bluetooth.org/gatt/declarations/Pages/DeclarationsHome.aspx */ + {0x2800, "GATT Primary Service Declaration"}, + {0x2801, "GATT Secondary Service Declaration"}, + {0x2802, "GATT Include Declaration"}, + {0x2803, "GATT Characteristic Declaration"}, + /* Descriptors - http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorsHomePage.aspx */ + {0x2900, "Characteristic Extended Properties"}, + {0x2901, "Characteristic User Description"}, + {0x2902, "Client Characteristic Configuration"}, + {0x2903, "Server Characteristic Configuration"}, + {0x2904, "Characteristic Presentation Format"}, + {0x2905, "Characteristic Aggregate Format"}, + {0x2906, "Valid Range"}, + {0x2907, "External Report Reference"}, + {0x2908, "Report Reference"}, + /* Characteristics - http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx */ + {0x2a00, "Device Name"}, + {0x2a01, "Appearance"}, + {0x2a02, "Peripheral Privacy Flag"}, + {0x2a03, "Reconnection Address"}, + {0x2a04, "Peripheral Preferred Connection Parameters"}, + {0x2a05, "Service Changed"}, + {0x2a06, "Alert Level"}, + {0x2a07, "Tx Power Level"}, + {0x2a08, "Date Time"}, + {0x2a09, "Day of Week"}, + {0x2a0a, "Day Date Time"}, + {0x2a0c, "Exact Time 256"}, + {0x2a0d, "DST Offset"}, + {0x2a0e, "Time Zone"}, + {0x2a0f, "Local Time Information"}, + {0x2a11, "Time with DST"}, + {0x2a12, "Time Accuracy"}, + {0x2a13, "Time Source"}, + {0x2a14, "Reference Time Information"}, + {0x2a16, "Time Update Control Point"}, + {0x2a17, "Time Update State"}, + {0x2a18, "Glucose Measurement"}, + {0x2a19, "Battery Level"}, + {0x2a1c, "Temperature Measurement"}, + {0x2a1d, "Temperature Type"}, + {0x2a1e, "Intermediate Temperature"}, + {0x2a21, "Measurement Interval"}, + {0x2a22, "Boot Keyboard Input Report"}, + {0x2a23, "System ID"}, + {0x2a24, "Model Number String"}, + {0x2a25, "Serial Number String"}, + {0x2a26, "Firmware Revision String"}, + {0x2a27, "Hardware Revision String"}, + {0x2a28, "Software Revision String"}, + {0x2a29, "Manufacturer Name String"}, + {0x2a2a, "IEEE 11073-20601 Reg. Cert. Data List"}, + {0x2a2b, "Current Time"}, + {0x2a31, "Scan Refresh"}, + {0x2a32, "Boot Keyboard Output Report"}, + {0x2a33, "Boot Mouse Input Report"}, + {0x2a34, "Glucose Measurement Context"}, + {0x2a35, "Blood Pressure Measurement"}, + {0x2a36, "Intermediate Cuff Pressure"}, + {0x2a37, "Heart Rate Measurement"}, + {0x2a38, "Body Sensor Location"}, + {0x2a39, "Heart Rate Control Point"}, + {0x2a3f, "Alert Status"}, + {0x2a40, "Ringer Control Point"}, + {0x2a41, "Ringer Setting"}, + {0x2a42, "Alert Category ID Bit Mask"}, + {0x2a43, "Alert Category ID"}, + {0x2a44, "Alert Notification Control Point"}, + {0x2a45, "Unread Alert Status"}, + {0x2a46, "New Alert"}, + {0x2a47, "Supported New Alert Category"}, + {0x2a48, "Supported Unread Alert Category"}, + {0x2a49, "Blood Pressure Feature"}, + {0x2a4a, "HID Information"}, + {0x2a4b, "Report Map"}, + {0x2a4c, "HID Control Point"}, + {0x2a4d, "Report"}, + {0x2a4e, "Protocol Mode"}, + {0x2a4f, "Scan Interval Window"}, + {0x2a50, "PnP ID"}, + {0x2a51, "Glucose Feature"}, + {0x2a52, "Record Access Control Point"}, + {0x2a53, "RSC Measurement"}, + {0x2a54, "RSC Feature"}, + {0x2a55, "SC Control Point"}, + {0x2a5b, "CSC Measurement"}, + {0x2a5c, "CSC Feature"}, + {0x2a5d, "Sensor Location"}, + {0x0, NULL} +}; +static value_string_ext uuid_vals_ext = VALUE_STRING_EXT_INIT(uuid_vals); + +static const value_string uuid_format_vals[] = { + {0x01, "16-bit UUIDs"}, + {0x02, "128-bit UUIDs"}, + {0x0, NULL} +}; + +static const value_string flags_vals[] = { + {0x00, "Cancel All"}, + {0x01, "Immediately Write All"}, + {0x0, NULL} +}; + +static void +dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; + gchar *col_info = ""; + proto_item *ti, *item; + proto_tree *st, *ltree; + guint8 opcode; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATT"); + + switch (pinfo->p2p_dir) { + + case P2P_DIR_SENT: + col_add_str(pinfo->cinfo, COL_INFO, "Sent "); + break; + + case P2P_DIR_RECV: + col_add_str(pinfo->cinfo, COL_INFO, "Rcvd "); + break; + + case P2P_DIR_UNKNOWN: + break; + + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", + pinfo->p2p_dir); + break; + } + + if (tvb_length_remaining(tvb, 0) < 1) + return; + + ti = proto_tree_add_item(tree, proto_btatt, tvb, 0, -1, ENC_NA); + st = proto_item_add_subtree(ti, ett_btatt); + + item = proto_tree_add_item(st, hf_btatt_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN); + opcode = tvb_get_guint8(tvb, 0); + offset++; + + col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, opcode_vals, "<unknown>")); + + switch (opcode) { + case 0x01: /* Error Response */ + proto_tree_add_item(st, hf_btatt_req_opcode_in_error, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(st, hf_btatt_handle_in_error, tvb, offset, 2, ENC_LITTLE_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, " - %s, Handle: 0x%04x", + val_to_str(tvb_get_guint8(tvb, offset+2), error_vals, "<unknown>"), + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset)); + offset += 2; + proto_tree_add_item(st, hf_btatt_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x02: /* Exchange MTU Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Client Rx MTU: %u", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_client_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x03: /* Exchange MTU Response */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Server Rx MTU: %u", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_server_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x04: /* Find Information Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handles: 0x%04x..0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x05: /* Find Information Response */ + { + guint8 format = tvb_get_guint8(tvb, offset); + + item = proto_tree_add_item(st, hf_btatt_uuid_format, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if( format == 1 ) { + while( tvb_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + } + else if( format == 2 ) { + while( tvb_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); + offset += 16; + } + } + else { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Unknown format"); + } + } + break; + + case 0x06: /* Find By Type Value Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", + val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"), + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + if( tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x07: /* Find By Type Value Response */ + while( tvb_length_remaining(tvb, offset) > 0 ) { + item = proto_tree_add_text(st, tvb, offset, 4, + "Handles Info, Handle: 0x%04x, Group End Handle: 0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + break; + + case 0x08: /* Read By Type Request */ + case 0x10: /* Read By Group Type Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", + val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"), + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + if (tvb_length_remaining(tvb, offset) == 2) { + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + else if (tvb_length_remaining(tvb, offset) == 16) { + item = proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); + proto_item_append_text(item, " (%s)", val_to_str_ext_const(tvb_get_letohs(tvb, offset), + &uuid_vals_ext, "<unknown>")); + offset += 16; + } + break; + + case 0x09: /* Read By Type Response */ + { + guint8 length = tvb_get_guint8(tvb, offset); + + proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if(length > 0) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", + tvb_length_remaining(tvb, offset)/length); + + while (tvb_length_remaining(tvb, offset) >= length) + { + item = proto_tree_add_text(st, tvb, offset, length, "Attribute Data, Handle: 0x%04x", + tvb_get_letohs(tvb, offset)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length-2, ENC_LITTLE_ENDIAN); + offset += (length-2); + } + } + } + break; + + case 0x0a: /* Read Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x0b: /* Read Response */ + case 0x0d: /* Read Blob Response */ + case 0x0f: /* Multiple Read Response */ + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x0c: /* Read Blob Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x0e: /* Multiple Read Request */ + if(tvb_length_remaining(tvb, offset) < 4) { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, + "Too few handles, should be 2 or more"); + break; + } + + col_append_str(pinfo->cinfo, COL_INFO, ", Handles: "); + while (tvb_length_remaining(tvb, offset) >= 2) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, "0x%04x ", tvb_get_letohs(tvb, offset)); + offset += 2; + } + break; + + case 0x11: /* Read By Group Type Response */ + { + guint8 length = tvb_get_guint8(tvb, offset); + + proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if(length > 0) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", tvb_length_remaining(tvb, offset)/length); + + while (tvb_length_remaining(tvb, offset) >= length) { + item = proto_tree_add_text(st, tvb, offset, length, + "Attribute Data, Handle: 0x%04x, Group End Handle: 0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length-4, ENC_LITTLE_ENDIAN); + offset += (length-4); + } + } + } + break; + + case 0x12: /* Write Request */ + case 0x52: /* Write Command */ + case 0x1b: /* Handle Value Notification */ + case 0x1d: /* Handle Value Indication */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x16: /* Prepare Write Request */ + case 0x17: /* Prepare Write Response */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x18: /* Execute Write Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", + val_to_str(tvb_get_guint8(tvb, offset), flags_vals, "<unknown>")); + proto_tree_add_item(st, hf_btatt_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0xd2: /* Signed Write Command */ + { + guint8 length; + + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + length = tvb_length_remaining(tvb, offset); + if (length > 12) { + proto_tree_add_item(st, hf_btatt_value, tvb, offset, length-12, ENC_NA); + offset+=length-12; + } + + proto_tree_add_item(st, hf_btatt_sign_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(st, hf_btatt_signature, tvb, offset, 8, ENC_NA); + offset+=8; + break; + } + default: + break; + } +} + +void +proto_register_btatt(void) +{ + module_t *module; + + static hf_register_info hf[] = { + {&hf_btatt_opcode, + {"Opcode", "btatt.opcode", + FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_handle, + {"Handle", "btatt.handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_starting_handle, + {"Starting Handle", "btatt.starting_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_ending_handle, + {"Ending Handle", "btatt.ending_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_group_end_handle, + {"Group End Handle", "btatt.group_end_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_value, + {"Value", "btatt.value", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_req_opcode_in_error, + {"Request Opcode in Error", "btatt.req_opcode_in_error", + FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_handle_in_error, + {"Handle in Error", "btatt.handle_in_error", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_error_code, + {"Error Code", "btatt.error_code", + FT_UINT8, BASE_HEX, VALS(error_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid16, + {"UUID", "btatt.uuid16", + FT_UINT16, BASE_HEX |BASE_EXT_STRING, &uuid_vals_ext, 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid128, + {"UUID", "btatt.uuid128", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_client_rx_mtu, + {"Client Rx MTU", "btatt.client_rx_mtu", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_server_rx_mtu, + {"Server Rx MTU", "btatt.server_rx_mtu", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid_format, + {"UUID Format", "btatt.uuid_format", + FT_UINT8, BASE_HEX, VALS(uuid_format_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_length, + {"Length", "btatt.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Length of Handle/Value Pair", HFILL} + }, + {&hf_btatt_offset, + {"Offset", "btatt.offset", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_flags, + {"Flags", "btatt.flags", + FT_UINT8, BASE_HEX, VALS(flags_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_sign_counter, + {"Sign Counter", "btatt.sign_counter", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_signature, + {"Signature", "btatt.signature", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btatt, + &ett_btatt_list + }; + + /* Register the protocol name and description */ + proto_btatt = proto_register_protocol("Bluetooth Attribute Protocol", "ATT", "btatt"); + + register_dissector("btatt", dissect_btatt, proto_btatt); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btatt, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + module = prefs_register_protocol(proto_btatt, NULL); + prefs_register_static_text_preference(module, "att.version", + "Bluetooth Protocol ATT version from Core 4.0", + "Version of protocol supported by this dissector."); +} + +void +proto_reg_handoff_btatt(void) +{ + dissector_handle_t btatt_handle; + + btatt_handle = find_dissector("btatt"); + dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_ATT, btatt_handle); + dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_ATT, btatt_handle); +} + +/* + * 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: + */
\ No newline at end of file diff --git a/epan/dissectors/packet-bthci_cmd.c b/epan/dissectors/packet-bthci_cmd.c index 49bb49e693..27ae6ca420 100644 --- a/epan/dissectors/packet-bthci_cmd.c +++ b/epan/dissectors/packet-bthci_cmd.c @@ -8,6 +8,8 @@ * * Updated to HCI specification 2.1 + EDR * Allan M. Madsen 2007 + * Updated to HCI specification 3.0+HS & 4.0 + * Allan M. Madsen 2012 * * $Id$ * @@ -67,7 +69,6 @@ static int hf_bthci_cmd_allow_role_switch = -1; static int hf_bthci_cmd_page_scan_mode = -1; static int hf_bthci_cmd_page_scan_repetition_mode = -1; static int hf_bthci_cmd_page_scan_period_mode = -1; -static int hf_bthci_cmd_status = -1; static int hf_bthci_cmd_max_period_length = -1; static int hf_bthci_cmd_min_period_length = -1; static int hf_bthci_cmd_connection_handle = -1; @@ -181,7 +182,6 @@ static int hf_bthci_cmd_host_data_packet_length_acl = -1; static int hf_bthci_cmd_host_data_packet_length_sco = -1; static int hf_bthci_cmd_host_total_num_acl_data_packets = -1; static int hf_bthci_cmd_host_total_num_sco_data_packets = -1; -static int hf_bthci_cmd_power_level_type = -1; static int hf_bthci_cmd_loopback_mode = -1; static int hf_bthci_cmd_page_number = -1; static int hf_bthci_cmd_transmit_bandwidth = -1; @@ -225,12 +225,105 @@ static int hf_bthci_cmd_eir_struct_type = -1; static int hf_bthci_cmd_sc_uuid16 = -1; static int hf_bthci_cmd_sc_uuid32 = -1; static int hf_bthci_cmd_sc_uuid128 = -1; +static int hf_bthci_cmd_physical_link_handle = -1; +static int hf_bthci_cmd_dedicated_amp_key_length = -1; +static int hf_bthci_cmd_dedicated_amp_key_type = -1; +static int hf_bthci_cmd_dedicated_amp_key = -1; +static int hf_bthci_cmd_flow_spec = -1; +static int hf_bthci_cmd_flow_spec_identifier = -1; +static int hf_bthci_cmd_flow_spec_service_type = -1; +static int hf_bthci_cmd_flow_spec_sdu_size = -1; +static int hf_bthci_cmd_flow_spec_sdu_arrival_time = -1; +static int hf_bthci_cmd_flow_spec_access_latency = -1; +static int hf_bthci_cmd_flush_to_us = -1; +static int hf_bthci_cmd_logical_link_handle = -1; +static int hf_bthci_cmd_evt_mask2_00 = -1; +static int hf_bthci_cmd_evt_mask2_01 = -1; +static int hf_bthci_cmd_evt_mask2_02 = -1; +static int hf_bthci_cmd_evt_mask2_03 = -1; +static int hf_bthci_cmd_evt_mask2_04 = -1; +static int hf_bthci_cmd_evt_mask2_05 = -1; +static int hf_bthci_cmd_evt_mask2_06 = -1; +static int hf_bthci_cmd_evt_mask2_07 = -1; +static int hf_bthci_cmd_evt_mask2_10 = -1; +static int hf_bthci_cmd_evt_mask2_11 = -1; +static int hf_bthci_cmd_evt_mask2_12 = -1; +static int hf_bthci_cmd_evt_mask2_13 = -1; +static int hf_bthci_cmd_evt_mask2_14 = -1; +static int hf_bthci_cmd_evt_mask2_15 = -1; +static int hf_bthci_cmd_location_domain_aware = -1; +static int hf_bthci_cmd_location_domain = -1; +static int hf_bthci_cmd_location_domain_options = -1; +static int hf_bthci_cmd_location_options = -1; +static int hf_bthci_cmd_flow_control_mode = -1; +static int hf_bthci_cmd_tx_power_level_type = -1; +static int hf_bthci_cmd_short_range_mode = -1; +static int hf_bthci_cmd_le_supported_host = -1; +static int hf_bthci_cmd_le_simultaneous_host = -1; +static int hf_bthci_cmd_enable_amp_recv_reports = -1; +static int hf_bthci_cmd_amp_recv_report_interval = -1; +static int hf_bthci_cmd_length_so_far = -1; +static int hf_bthci_cmd_amp_assoc_length = -1; +static int hf_bthci_cmd_amp_remaining_assoc_length = -1; +static int hf_bthci_cmd_amp_assoc_fragment = -1; +static int hf_bthci_cmd_le_evt_mask_00 = -1; +static int hf_bthci_cmd_le_evt_mask_01 = -1; +static int hf_bthci_cmd_le_evt_mask_02 = -1; +static int hf_bthci_cmd_le_evt_mask_03 = -1; +static int hf_bthci_cmd_le_evt_mask_04 = -1; +static int hf_bthci_cmd_le_advts_interval_min = -1; +static int hf_bthci_cmd_le_advts_interval_max = -1; +static int hf_bthci_cmd_le_advts_type = -1; +static int hf_bthci_cmd_le_own_address_type = -1; +static int hf_bthci_cmd_le_direct_address_type = -1; +static int hf_bthci_cmd_le_advts_channel_map_1 = -1; +static int hf_bthci_cmd_le_advts_channel_map_2 = -1; +static int hf_bthci_cmd_le_advts_channel_map_3 = -1; +static int hf_bthci_cmd_le_advts_filter_policy = -1; +static int hf_bthci_cmd_le_data_length = -1; +static int hf_bthci_cmd_le_advts_enable = -1; +static int hf_bthci_cmd_le_scan_enable = -1; +static int hf_bthci_cmd_le_filter_dublicates = -1; +static int hf_bthci_cmd_le_scan_type = -1; +static int hf_bthci_cmd_le_scan_interval = -1; +static int hf_bthci_cmd_le_scan_window = -1; +static int hf_bthci_cmd_le_scan_filter_policy = -1; +static int hf_bthci_cmd_le_initiator_filter_policy = -1; +static int hf_bthci_cmd_le_peer_address_type = -1; +static int hf_bthci_cmd_le_con_interval_min = -1; +static int hf_bthci_cmd_le_con_interval_max = -1; +static int hf_bthci_cmd_le_con_latency = -1; +static int hf_bthci_cmd_le_supervision_timeout = -1; +static int hf_bthci_cmd_le_min_ce_length = -1; +static int hf_bthci_cmd_le_max_ce_length = -1; +static int hf_bthci_cmd_le_address_type = -1; +static int hf_bthci_cmd_le_channel_map = -1; +static int hf_bthci_cmd_key = -1; +static int hf_bthci_cmd_plaintext_data = -1; +static int hf_bthci_cmd_random_number = -1; +static int hf_bthci_cmd_encrypted_diversifier = -1; +static int hf_bthci_cmd_le_long_term_key = -1; +static int hf_bthci_cmd_rx_freqency = -1; +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_appearance = -1; +static int hf_bthci_cmd_flags_limited_disc_mode = -1; +static int hf_bthci_cmd_flags_general_disc_mode = -1; +static int hf_bthci_cmd_flags_bredr_not_support = -1; +static int hf_bthci_cmd_flags_le_bredr_support_ctrl = -1; +static int hf_bthci_cmd_flags_le_bredr_support_host = -1; +static int hf_bthci_cmd_flags_le_oob_data_present = -1; +static int hf_bthci_cmd_flags_le_oob_le_supported_host = -1; +static int hf_bthci_cmd_flags_le_oob_le_bredr_support = -1; +static int hf_bthci_cmd_flags_le_oob_address_type = -1; /* Initialize the subtree pointers */ static gint ett_bthci_cmd = -1; static gint ett_opcode = -1; static gint ett_eir_subtree = -1; static gint ett_eir_struct_subtree = -1; +static gint ett_flow_spec_subtree = -1; static const value_string bthci_cmd_opcode_vals[] = { {0x0000, "No Operation"}, @@ -270,6 +363,15 @@ static const value_string bthci_cmd_opcode_vals[] = { {0x042f, "User Passkey Request Negative Reply"}, {0x0430, "Remote OOB Data Request Reply"}, {0x0433, "Remote OOB Data Request Negative Reply"}, + {0x0434, "IO Capability Request Negative Reply"}, + {0x0435, "Create Physical Link"}, + {0x0436, "Accept Physical Link"}, + {0x0437, "Disconnect Physical Link"}, + {0x0438, "Create Logical Link"}, + {0x0439, "Accept Logical Link"}, + {0x043a, "Disconnect Logical Link"}, + {0x043b, "Logical Link Cancel"}, + {0x043c, "Flow Spec Modify"}, {0x0801, "Hold Mode"}, {0x0803, "Sniff Mode"}, {0x0804, "Exit Sniff Mode"}, @@ -356,6 +458,19 @@ static const value_string bthci_cmd_opcode_vals[] = { {0x0c5b, "Write Default Erroneous Data Reporting"}, {0x0c5f, "Enhanced Flush"}, {0x0c60, "Send Keypress Notification"}, + {0x0c61, "Read Logical Link Accept Timeout"}, + {0x0c62, "Write Logical Link Accept Timeout"}, + {0x0c63, "Set Event Mask Page 2"}, + {0x0c64, "Read Location Data"}, + {0x0c65, "Write Location Data"}, + {0x0c66, "Read Flow Control Mode"}, + {0x0c67, "Write Flow Control Mode"}, + {0x0c68, "Read Enhanced Transmit Power Level"}, + {0x0c69, "Read Best Effort Flush Timeout"}, + {0x0c6a, "Write Best Effort Flush Timeout"}, + {0x0c6b, "Short Range Mode"}, + {0x0c6c, "Read LE Host Supported"}, + {0x0c6d, "Write LE Host Supported"}, {0x1001, "Read Local Version Information"}, {0x1002, "Read Local Supported Commands"}, {0x1003, "Read Local Supported Features"}, @@ -363,30 +478,69 @@ static const value_string bthci_cmd_opcode_vals[] = { {0x1005, "Read Buffer Size"}, {0x1007, "Read Country Code"}, {0x1009, "Read BD ADDR"}, + {0x100a, "Read Data Block Size"}, {0x1401, "Read Failed Contact Counter"}, {0x1402, "Reset Failed Contact Counter"}, {0x1403, "Read Link Quality"}, {0x1405, "Read RSSI"}, {0x1406, "Read AFH Channel Map"}, {0x1407, "Read Clock"}, + {0x1408, "Read Encryption Key Size"}, + {0x1409, "Read Local AMP Info"}, + {0x140a, "Read Local AMP Assoc"}, + {0x140b, "Write Remote AMP Assoc"}, {0x1801, "Read Loopback Mode"}, {0x1802, "Write Loopback Mode"}, {0x1803, "Enable Device Under Test Mode"}, {0x1804, "Write Simple Pairing Debug Mode"}, + {0x1807, "Enable AMP Receiver Reports"}, + {0x1808, "AMP Test End"}, + {0x1809, "AMP Test"}, + {0x2001, "LE Set Event Mask"}, + {0x2002, "LE Read Buffer Size"}, + {0x2003, "LE Read Local Supported Features"}, + {0x2005, "LE Set Random Address"}, + {0x2006, "LE Set Advertising Parameters"}, + {0x2007, "LE Read Advertising Channel Tx Power"}, + {0x2008, "LE Set Advertising Data"}, + {0x2009, "LE Set Scan Response Data"}, + {0x200a, "LE Set Advertise Enable"}, + {0x200b, "LE Set Scan Parameters"}, + {0x200c, "LE Set Scan Enable"}, + {0x200d, "LE Create Connection"}, + {0x200e, "LE Create Connection Cancel"}, + {0x200f, "LE Read White List Size"}, + {0x2010, "LE Clear White List"}, + {0x2011, "LE Add Device To White List"}, + {0x2012, "LE Remove Device From White List"}, + {0x2013, "LE Connection Update"}, + {0x2014, "LE Set Host Channel Classification"}, + {0x2015, "LE Read Channel Map"}, + {0x2016, "LE Read Remote Used Features"}, + {0x2017, "LE Encrypt"}, + {0x2018, "LE Rand"}, + {0x2019, "LE Start Encryption"}, + {0x201a, "LE Long Term Key Request Reply"}, + {0x201b, "LE Long Term Key Request Negative Reply"}, + {0x201c, "LE Read Supported States"}, + {0x201d, "LE Receiver Test"}, + {0x201e, "LE Transmitter Test"}, + {0x201f, "LE Test End"}, {0xfc00, "Vendor-Specific"}, {0, NULL} }; value_string_ext bthci_cmd_opcode_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_opcode_vals); static const value_string bthci_ogf_vals[] = { - { HCI_OGF_LINK_CONTROL, "Link Control Commands" }, - { HCI_OGF_LINK_POLICY, "Link Policy Commands" }, + { HCI_OGF_LINK_CONTROL, "Link Control Commands" }, + { HCI_OGF_LINK_POLICY, "Link Policy Commands" }, { HCI_OGF_HOST_CONTROLLER,"Host Controller & Baseband Commands" }, { HCI_OGF_INFORMATIONAL,"Informational Parameters" }, - { HCI_OGF_STATUS, "Status Parameters" }, - { HCI_OGF_TESTING, "Testing Commands" }, - { HCI_OGF_LOGO_TESTING, "Bluetooth Logo Testing Commands" }, - { HCI_OGF_VENDOR_SPECIFIC, "Vendor-Specific Commands" }, + { HCI_OGF_STATUS, "Status Parameters" }, + { HCI_OGF_TESTING, "Testing Commands" }, + { HCI_OGF_LOW_ENERGY, "LE Controller Commands" }, + { HCI_OGF_LOGO_TESTING, "Bluetooth Logo Testing Commands" }, + { HCI_OGF_VENDOR_SPECIFIC, "Vendor-Specific Commands" }, { 0, NULL } }; value_string_ext bthci_ogf_vals_ext = VALUE_STRING_EXT_INIT(bthci_ogf_vals); @@ -444,10 +598,17 @@ static const value_string bthci_cmd_status_vals[] = { {0x32, "Role Switch Pending"}, {0x33, "Unknown"}, {0x34, "Reserved Slot Violation"}, - {0x35, "Role Switch Failed"}, - {0x36, "Extended Inquiry Response Too Large"}, + {0x35, "Role Switch Failed"}, + {0x36, "Extended Inquiry Response Too Large"}, {0x37, "Secure Simple Pairing Not Supported By Host"}, {0x38, "Host Busy - Pairing"}, + {0x39, "Connection Rejected - No Suitable Channel Found"}, + {0x3a, "Controller Busy"}, + {0x3b, "Unacceptable Connection Interval"}, + {0x3c, "Directed Advertising Timeout"}, + {0x3d, "Connection Terminated - MIC Failure"}, + {0x3e, "Connection Failed To Be Established"}, + {0x3f, "MAC Connection Failed"}, {0, NULL } }; value_string_ext bthci_cmd_status_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_status_vals); @@ -531,6 +692,29 @@ static const value_string bthci_cmd_service_class_type_vals[] = { {0x1303, "Video Source"}, {0x1304, "Video Sink"}, {0x1305, "Video Distribution"}, + /* LE services */ + {0x1800, "Generic Access"}, + {0x1801, "Generic Attribute"}, + {0x1802, "Immediate Alert"}, + {0x1803, "Link Loss"}, + {0x1804, "Tx Power"}, + {0x1805, "Current Time"}, + {0x1806, "Reference Time Update"}, + {0x1807, "Next DST Change"}, + {0x1808, "Glucose"}, + {0x1809, "Health Thermometer"}, + {0x180a, "Device Information"}, + {0x180b, ""}, + {0x180c, ""}, + {0x180d, "Heart Rate"}, + {0x180e, "Phone Alert Status"}, + {0x180f, "Battery"}, + {0x1810, "Blood Pressure"}, + {0x1811, "Alert Notification"}, + {0x1812, "Human Interface Device"}, + {0x1813, "Scan Parameters"}, + {0x1814, "Running Speed and Cadence"}, + {0x1816, "Cycling Speed and Cadence"}, {0, NULL} }; value_string_ext bthci_cmd_service_class_type_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_service_class_type_vals); @@ -551,11 +735,65 @@ static const value_string bthci_cmd_eir_data_type_vals[] = { {0x0D, "Class Of Device" }, {0x0E, "Simple Pairing Hash C" }, {0x0F, "Simple Pairing Randomizer R" }, + {0x10, "Device ID/Security Manager TK Value" }, + {0x11, "Security Manager Out of Band Flags" }, + {0x12, "Slave Connection Interval Range" }, + {0x14, "List of 16-bit Service Solicitation UUIDs" }, + {0x15, "List of 128-bit Service Solicitation UUIDs" }, + {0x16, "Service Data" }, + {0x17, "Public Target Address" }, + {0x18, "Random Target Address" }, + {0x19, "Appearance" }, {0xFF, "Manufacturer Specific" }, { 0, NULL } }; value_string_ext bthci_cmd_eir_data_type_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_eir_data_type_vals); +static const value_string bthci_cmd_appearance_vals[] = { + { 0x0000, "Unknown" }, + { 0x0040, "Generic Phone" }, + { 0x0080, "Generic Computer" }, + { 0x00C0, "Generic Watch" }, + { 0x00C1, "Sports Watch" }, + { 0x0100, "Generic Clock" }, + { 0x0140, "Generic Display" }, + { 0x0180, "Generic Remote Control" }, + { 0x01C0, "Generic Eye-glasses" }, + { 0x0200, "Generic Tag" }, + { 0x0240, "Generic Keyring" }, + { 0x0280, "Generic Media Player" }, + { 0x02C0, "Generic Barcode Scanner" }, + { 0x0300, "Generic Thermometer" }, + { 0x0301, "Ear Thermometer" }, + { 0x0340, "Generic Heart Rate Sensor" }, + { 0x0341, "Heart Rate Belt Sensor" }, + { 0x0380, "Generic Blood Pressure" }, + { 0x0381, "Arm Blood Pressure" }, + { 0x0382, "Wrist Blood Pressure" }, + { 0x03C0, "Human Interface Device (HID)" }, + { 0x03C1, "Keyboard" }, + { 0x03C2, "Mouse" }, + { 0x03C3, "Joystick" }, + { 0x03C4, "Gamepad" }, + { 0x03C5, "Digitizer Tablet" }, + { 0x03C6, "Card Reader" }, + { 0x03C7, "Digital Pen" }, + { 0x03C8, "Barcode Scanner" }, + { 0x0400, "Generic Glucose Meter" }, + { 0x0440, "Generic Running/Walking Sensor" }, + { 0x0441, "In-shoe Running/Walking Sensor" }, + { 0x0442, "On-shoe Running/Walking Sensor" }, + { 0x0443, "On-hip Running/Walking Sensor" }, + { 0x0480, "Generic Cycling Sensor" }, + { 0x0481, "Cycling Computer" }, + { 0x0482, "Cycling Speed Sensor" }, + { 0x0483, "Cycling Cadence Sensor" }, + { 0x0484, "Cycling Power Sensor" }, + { 0x0485, "Cycling Speed and Cadence Sensor" }, + { 0, NULL } +}; +value_string_ext bthci_cmd_appearance_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_appearance_vals); + const value_string bthci_cmd_io_capability_vals[] = { {0x00, "Display Only" }, {0x01, "Display Yes/No" }, @@ -581,6 +819,12 @@ static const value_string bthci_cmd_auth_req_vals[] = { }; value_string_ext bthci_cmd_auth_req_vals_ext = VALUE_STRING_EXT_INIT(bthci_cmd_auth_req_vals); +const value_string bthci_cmd_address_types_vals[] = { + { 0x00, "Public Device Address" }, + { 0x01, "Random Device Address" }, + { 0, NULL } +}; + static const value_string cmd_role_vals[] = { {0x00, "Become Master"}, {0x01, "Remain Slave"}, @@ -652,7 +896,7 @@ static const value_string cmd_delete_all_flag_values[] = { {0, NULL } }; -static const value_string cmd_scan_enable_values[] = { +const value_string bthci_cmd_scan_enable_values[] = { {0x00, "No Scans enabled" }, {0x01, "Inquiry Scan enabled/Page Scan disable" }, {0x02, "Inquiry Scan disabled/Page Scan enabled" }, @@ -690,6 +934,7 @@ static const value_string cmd_air_coding_format_values[] = { {0x0, "CVSD" }, {0x1, "\xb5-law" }, {0x2, "A-law" }, + {0x3, "Transparent" }, {0, NULL } }; @@ -708,8 +953,8 @@ static const value_string cmd_flow_contr_enable[] = { }; static const value_string cmd_power_level_types[] = { - {0x00, "Read Current Transmission Power Level" }, - {0x01, "Read Maximum Transmission Power Level" }, + {0x00, "Current Tx Power Level" }, + {0x01, "Maximum Tx Power Level" }, {0, NULL } }; @@ -720,7 +965,7 @@ static const value_string cmd_loopback_modes[] = { {0, NULL } }; -static const value_string encrypt_mode_vals[] = { +static const value_string cmd_encrypt_mode_vals[] = { { 0x00, "Encryption Disabled" }, { 0x01, "Encryption only for Point-To-Point Packets" }, { 0x02, "Encryption for Point-To-Point and Broadcast Packets" }, @@ -733,7 +978,7 @@ static const value_string cmd_boolean[] = { {0, NULL } }; -static const value_string cmd_page_scan_modes[] = { +const value_string bthci_cmd_page_scan_modes[] = { {0, "Mandatory Page Scan Mode"}, {1, "Optional Page Scan Mode I"}, {2, "Optional Page Scan Mode II"}, @@ -741,14 +986,14 @@ static const value_string cmd_page_scan_modes[] = { {0, NULL } }; -static const value_string cmd_page_scan_repetition_modes[] = { +const value_string bthci_cmd_page_scan_repetition_modes[] = { {0, "R0"}, {1, "R1"}, {2, "R2"}, {0, NULL } }; -static const value_string cmd_page_scan_period_modes[] = { +const value_string bthci_cmd_page_scan_period_modes[] = { {0, "P0"}, {1, "P1"}, {2, "P2"}, @@ -763,7 +1008,7 @@ static const value_string cmd_role_switch_modes[] = { static const value_string cmd_rtx_effort[] = { {0x00, "No Retransmission" }, - {0x01, "At least 1 retransmission, optimize for consumption" }, + {0x01, "At least 1 retransmission, optimize for power consumption" }, {0x02, "At least 1 retransmission, optimize for link quality" }, {0xFF, "Don't Care" }, { 0, NULL } @@ -793,7 +1038,7 @@ static const value_string cmd_which_clock[] = { { 0, NULL } }; -static const value_string cmd_notification_types[] = { +const value_string bthci_cmd_notification_types[] = { {0x00, "Passkey Entry Started" }, {0x01, "Passkey Digit Entered" }, {0x02, "Passkey Digit Erased" }, @@ -802,8 +1047,73 @@ static const value_string cmd_notification_types[] = { { 0, NULL } }; +static const value_string bthci_cmd_amp_key_type[] = { + {0x03, "Debug Combination Key" }, + {0x04, "Authenticated Combination Key" }, + {0x05, "Unauthenticated Combination Key" }, + { 0, NULL } +}; -static int +static const value_string cmd_flow_spec_servicetype[] = { + { 0x00, "No traffic" }, + { 0x01, "Best effort (Default)" }, + { 0x02, "Guaranteed" }, + { 0, NULL } +}; + +static const value_string cmd_flow_ctrl_mode[] = { + { 0x00, "Packet based" }, + { 0x01, "Data Block based" }, + { 0, NULL } +}; + +static const value_string cmd_le_advertising_types[] = { + { 0x00, "Connectable Unidirected Advertising" }, + { 0x01, "Connectable Directed Advertising" }, + { 0x02, "Scannable Unidirected Advertising" }, + { 0x03, "Non-Connectable Unidirected Advertising" }, + { 0, NULL } +}; + +static const value_string cmd_le_advertising_filter_policy[] = { + { 0x00, "Allow Scan Req from Any, Allow Connect Req from Any" }, + { 0x01, "Allow Scan Req from White List Only, Allow Connect Req from Any" }, + { 0x02, "Allow Scan Req from Any, Allow Connect Req from White List Only" }, + { 0x03, "Allow Scan Req from White List Only, Allow Connect Req from White List Only." }, + { 0, NULL } +}; + +static const value_string cmd_le_scan_types[] = { + { 0x00, "Passive" }, + { 0x01, "Active" }, + { 0, NULL } +}; + +static const value_string cmd_le_scan_filter_policy[] = { + { 0x00, "Accept all advertisments. Ignore directed advertisements not addresed to this device" }, + { 0x01, "Ignore advertisments from devices not in the white list only. Ignore directed advertisements not addresed to this device" }, + { 0, NULL } +}; + +static const value_string cmd_init_filter_policy[] = { + { 0x00, "Use Peer Address" }, + { 0x01, "Use White List. Ignore Peer Address" }, + { 0, NULL } +}; + +static const value_string cmd_le_test_pkt_payload[] = { + { 0x00, "Pseudo-Random Sequence 9" }, + { 0x01, "Pattern Of Alternating Bits '11110000'" }, + { 0x02, "Pattern Of Alternating Bits '10101010'" }, + { 0x03, "Pseudo-Random Sequence 15" }, + { 0x04, "Pattern Of All '1' bits" }, + { 0x05, "Pattern Of All '0' bits" }, + { 0x06, "Pattern Of Alternating Bits '00001111'" }, + { 0x07, "Pattern Of Alternating Bits '0101'" }, + { 0, NULL } +}; + +static int dissect_bthci_cmd_bd_addr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint8 i, bd_addr[6]; @@ -863,43 +1173,54 @@ dissect_bthci_cmd_cod(int type, tvbuff_t *tvb, int offset, packet_info *pinfo _U return offset+3; } -static int -dissect_bthci_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +static int +dissect_bthci_eir_ad_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 size) { - guint8 i, j, length, type; - proto_item *ti_eir = NULL; - proto_tree *ti_eir_subtree = NULL; + guint8 i, j, length, type, data_size = size; + proto_item *item, *ti_data = NULL; + proto_tree *ti_data_subtree = NULL; if (tree) { - ti_eir=proto_tree_add_text(tree, tvb, offset, 240, "Extended Inquiry Response Data"); - ti_eir_subtree=proto_item_add_subtree(ti_eir, ett_eir_subtree); + ti_data=proto_tree_add_text(tree, tvb, offset, data_size, (size==240)?"Extended Inquiry Response Data":"Advertising Data"); + ti_data_subtree=proto_item_add_subtree(ti_data, ett_eir_subtree); } i=0; - while(i<240) { + while(i<data_size){ length = tvb_get_guint8(tvb, offset+i); if (length != 0) { - proto_item *ti_eir_struct=NULL; - proto_tree *ti_eir_struct_subtree=NULL; + proto_item *ti_data_struct=NULL; + proto_tree *ti_data_struct_subtree=NULL; - ti_eir_struct = proto_tree_add_text(ti_eir_subtree, tvb, offset+i, length+1, "%s", ""); - ti_eir_struct_subtree = proto_item_add_subtree(ti_eir_struct, ett_eir_struct_subtree); + ti_data_struct = proto_tree_add_text(ti_data_subtree, tvb, offset+i, length+1, "%s", ""); + ti_data_struct_subtree = proto_item_add_subtree(ti_data_struct, ett_eir_struct_subtree); type = tvb_get_guint8(tvb, offset+i+1); - proto_item_append_text(ti_eir_struct,"%s", val_to_str_ext_const(type, &bthci_cmd_eir_data_type_vals_ext, "Unknown")); + proto_item_append_text(ti_data_struct,"%s", val_to_str(type, bthci_cmd_eir_data_type_vals, "Unknown")); - proto_tree_add_item(ti_eir_struct_subtree,hf_bthci_cmd_eir_struct_length, tvb, offset+i, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(ti_eir_struct_subtree,hf_bthci_cmd_eir_struct_type, tvb, offset+i+1, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree,hf_bthci_cmd_eir_struct_length, tvb, offset+i, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree,hf_bthci_cmd_eir_struct_type, tvb, offset+i+1, 1, ENC_LITTLE_ENDIAN); switch (type) { + case 0x01: /* flags */ + if(length-1 > 0) + { + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_limited_disc_mode, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_general_disc_mode, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_bredr_not_support, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_bredr_support_ctrl, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_bredr_support_host, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + } + break; case 0x02: /* 16-bit Service Class UUIDs, incomplete list */ case 0x03: /* 16-bit Service Class UUIDs, complete list */ + case 0x14: /* 16-bit Service Solicitation UUIDs */ j=0; while(j<(length-1)) { - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_sc_uuid16, tvb, offset+i+j+2, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_sc_uuid16, tvb, offset+i+j+2, 2, ENC_LITTLE_ENDIAN); j+=2; } break; @@ -908,29 +1229,73 @@ dissect_bthci_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *pinfo j=0; while(j<(length-1)) { - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_sc_uuid32, tvb, offset+i+j+2, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_sc_uuid32, tvb, offset+i+j+2, 4, ENC_LITTLE_ENDIAN); j+=4; } break; case 0x06: /* 128-bit Service Class UUIDs, incomplete list */ case 0x07: /* 128-bit Service Class UUIDs, complete list */ + case 0x15: /* 128-bit Service Solicitation UUIDs */ j=0; while(j<(length-1)) { - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_sc_uuid128, tvb, offset+i+j+2, 16, ENC_NA); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_sc_uuid128, tvb, offset+i+j+2, 16, ENC_NA); j+=16; } break; case 0x08: /* Device Name, shortened */ case 0x09: /* Device Name, full */ - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_device_name, tvb, offset+i+2, length-1, ENC_ASCII|ENC_NA); - proto_item_append_text(ti_eir_struct,": %s", tvb_format_text(tvb,offset+i+2,length-1)); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_device_name, tvb, offset+i+2, length-1, ENC_ASCII|ENC_NA); + proto_item_append_text(ti_data_struct,": %s", tvb_format_text(tvb,offset+i+2,length-1)); break; case 0x0A: /* Tx Power Level */ - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_tx_power, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_tx_power, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + break; + case 0x0D: /* Class of Device */ + dissect_bthci_cmd_cod(hf_bthci_cmd_class_of_device, tvb, offset+i+2, pinfo, ti_data_struct_subtree); + break; + case 0x0E: /* Simple Pairing Hash C */ + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_hash_c, tvb, offset+i+2, 16, ENC_NA); + break; + case 0x0F: /* Simple Pairing Randomizer R */ + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_randomizer_r, tvb, offset+i+2, 16, ENC_NA); + break; + case 0x11: /* Security Manager OOB Flags */ + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_oob_data_present, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_oob_le_supported_host, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_oob_le_bredr_support, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_flags_le_oob_address_type, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + break; + case 0x12: /* Slave Connection Interval Range */ + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_min, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset+i+2)*1.25); + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_max, tvb, offset+i+4, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset+i+4)*1.25); + proto_item_append_text(ti_data_struct,": %g - %g msec", tvb_get_letohs(tvb, offset+i+2)*1.25, tvb_get_letohs(tvb, offset+i+4)*1.25); + break; + case 0x16: /* Service Data */ + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_sc_uuid16, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + break; + case 0x17: /* Public Target Address */ + case 0x18: /* Random Target Address */ + { + j=0; + while(j<(length-1)) + { + dissect_bthci_cmd_bd_addr(tvb, offset+i+j+2, pinfo, ti_data_struct_subtree); + j+=6; + } + break; + } + case 0x19: /* Appearance */ + { + guint16 appearance = tvb_get_letohs(tvb, offset+i+2); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_appearance, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_data_struct,": %s", val_to_str(appearance, bthci_cmd_appearance_vals, "Unknown")); break; + } default: - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_cmd_eir_data, tvb, offset+i+2, length-1, ENC_NA); + proto_tree_add_item(ti_data_struct_subtree, hf_bthci_cmd_eir_data, tvb, offset+i+2, length-1, ENC_LITTLE_ENDIAN); break; } i += length+1; @@ -940,7 +1305,32 @@ dissect_bthci_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *pinfo } } - return offset+240; + return offset+data_size; +} + +static int +dissect_bthci_cmd_flow_spec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, gboolean tx) +{ + proto_item *ti_flow_spec=NULL; + proto_tree *ti_flow_spec_subtree=NULL; + + ti_flow_spec = proto_tree_add_none_format(tree, hf_bthci_cmd_flow_spec, tvb, offset, 16, tx?"Tx Flow Spec ":"Rx Flow Spec"); + ti_flow_spec_subtree = proto_item_add_subtree(ti_flow_spec, ett_flow_spec_subtree); + + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flow_spec_identifier, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flow_spec_service_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flow_spec_sdu_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flow_spec_sdu_arrival_time, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flow_spec_access_latency, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(ti_flow_spec_subtree, hf_bthci_cmd_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + return offset; } static int @@ -953,7 +1343,8 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot case 0x0001: /* Inquiry */ proto_tree_add_item(tree, hf_bthci_cmd_lap, tvb, offset, 3, ENC_LITTLE_ENDIAN); offset+=3; - proto_tree_add_item(tree, hf_bthci_cmd_inq_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + item = proto_tree_add_item(tree, hf_bthci_cmd_inq_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g sec)", 1.28*tvb_get_guint8(tvb, offset)); offset++; proto_tree_add_item(tree, hf_bthci_cmd_num_responses, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -964,13 +1355,16 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot break; case 0x0003: /* Periodic Inquiry Mode */ - proto_tree_add_item(tree, hf_bthci_cmd_max_period_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + item = proto_tree_add_item(tree, hf_bthci_cmd_max_period_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g sec)", 1.28*tvb_get_letohs(tvb, offset)); offset+=2; - proto_tree_add_item(tree, hf_bthci_cmd_min_period_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + item = proto_tree_add_item(tree, hf_bthci_cmd_min_period_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g sec)", 1.28*tvb_get_letohs(tvb, offset)); offset+=2; proto_tree_add_item(tree, hf_bthci_cmd_lap, tvb, offset, 3, ENC_LITTLE_ENDIAN); offset+=3; - proto_tree_add_item(tree, hf_bthci_cmd_inq_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + item = proto_tree_add_item(tree, hf_bthci_cmd_inq_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g sec)", 1.28*tvb_get_guint8(tvb, offset)); offset++; proto_tree_add_item(tree, hf_bthci_cmd_num_responses, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1005,7 +1399,7 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot item = proto_tree_add_item(tree, hf_bthci_cmd_clock_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); clock_value = tvb_get_letohs(tvb, 13) & 32767; /* only bit0-14 are valid */ - proto_item_append_text(item, " (%g ms)", 1.25*clock_value); + proto_item_append_text(item, " (%g msec)", 1.25*clock_value); proto_tree_add_item(tree, hf_bthci_cmd_clock_offset_valid , tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; @@ -1117,7 +1511,7 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot item = proto_tree_add_item(tree, hf_bthci_cmd_clock_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); clock_value = tvb_get_letohs(tvb, offset) & 32767; /* only bit0-14 are valid */ - proto_item_append_text(item, " (%g ms)", 1.25*clock_value); + proto_item_append_text(item, " (%g msec)", 1.25*clock_value); proto_tree_add_item(tree, hf_bthci_cmd_clock_offset_valid , tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; break; @@ -1194,6 +1588,12 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot offset++; break; + case 0x0034: /* IO Capability Request Negative Reply */ + offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); + proto_tree_add_item(tree, hf_bthci_cmd_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + case 0x002c: /* User Confirmation Request Reply */ case 0x002d: /* User Confirmation Request Negative Reply */ case 0x002f: /* User Passkey Request Negative Reply */ @@ -1211,18 +1611,64 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot case 0x0030: /* Remote OOB Data Request Reply */ offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); - proto_tree_add_item(tree, hf_bthci_cmd_hash_c, tvb, offset, 2, ENC_LITTLE_ENDIAN); - offset+=2; - proto_tree_add_item(tree, hf_bthci_cmd_randomizer_r, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_hash_c, tvb, offset, 16, ENC_LITTLE_ENDIAN); + offset+=16; + proto_tree_add_item(tree, hf_bthci_cmd_randomizer_r, tvb, offset, 16, ENC_LITTLE_ENDIAN); + offset+=16; + break; + + case 0x0035: /* Create Physical Link */ + case 0x0036: /* Accept Physical Link */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_dedicated_amp_key_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_dedicated_amp_key_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_dedicated_amp_key, tvb, offset, -1, ENC_NA); + offset+=tvb_length_remaining(tvb, offset); + break; + + case 0x0037: /* Disconnect Physical Link */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0038: /* Create Logical Link */ + case 0x0039: /* Accept Logical Link */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_cmd_flow_spec(tvb, offset, pinfo, tree, TRUE); + offset = dissect_bthci_cmd_flow_spec(tvb, offset, pinfo, tree, FALSE); + break; + + case 0x003a: /* Disconnect Logical Link */ + proto_tree_add_item(tree, hf_bthci_cmd_logical_link_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; break; + case 0x003b: /* Logical Link Cancel */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_flow_spec_identifier, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x003c: /* Flow Spec Modify */ + proto_tree_add_item(tree, hf_bthci_cmd_logical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_cmd_flow_spec(tvb, offset, pinfo, tree, TRUE); + offset = dissect_bthci_cmd_flow_spec(tvb, offset, pinfo, tree, FALSE); + break; + default: proto_tree_add_item(tree, hf_bthci_cmd_params, tvb, offset, -1, ENC_NA); offset+=tvb_length_remaining(tvb, offset); break; } -return offset; + return offset; } static int @@ -1314,9 +1760,10 @@ dissect_link_policy_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto break; case 0x000d: /* Write Link Policy Settings */ - case 0x000f: /* Write Default Link Policy Settings */ proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; + /* deliberately fall through */ + case 0x000f: /* Write Default Link Policy Settings */ proto_tree_add_item(tree, hf_bthci_cmd_link_policy_setting_switch, tvb, offset, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(tree, hf_bthci_cmd_link_policy_setting_hold , tvb, offset, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(tree, hf_bthci_cmd_link_policy_setting_sniff , tvb, offset, 2, ENC_LITTLE_ENDIAN); @@ -1629,7 +2076,7 @@ dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pin proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; - proto_tree_add_item(tree, hf_bthci_cmd_power_level_type, + proto_tree_add_item(tree, hf_bthci_cmd_tx_power_level_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; @@ -1755,7 +2202,7 @@ dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pin case 0x0052: /* Write Extended Inquiry Response */ proto_tree_add_item(tree, hf_bthci_cmd_fec_required, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; - offset=dissect_bthci_ext_inquiry_response(tvb, offset, pinfo, tree); + offset=dissect_bthci_eir_ad_data(tvb, offset, pinfo, tree, 240); break; case 0x0053: /* Refresh Encryption Key */ @@ -1792,6 +2239,81 @@ dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pin offset++; break; + case 0x0062: /* Write Logical Link Accept Timeout */ + item = proto_tree_add_item(tree, hf_bthci_cmd_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " slots (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + break; + + case 0x0063: /* Set Event Mask Page 2 */ + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_00, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_01, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_02, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_03, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_04, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_05, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_06, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_07, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_10, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_11, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_12, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_13, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_14, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_evt_mask2_15, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=7; + break; + + case 0x0065: /* Write Location Data */ + proto_tree_add_item(tree, hf_bthci_cmd_location_domain_aware, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_location_domain, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_location_domain_options, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_location_options, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0067: /* Write Flow Control Mode */ + proto_tree_add_item(tree, hf_bthci_cmd_flow_control_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0068: /* Read Enhanced Tx Power Level */ + proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_tx_power_level_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0069: /* Read Best Effort Flush Timeout */ + proto_tree_add_item(tree, hf_bthci_cmd_logical_link_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + + case 0x006a: /* Write Best Effort Flush Timeout */ + proto_tree_add_item(tree, hf_bthci_cmd_logical_link_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + break; + + case 0x006b: /* Short Range Mode */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_short_range_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x006d: /* Write LE Host Supported */ + proto_tree_add_item(tree, hf_bthci_cmd_le_supported_host, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_simultaneous_host, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + default: proto_tree_add_item(tree, hf_bthci_cmd_params, tvb, offset, -1, ENC_NA); offset+=tvb_length_remaining(tvb, offset); @@ -1818,7 +2340,7 @@ dissect_informational_parameters_cmd(tvbuff_t *tvb, int offset, packet_info *pin break; } -return offset; + return offset; } static int @@ -1832,6 +2354,7 @@ dissect_status_parameters_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, case 0x0003: /* Get Link Quality */ case 0x0005: /* Read RSSI */ case 0x0006: /* Read AFH Channel Map */ + case 0x0008: /* Read Encryption Key Size */ proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset+=2; break; @@ -1843,6 +2366,29 @@ dissect_status_parameters_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, offset++; break; + case 0x0009: /* Read Local AMP Info */ + break; + + case 0x000a: /* Read Local AMP Assoc */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_length_so_far, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_amp_assoc_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + + case 0x000b: /* Write Remote AMP Assoc */ + proto_tree_add_item(tree, hf_bthci_cmd_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_length_so_far, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_amp_remaining_assoc_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_amp_assoc_fragment, tvb, offset, -1, ENC_NA); + offset+=tvb_length_remaining(tvb, offset); + break; + default: proto_tree_add_item(tree, hf_bthci_cmd_params, tvb, offset, -1, ENC_NA); offset+=tvb_length_remaining(tvb, offset); @@ -1867,6 +2413,13 @@ dissect_testing_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tre offset++; break; + case 0x0007: /* Enable AMP Receiver Reports */ + proto_tree_add_item(tree, hf_bthci_cmd_enable_amp_recv_reports, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_amp_recv_report_interval, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + default: proto_tree_add_item(tree, hf_bthci_cmd_params, tvb, offset, -1, ENC_NA); offset+=tvb_length_remaining(tvb, offset); @@ -1876,6 +2429,206 @@ dissect_testing_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tre return offset; } +static void +dissect_le_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 cmd_ocf) +{ + proto_item *item; + + switch(cmd_ocf) { + + case 0x0001: /* LE Set Event Mask */ + proto_tree_add_item(tree, hf_bthci_cmd_le_evt_mask_00, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_evt_mask_01, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_evt_mask_02, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_evt_mask_03, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_evt_mask_04, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=8; + break; + + case 0x0005: /* LE Set Random Address */ + offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); + break; + + case 0x0006: /* LE Set Advertising Parameters */ + item = proto_tree_add_item(tree, hf_bthci_cmd_le_advts_interval_min, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_advts_interval_max, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_own_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_direct_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_channel_map_1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_channel_map_2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_channel_map_3, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_filter_policy, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0008: /* LE Set Advertising Data */ + case 0x0009: /* LE Set Scan Response Data */ + proto_tree_add_item(tree, hf_bthci_cmd_le_data_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_eir_ad_data(tvb, offset, pinfo, tree, 31); + break; + + case 0x000a: /* LE Set Advertise Enable */ + proto_tree_add_item(tree, hf_bthci_cmd_le_advts_enable, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x000b: /* LE Set Scan Parameters */ + proto_tree_add_item(tree, hf_bthci_cmd_le_scan_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_scan_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_scan_window, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_le_own_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_scan_filter_policy, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x000c: /* LE Set Scan Enable */ + proto_tree_add_item(tree, hf_bthci_cmd_le_scan_enable, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_filter_dublicates, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x000d: /* LE Create Connection */ + item = proto_tree_add_item(tree, hf_bthci_cmd_le_scan_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_scan_window, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_le_initiator_filter_policy, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_le_peer_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); + proto_tree_add_item(tree, hf_bthci_cmd_le_own_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_min, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_max, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (number events)"); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_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; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_min_ce_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_max_ce_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + break; + + case 0x0011: /* LE Add Device To White List */ + case 0x0012: /* LE Remove Device From White List */ + proto_tree_add_item(tree, hf_bthci_cmd_le_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_cmd_bd_addr(tvb, offset, pinfo, tree); + break; + + case 0x0013: /* LE Connection Update */ + proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_min, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_interval_max, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_con_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (number events)"); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_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; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_min_ce_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_cmd_le_max_ce_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + break; + + case 0x0014: /* LE Set Host Channel Classification */ + proto_tree_add_item(tree, hf_bthci_cmd_le_channel_map, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=5; + break; + + case 0x0015: /* LE Read Channel Map */ + case 0x0016: /* LE Read Remote Used Features */ + case 0x001b: /* LE Long Term Key Request Negative Reply */ + proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + + case 0x0017: /* LE Encrypt */ + proto_tree_add_item(tree, hf_bthci_cmd_key, tvb, offset, 16, ENC_NA); + offset+=16; + proto_tree_add_item(tree, hf_bthci_cmd_plaintext_data, tvb, offset, 16, ENC_NA); + offset+=16; + break; + + case 0x0019: /* LE Start Encryption */ + proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_random_number, tvb, offset, 8, ENC_NA); + offset+=8; + proto_tree_add_item(tree, hf_bthci_cmd_encrypted_diversifier, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_le_long_term_key, tvb, offset, 16, ENC_NA); + offset+=16; + break; + + case 0x001a: /* LE Long Term Key Request Reply */ + proto_tree_add_item(tree, hf_bthci_cmd_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_cmd_le_long_term_key, tvb, offset, 16, ENC_NA); + offset+=16; + break; + + case 0x001d: /* LE Receiver Test */ + item = proto_tree_add_item(tree, hf_bthci_cmd_rx_freqency, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g MHz)", 2402 + 2*tvb_get_guint8(tvb, offset)); + offset++; + break; + + case 0x001e: /* LE Transmitter Test */ + item = proto_tree_add_item(tree, hf_bthci_cmd_tx_freqency, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g MHz)", 2402 + 2*tvb_get_guint8(tvb, offset)); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_test_data_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_cmd_test_packet_payload, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + default: + proto_tree_add_item(tree, hf_bthci_cmd_params, tvb, offset, -1, ENC_NA); + offset+=tvb_length_remaining(tvb, offset); + break; + } +} + /* Code to actually dissect the packets */ static void dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) @@ -1941,6 +2694,10 @@ dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) dissect_testing_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf); break; + case 0x08: /* Low Energy Command */ + dissect_le_cmd(tvb, offset, pinfo, bthci_cmd_tree, ocf); + break; + default: proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_params, tvb, 3, -1, ENC_NA); break; @@ -2001,7 +2758,7 @@ proto_register_bthci_cmd(void) }, { &hf_bthci_cmd_encrypt_mode, { "Encryption Mode", "bthci_cmd.encrypt_mode", - FT_UINT8, BASE_HEX, VALS(encrypt_mode_vals), 0x0, + FT_UINT8, BASE_HEX, VALS(cmd_encrypt_mode_vals), 0x0, NULL, HFILL } }, { &hf_bthci_cmd_bd_addr, @@ -2071,17 +2828,17 @@ proto_register_bthci_cmd(void) }, { &hf_bthci_cmd_page_scan_mode, { "Page Scan Mode", "bthci_cmd.page_scan_mode", - FT_UINT8, BASE_HEX, VALS(cmd_page_scan_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_modes), 0x0, NULL, HFILL } }, { &hf_bthci_cmd_page_scan_repetition_mode, { "Page Scan Repetition Mode", "bthci_cmd.page_scan_repetition_mode", - FT_UINT8, BASE_HEX, VALS(cmd_page_scan_repetition_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_repetition_modes), 0x0, NULL, HFILL } }, { &hf_bthci_cmd_page_scan_period_mode, { "Page Scan Period Mode", "bthci_cmd.page_scan_period_mode", - FT_UINT8, BASE_HEX, VALS(cmd_page_scan_period_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_period_modes), 0x0, NULL, HFILL } }, { &hf_bthci_cmd_clock_offset, @@ -2099,12 +2856,6 @@ proto_register_bthci_cmd(void) FT_UINT8, BASE_HEX, VALS(cmd_role_switch_modes), 0x0, NULL, HFILL } }, - { &hf_bthci_cmd_status, - { "Status", "bthci_cmd.status", - FT_UINT8, BASE_HEX|BASE_EXT_STRING, &bthci_cmd_status_vals_ext, 0x0, - NULL, HFILL } - }, - { &hf_bthci_cmd_max_period_length, { "Max Period Length", "bthci_cmd.max_period_length", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -2367,7 +3118,7 @@ proto_register_bthci_cmd(void) }, { &hf_bthci_cmd_scan_enable, { "Scan Enable", "bthci_cmd.scan_enable", - FT_UINT8, BASE_HEX, VALS(cmd_scan_enable_values), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_scan_enable_values), 0x0, NULL, HFILL } }, { &hf_bthci_cmd_interval, @@ -2671,11 +3422,6 @@ proto_register_bthci_cmd(void) FT_UINT16, BASE_DEC, NULL, 0x0, "Total Number of HCI SCO Data Packets that can be stored in the data buffers of the Host", HFILL } }, - { &hf_bthci_cmd_power_level_type, - {"Type", "bthci_cmd.power_level_type", - FT_UINT8, BASE_HEX, VALS(cmd_power_level_types), 0x0, - NULL, HFILL} - }, { &hf_bthci_cmd_loopback_mode, {"Loopback Mode", "bthci_cmd.loopback_mode", FT_UINT8, BASE_HEX, VALS(cmd_loopback_modes), 0x0, @@ -2838,12 +3584,12 @@ proto_register_bthci_cmd(void) }, { &hf_bthci_cmd_hash_c, {"Hash C", "bthci_cmd.hash_c", - FT_UINT16, BASE_DEC, NULL, 0x0, + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }, { &hf_bthci_cmd_randomizer_r, {"Randomizer R", "bthci_cmd.randomizer_r", - FT_UINT16, BASE_DEC, NULL, 0x0, + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }, { &hf_bthci_cmd_simple_pairing_mode, @@ -2858,13 +3604,13 @@ proto_register_bthci_cmd(void) }, { &hf_bthci_cmd_notification_type, {"Notification Type", "bthci_cmd.notification_type", - FT_UINT8, BASE_DEC, VALS(cmd_notification_types), 0x0, + FT_UINT8, BASE_DEC, VALS(bthci_cmd_notification_types), 0x0, NULL, HFILL} }, { &hf_bthci_cmd_eir_data, {"Data", "bthci_cmd.eir_data", FT_BYTES, BASE_NONE, NULL, 0x0, - "EIR Data", HFILL} + NULL, HFILL} }, { &hf_bthci_cmd_eir_struct_length, { "Length", "bthci_cmd.eir_struct_length", @@ -2890,7 +3636,469 @@ proto_register_bthci_cmd(void) { "UUID", "bthci_cmd.service_class_uuid128", FT_BYTES, BASE_NONE, NULL, 0x0, "128-bit Service Class UUID", HFILL } - } + }, + { &hf_bthci_cmd_physical_link_handle, + {"Physical Link Handle", "bthci_cmd.physical_link_handle", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_cmd_dedicated_amp_key_length, + {"Dedicated AMP Key Length", "bthci_cmd.dedicated_amp_key_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_cmd_dedicated_amp_key_type, + {"Dedicated AMP Key Type", "bthci_cmd.dedicated_amp_key_type", + FT_UINT8, BASE_DEC, VALS(bthci_cmd_amp_key_type), 0x0, + NULL, HFILL} + }, + { &hf_bthci_cmd_dedicated_amp_key, + {"Dedicated AMP Key Type", "bthci_cmd.dedicated_amp_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_cmd_flow_spec, + { "Flow Spec", "bthci_cmd.flow_spec", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_spec_sdu_size, + { "Maximum SDU Size", "bthci_cmd.sdu_size", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_spec_sdu_arrival_time, + { "SDU Inter-arrival Time (us)", "bthci_cmd.sdu_arrival_time", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_spec_identifier, + { "Identifier", "bthci_cmd.ident", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_spec_access_latency, + { "Access Latency (us)", "bthci_cmd.access_latency", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_spec_service_type, + { "Service Type", "bthci_cmd.servicetype", + FT_UINT8, BASE_HEX, VALS(cmd_flow_spec_servicetype), 0x0, + "Level of service required", HFILL } + }, + { &hf_bthci_cmd_flush_to_us, + { "Flush Timeout (us)", "bthci_cmd.flushto", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_logical_link_handle, + { "Logical Link Handle", "bthci_cmd.logical_link_handle", + FT_UINT16, BASE_HEX, NULL, 0x0FFF, + NULL, HFILL } + }, + + { &hf_bthci_cmd_evt_mask2_00, + { "Physical Link Complete", "bthci_cmd.evt_mask2_00", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + "Physical Link Complete Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_01, + { "Channel Selected", "bthci_cmd.evt_mask2_01", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + "Channel Selected Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_02, + { "Disconnection Physical Link", "bthci_cmd.evt_mask2_02", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + "Disconnection Physical Link Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_03, + { "Physical Link Loss Early Warning", "bthci_cmd.evt_mask2_03", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x08, + "Physical Link Loss Early Warning Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_04, + { "Physical Link Recovery", "bthci_cmd.evt_mask2_04", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x10, + "Physical Link Recovery Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_05, + { "Logical Link Complete", "bthci_cmd.evt_mask2_05", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x20, + "Logical Link Complete Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_06, + { "Disconnection Logical Link Complete", "bthci_cmd.evt_mask2_06", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x40, + "Disconnection Logical Link Complete Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_07, + { "Flow Spec Modify Complete", "bthci_cmd.evt_mask2_07", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x80, + "Flow Spec Modify Complete Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_10, + { "Number Of Completed Data Blocks", "bthci_cmd.evt_mask2_10", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + "Number Of Completed Data Blocks Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_11, + { "AMP Start Test", "bthci_cmd.evt_mask2_11", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + "AMP Start Test Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_12, + { "AMP Test End", "bthci_cmd.evt_mask2_12", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + "AMP Test End Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_13, + { "AMP Receiver Report", "bthci_cmd.evt_mask2_13", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x08, + "AMP Receiver Report Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_14, + { "Short Range Mode Change Complete", "bthci_cmd.evt_mask2_14", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x10, + "Short Range Mode Change Complete Bit", HFILL } + }, + { &hf_bthci_cmd_evt_mask2_15, + { "AMP Status Change", "bthci_cmd.evt_mask2_15", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x20, + "AMP Status Change Bit", HFILL } + }, + { &hf_bthci_cmd_location_domain_aware, + { "Location Domain Aware", "bthci_cmd.location_domain_aware", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_location_domain, + { "Location Domain", "bthci_cmd.location_domain", + FT_STRING, BASE_NONE, NULL, 0x0, + "ISO 3166-1 Country Code", HFILL } + }, + { &hf_bthci_cmd_location_domain_options, + { "Location Domain Options", "bthci_cmd.location_domain_options", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_location_options, + { "Location Options", "bthci_cmd.location_options", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flow_control_mode, + { "Flow Control Mode", "bthci_cmd.flow_control_mode", + FT_UINT8, BASE_HEX, VALS(cmd_flow_ctrl_mode), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_tx_power_level_type, + { "Tx Power Level Type", "bthci_cmd.tx_power_level_type", + FT_UINT8, BASE_HEX, VALS(cmd_power_level_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_short_range_mode, + { "Short Range Mode", "bthci_cmd.short_range_mode", + FT_UINT8, BASE_HEX, VALS(cmd_en_disabled), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_enable_amp_recv_reports, + { "Enable AMP Receiver Reports", "bthci_cmd.enable_amp_recv_reports", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_amp_recv_report_interval, + { "AMP Receiver Report Interval (s)", "bthci_cmd.amp_recv_report_interval", + FT_UINT8, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_length_so_far, + { "Length So Far", "bthci_cmd.length_so_far", + FT_UINT16, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_amp_assoc_length, + { "AMP Assoc Length", "bthci_cmd.amp_assoc_length", + FT_UINT16, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_amp_remaining_assoc_length, + { "AMP Remaining Assoc Length", "bthci_cmd.amp_remaining_assoc_length", + FT_UINT16, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_amp_assoc_fragment, + { "AMP Assoc Fragment", "bthci_cmd.amp_assoc_fragment", + FT_BYTES, BASE_NONE, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_supported_host, + { "LE Supported Host", "bthci_cmd.le_supported_host", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_simultaneous_host, + { "Simultaneous LE Host", "bthci_cmd.le_simlutaneous_host", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + "Support for both LE and BR/EDR to same device", HFILL } + }, + { &hf_bthci_cmd_le_evt_mask_00, + { "LE Connection Complete", "bthci_cmd.le_evt_mask_00", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + "LE Connection Complete Bit", HFILL } + }, + { &hf_bthci_cmd_le_evt_mask_01, + { "LE Advertising Report", "bthci_cmd.le_evt_mask_01", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + "LE Advertising Report Bit", HFILL } + }, + { &hf_bthci_cmd_le_evt_mask_02, + { "LE Connection Update Complete", "bthci_cmd.le_evt_mask_02", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + "LE Connection Update Complete Bit", HFILL } + }, + { &hf_bthci_cmd_le_evt_mask_03, + { "LE Read Remote Used Features Complete", "bthci_cmd.le_evt_mask_03", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x08, + "LE Read Remote Used Features Complete Bit", HFILL } + }, + { &hf_bthci_cmd_le_evt_mask_04, + { "LE Long Term Key Request", "bthci_cmd.le_evt_mask_04", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x10, + "LE Long Term Key Request Bit", HFILL } + }, + { &hf_bthci_cmd_le_advts_interval_min, + { "Advertising Interval Min", "bthci_cmd.le_advts_interval_min", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_interval_max, + { "Advertising Interval Max", "bthci_cmd.le_advts_interval_max", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_type, + { "Advertising Type", "bthci_cmd.le_advts_type", + FT_UINT8, BASE_HEX, VALS(cmd_le_advertising_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_address_type, + { "Address Type", "bthci_cmd.le_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_own_address_type, + { "Own Address Type", "bthci_cmd.le_own_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_peer_address_type, + { "Peer Address Type", "bthci_cmd.le_peer_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_direct_address_type, + { "Direct Address Type", "bthci_cmd.le_direct_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_channel_map_1, + { "Channel 37", "bthci_cmd.le_advts_ch_map_1", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_channel_map_2, + { "Channel 38", "bthci_cmd.le_advts_ch_map_2", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_channel_map_3, + { "Channel 39", "bthci_cmd.le_advts_ch_map_3", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_filter_policy, + { "Advertising Filter Policy", "bthci_cmd.le_advts_filter_policy", + FT_UINT8, BASE_HEX, VALS(cmd_le_advertising_filter_policy), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_data_length, + { "Data Length", "bthci_cmd.le_data_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_advts_enable, + { "Advertising Enable", "bthci_cmd.le_advts_enable", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_scan_enable, + { "Scan Enable", "bthci_cmd.le_scan_enable", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_filter_dublicates, + { "Filter Dublicates", "bthci_cmd.le_filter_dublicates", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_scan_type, + { "Scan Type", "bthci_cmd.le_scan_type", + FT_UINT8, BASE_HEX, VALS(cmd_le_scan_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_scan_interval, + { "Scan Interval", "bthci_cmd.le_scan_interval", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_scan_window, + { "Scan Window", "bthci_cmd.le_scan_window", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_scan_filter_policy, + { "Scan Filter Policy", "bthci_cmd.le_scan_filter_policy", + FT_UINT8, BASE_HEX, VALS(cmd_le_scan_filter_policy), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_initiator_filter_policy, + { "Initiator Filter Policy", "bthci_cmd.le_initiator_filter_policy", + FT_UINT8, BASE_HEX, VALS(cmd_init_filter_policy), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_con_interval_min, + { "Connection Interval Min", "bthci_cmd.le_con_interval_min", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_con_interval_max, + { "Connection Interval Max", "bthci_cmd.le_con_interval_max", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_con_latency, + { "Connection Latency", "bthci_cmd.le_con_latency", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_supervision_timeout, + { "Supervision Timeout", "bthci_cmd.le_supv_timeout", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_min_ce_length, + { "Min CE Length", "bthci_cmd.le_min_ce_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Min. Connection Event Length", HFILL } + }, + { &hf_bthci_cmd_le_max_ce_length, + { "Max CE Length", "bthci_cmd.le_max_ce_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Max. Connection Event Length", HFILL } + }, + { &hf_bthci_cmd_le_channel_map, + { "Channel Map", "bthci_cmd.le_channel_map", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_key, + { "Key", "bthci_cmd.le_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Encryption Key", HFILL } + }, + { &hf_bthci_cmd_plaintext_data, + { "Plaintext", "bthci_cmd.le_plaintext", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_random_number, + { "Random Number", "bthci_cmd.le_random_number", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_encrypted_diversifier, + { "Encrypted Diversifier", "bthci_cmd.le_encrypted_diversifier", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_le_long_term_key, + { "Long Term Key", "bthci_cmd.le_long_tem_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_rx_freqency, + { "Rx Frequency", "bthci_cmd.rx_freqency", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_tx_freqency, + { "Tx Frequency", "bthci_cmd.tx_freqency", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_test_data_length, + { "Test Data Length", "bthci_cmd.le_test_data_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_test_packet_payload, + { "Packet Payload", "bthci_cmd.le_test_data_length", + FT_UINT8, BASE_HEX, VALS(cmd_le_test_pkt_payload), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_appearance, + { "Appearance", "bthci_cmd.le_appearance", + FT_UINT16, BASE_HEX, VALS(bthci_cmd_appearance_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_limited_disc_mode, + { "LE Limited Discoverable Mode", "bthci_cmd.le_flags_limit_disc_mode", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_general_disc_mode, + { "LE General Discoverable Mode", "bthci_cmd.le_flags_general_disc_mode", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_bredr_not_support, + { "BR/EDR Not Supported", "bthci_cmd.le_flags_bredr_not_supported", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_bredr_support_ctrl, + { "Simultaneous LE and BR/EDR to Same Device Capable (Controller)", "bthci_cmd.le_flags_bredr_support_ctrl", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_bredr_support_host, + { "Simultaneous LE and BR/EDR to Same Device Capable (Host)", "bthci_cmd.le_flags_bredr_support_host", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x10, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_oob_data_present, + { "OOB Data Present", "bthci_cmd.le_flags_le_oob_data_present", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_oob_le_supported_host, + { "LE Supported By Host", "bthci_cmd.le_flags_le_oob_le_supported_host", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_oob_le_bredr_support, + { "Simultaneous LE and BR/EDR to Same Device Capable (Host)", "bthci_cmd.le_flags_le_oob_le_bredr_support", + FT_UINT8, BASE_HEX, VALS(cmd_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_cmd_flags_le_oob_address_type, + { "Address Type", "bthci_cmd.le_flags_le_oob_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x08, + NULL, HFILL } + }, + }; /* Setup protocol subtree array */ @@ -2898,7 +4106,8 @@ proto_register_bthci_cmd(void) &ett_bthci_cmd, &ett_opcode, &ett_eir_subtree, - &ett_eir_struct_subtree + &ett_eir_struct_subtree, + &ett_flow_spec_subtree }; /* Register the protocol name and description */ diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c index 9d3aa878fe..e21bcf4e09 100644 --- a/epan/dissectors/packet-bthci_evt.c +++ b/epan/dissectors/packet-bthci_evt.c @@ -8,6 +8,8 @@ * * Updated to HCI specification 2.1 + EDR * Allan M. Madsen 2007 + * Updated to HCI specification 3.0+HS & 4.0 + * Allan M. Madsen 2012 * * $Id$ * @@ -175,6 +177,10 @@ static int hf_bthci_evt_hold_mode_act_page = -1; static int hf_bthci_evt_hold_mode_act_inquiry = -1; static int hf_bthci_evt_hold_mode_act_periodic = -1; static int hf_bthci_evt_transmit_power_level = -1; +static int hf_bthci_evt_transmit_power_level_gfsk = -1; +static int hf_bthci_evt_transmit_power_level_dqpsk = -1; +static int hf_bthci_evt_transmit_power_level_8dpsk = -1; +static int hf_bthci_evt_flush_to_us = -1; static int hf_bthci_evt_num_supp_iac = -1; static int hf_bthci_evt_num_curr_iac = -1; static int hf_bthci_evt_iac_lap = -1; @@ -224,13 +230,106 @@ static int hf_bthci_evt_auth_requirements = -1; static int hf_bthci_evt_numeric_value = -1; static int hf_bthci_evt_passkey = -1; static int hf_bthci_evt_notification_type = -1; -static int hf_bthci_evt_eir_data = -1; +static int hf_bthci_evt_data = -1; static int hf_bthci_evt_eir_struct_length = -1; static int hf_bthci_evt_eir_struct_type = -1; static int hf_bthci_evt_sc_uuid16 = -1; static int hf_bthci_evt_sc_uuid32 = -1; static int hf_bthci_evt_sc_uuid128 = -1; - +static int hf_bthci_evt_data_length = -1; + +static int hf_bthci_evt_location_domain_aware = -1; +static int hf_bthci_evt_location_domain = -1; +static int hf_bthci_evt_location_domain_options = -1; +static int hf_bthci_evt_location_options = -1; +static int hf_bthci_evt_flow_control_mode = -1; +static int hf_bthci_evt_physical_link_handle = -1; +static int hf_bthci_evt_flow_spec_identifier = -1; +static int hf_bthci_evt_logical_link_handle = -1; +static int hf_bthci_evt_max_acl_data_packet_length = -1; +static int hf_bthci_evt_data_block_length = -1; +static int hf_bthci_evt_total_num_data_blocks = -1; +static int hf_bthci_evt_enc_key_size = -1; +static int hf_bthci_evt_amp_remaining_assoc_length = -1; +static int hf_bthci_evt_amp_assoc_fragment = -1; +static int hf_bthci_evt_amp_status = -1; +static int hf_bthci_evt_total_bandwidth = -1; +static int hf_bthci_evt_max_guaranteed_bandwidth = -1; +static int hf_bthci_evt_min_latency = -1; +static int hf_bthci_evt_max_pdu_size = -1; +static int hf_bthci_evt_amp_controller_type = -1; +static int hf_bthci_evt_pal_capabilities_00 = -1; +static int hf_bthci_evt_max_amp_assoc_length = -1; +static int hf_bthci_evt_max_flush_to_us = -1; +static int hf_bthci_evt_best_effort_flush_to_us = -1; +static int hf_bthci_evt_link_loss_reason = -1; +static int hf_bthci_evt_num_compl_blocks = -1; +static int hf_bthci_evt_test_scenario = -1; +static int hf_bthci_evt_report_reason = -1; +static int hf_bthci_evt_report_event_type = -1; +static int hf_bthci_evt_num_frames = -1; +static int hf_bthci_evt_num_error_frames = -1; +static int hf_bthci_evt_num_bits = -1; +static int hf_bthci_evt_num_error_bits = -1; +static int hf_bthci_evt_short_range_mode_state = -1; +static int hf_bthci_evt_le_supported_host = -1; +static int hf_bthci_evt_le_simultaneous_host = -1; +static int hf_bthci_evt_le_acl_data_pkt_len = -1; +static int hf_bthci_evt_total_num_le_acl_data_pkts = -1; +static int hf_bthci_evt_le_feature_00 = -1; +static int hf_bthci_evt_white_list_size = -1; +static int hf_bthci_evt_le_channel_map = -1; +static int hf_bthci_evt_encrypted_data = -1; +static int hf_bthci_evt_random_number = -1; +static int hf_bthci_evt_le_num_packets = -1; +static int hf_bthci_evt_le_meta_subevent = -1; +static int hf_bthci_evt_le_peer_address_type = -1; +static int hf_bthci_evt_le_con_interval = -1; +static int hf_bthci_evt_le_con_latency = -1; +static int hf_bthci_evt_le_supervision_timeout = -1; +static int hf_bthci_evt_encrypted_diversifier = -1; +static int hf_bthci_evt_le_master_clock_accuracy = -1; +static int hf_bthci_evt_num_reports = -1; +static int hf_bthci_evt_advts_event_type = -1; +static int hf_bthci_evt_appearance = -1; +static int hf_bthci_evt_flags_limited_disc_mode = -1; +static int hf_bthci_evt_flags_general_disc_mode = -1; +static int hf_bthci_evt_flags_bredr_not_support = -1; +static int hf_bthci_evt_flags_le_bredr_support_ctrl = -1; +static int hf_bthci_evt_flags_le_bredr_support_host = -1; +static int hf_bthci_evt_flags_le_oob_data_present = -1; +static int hf_bthci_evt_flags_le_oob_le_supported_host = -1; +static int hf_bthci_evt_flags_le_oob_le_bredr_support = -1; +static int hf_bthci_evt_flags_le_oob_address_type = -1; +static int hf_bthci_evt_le_states_00 = -1; +static int hf_bthci_evt_le_states_01 = -1; +static int hf_bthci_evt_le_states_02 = -1; +static int hf_bthci_evt_le_states_03 = -1; +static int hf_bthci_evt_le_states_04 = -1; +static int hf_bthci_evt_le_states_05 = -1; +static int hf_bthci_evt_le_states_06 = -1; +static int hf_bthci_evt_le_states_07 = -1; +static int hf_bthci_evt_le_states_10 = -1; +static int hf_bthci_evt_le_states_11 = -1; +static int hf_bthci_evt_le_states_12 = -1; +static int hf_bthci_evt_le_states_13 = -1; +static int hf_bthci_evt_le_states_14 = -1; +static int hf_bthci_evt_le_states_15 = -1; +static int hf_bthci_evt_le_states_16 = -1; +static int hf_bthci_evt_le_states_17 = -1; +static int hf_bthci_evt_le_states_20 = -1; +static int hf_bthci_evt_le_states_21 = -1; +static int hf_bthci_evt_le_states_22 = -1; +static int hf_bthci_evt_le_states_23 = -1; +static int hf_bthci_evt_le_states_24 = -1; +static int hf_bthci_evt_le_states_25 = -1; +static int hf_bthci_evt_le_states_26 = -1; +static int hf_bthci_evt_le_states_27 = -1; +static int hf_bthci_evt_le_states_30 = -1; +static int hf_bthci_evt_le_states_31 = -1; +static int hf_bthci_evt_le_states_32 = -1; +static int hf_bthci_evt_le_states_33 = -1; +static int hf_bthci_evt_le_states_34 = -1; /* Initialize the subtree pointers */ static gint ett_bthci_evt = -1; @@ -239,6 +338,7 @@ static gint ett_lmp_subtree = -1; static gint ett_ptype_subtree = -1; static gint ett_eir_subtree = -1; static gint ett_eir_struct_subtree = -1; +static gint ett_le_state_subtree = -1; static const value_string evt_code_vals[] = { {0x01, "Inquiry Complete"}, @@ -292,6 +392,21 @@ static const value_string evt_code_vals[] = { {0x3b, "User Passkey Notification"}, {0x3c, "Keypress Notification"}, {0x3d, "Remote Host Supported Features Notification"}, + {0x3e, "LE Meta"}, + {0x40, "Physical Link Complete"}, + {0x41, "Channel Selected"}, + {0x42, "Disconnect Physical Link Complete"}, + {0x43, "Physical Link Loss Early Warning"}, + {0x44, "Physical Link Recovery"}, + {0x45, "Logical Link Complete"}, + {0x46, "Disconnect Logical Link Complete"}, + {0x47, "Flow Spec Modify Complete"}, + {0x48, "Number Of Completed Data Blocks"}, + {0x49, "AMP Start Test"}, + {0x4a, "AMP Test End"}, + {0x4b, "AMP Receiver Report"}, + {0x4c, "Short Range Mode Change Complete"}, + {0x4d, "AMP Status Change"}, {0xfe, "Bluetooth Logo Testing"}, {0xff, "Vendor-Specific"}, {0, NULL} @@ -361,7 +476,7 @@ static const value_string evt_hci_vers_nr[] = { }; /* Taken from https://www.bluetooth.org/technical/assignednumbers/identifiers.htm */ -static const value_string evt_comp_id[] = { +static const value_string bthci_evt_comp_id[] = { {0x0000, "Ericsson Technology Licensing"}, {0x0001, "Nokia Mobile Phones"}, {0x0002, "Intel Corp."}, @@ -488,9 +603,50 @@ static const value_string evt_comp_id[] = { {0x007B, "Hanlynn Technologies"}, {0x007C, "A & R Cambridge"}, {0x007D, "Seers Technology Co. Ltd."}, + {0x007E, "Sports Tracking Technologies Ltd."}, + {0x007F, "Autonet Mobile"}, + {0x0080, "DeLorme Publishing Company, Inc."}, + {0x0081, "WuXi Vimicro"}, + {0x0082, "Sennheiser Communications A/S"}, + {0x0083, "TimeKeeping Systems, Inc."}, + {0x0084, "Ludus Helsinki Ltd."}, + {0x0085, "BlueRadios, Inc."}, + {0x0086, "equinux AG"}, + {0x0087, "Garmin International, Inc."}, + {0x0088, "Ecotest"}, + {0x0089, "GN ReSound A/S"}, + {0x008A, "Jawbone"}, + {0x008B, "Topcon Positioning Systems, LLC"}, + {0x008C, "Qualcomm Labs, Inc."}, + {0x008D, "Zscan Software"}, + {0x008E, "Quintic Corp."}, + {0x008F, "Stollmann E+V GmbH"}, + {0x0090, "Funai Electric Co., Ltd."}, + {0x0091, "Advanced PANMOBIL systems GmbH & Co. KG"}, + {0x0092, "ThinkOptics, Inc."}, + {0x0093, "Universal Electronics, Inc."}, + {0x0094, "Airoha Technology Corp."}, + {0x0095, "NEC Lighting, Ltd."}, + {0x0096, "ODM Technology, Inc."}, + {0x0097, "Bluetrek Technologies Limited"}, + {0x0098, "zero1.tv GmbH"}, + {0x0099, "i.Tech Dynamic Global Distribution Ltd."}, + {0x009A, "Alpwise"}, + {0x009B, "Jiangsu Toppower Automotive Electronics Co., Ltd."}, + {0x009C, "Colorfy, Inc."}, + {0x009D, "Geoforce Inc."}, + {0x009E, "Bose Corporation"}, + {0x009F, "Suunto Oy"}, + {0x00A0, "Kensington Computer Products Group"}, + {0x00A1, "SR-Medizinelektronik"}, + {0x00A2, "Vertu Corporation Limited"}, + {0x00A3, "Meta Watch Ltd."}, + {0x00A4, "LINAK A/S"}, + {0x00A5, "OTL Dynamics LLC"}, {0xFFFF, "For use in internal and interoperability tests."}, {0, NULL } }; +value_string_ext bthci_evt_comp_id_ext = VALUE_STRING_EXT_INIT(bthci_evt_comp_id); static const value_string evt_service_types[] = { {0x00, "No Traffic Available"}, @@ -530,28 +686,6 @@ static const value_string evt_key_types[] = { {0, NULL } }; -static const value_string evt_page_scan_modes[] = { - {0x00, "Mandatory Page Scan Mode"}, - {0x01, "Optional Page Scan Mode I"}, - {0x02, "Optional Page Scan Mode II"}, - {0x03, "Optional Page Scan Mode III"}, - {0, NULL } -}; - -static const value_string evt_page_scan_repetition_modes[] = { - {0x00, "R0"}, - {0x01, "R1"}, - {0x02, "R2"}, - {0, NULL } -}; - -static const value_string evt_page_scan_period_modes[] = { - {0x00, "P0"}, - {0x01, "P1"}, - {0x02, "P2"}, - {0, NULL } -}; - static const value_string evt_scan_types[] = { {0x00, "Standard Scan" }, {0x01, "Interlaced Scan" }, @@ -583,14 +717,6 @@ static const value_string evt_pin_types[] = { {0, NULL } }; -static const value_string evt_scan_enable_values[] = { - {0x00, "No Scans enabled" }, - {0x01, "Inquiry Scan enabled/Page Scan disable" }, - {0x02, "Inquiry Scan disabled/Page Scan enabled" }, - {0x03, "Inquiry Scan enabled/Page Scan enabled" }, - {0, NULL } -}; - static const value_string evt_auth_enable_values[] = { {0x00, "Disabled" }, {0x01, "Enabled for all connections "}, @@ -650,16 +776,81 @@ static const value_string evt_flow_direction_values[] = { {0, NULL } }; -static const value_string evt_notification_type_vals[] = { - {0x0, "Passkey Entry Started" }, - {0x1, "Passkey Digit Entered" }, - {0x2, "Passkey Digit Erased" }, - {0x3, "Passkey Cleared" }, - {0x4, "Passkey Entry Completed" }, - {0, NULL } +static const value_string evt_flow_ctrl_mode[] = { + { 0x00, "Packet based" }, + { 0x01, "Data Block based" }, + { 0, NULL } }; -static int +static const value_string evt_amp_status[] = { + { 0x00, "Controller available but currently physically powered down" }, + { 0x01, "Controller available exclusively for Bluetooth" }, + { 0x02, "No capacity available for Bluetooth operation" }, + { 0x03, "Low capacity available for Bluetooth operation" }, + { 0x04, "Medium capacity available for Bluetooth operation" }, + { 0x05, "High capacity available for Bluetooth operation" }, + { 0x06, "Full capacity available for Bluetooth operation" }, + { 0, NULL } +}; + +static const value_string evt_controller_types[] = { + { 0x00, "Primary BR/EDR" }, + { 0x01, "802.11 AMP" }, + { 0, NULL } +}; + +static const value_string evt_link_loss_reasons[] = { + { 0x00, "Unknown" }, + { 0x01, "Range related" }, + { 0x02, "Bandwidth related" }, + { 0x03, "Resolving Conflict" }, + { 0x04, "Interference" }, + { 0, NULL } +}; + +static const value_string evt_report_reasons[] = { + { 0x00, "Configured Interval" }, + { 0x01, "Test Ended" }, + { 0, NULL } +}; + +static const value_string evt_report_event_types[] = { + { 0x00, "Frames Received" }, + { 0x01, "Frames Received & Bits in Error" }, + { 0, NULL } +}; + +static const value_string evt_le_meta_subevent[] = { + { 0x01, "LE Connection Complete" }, + { 0x02, "LE Advertising Report" }, + { 0x03, "LE Connection Update Complete" }, + { 0x04, "LE Read Remote Used Features Complete" }, + { 0x05, "LE Long Term Key Request" }, + { 0, NULL } +}; + +static const value_string evt_le_advertising_evt_types[] = { + { 0x00, "Connectable Unidirected Advertising" }, + { 0x01, "Connectable Directed Advertising" }, + { 0x02, "Scannable Unidirected Advertising" }, + { 0x03, "Non-Connectable Unidirected Advertising" }, + { 0x04, "Scan Response" }, + { 0, NULL } +}; + +static const value_string evt_master_clock_accuray[] = { + { 0x00, "500 ppm" }, + { 0x01, "250 ppm" }, + { 0x02, "150 ppm" }, + { 0x03, "100 ppm" }, + { 0x04, "75 ppm" }, + { 0x05, "50 ppm" }, + { 0x06, "30 ppm" }, + { 0x07, "20 ppm" }, + { 0, NULL } +}; + +static int dissect_bthci_evt_bd_addr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint8 i, bd_addr[6]; @@ -1261,22 +1452,26 @@ dissect_bthci_evt_inq_result_with_rssi(tvbuff_t *tvb, int offset, packet_info *p } static int -dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_eir_ad_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 size) { - guint8 length, type; - guint i, j; - proto_item *ti_eir = NULL; - proto_item *ti_eir_subtree = NULL; + guint8 i, j, length, type; + proto_item *ti_eir=NULL; + proto_item *ti_eir_subtree=NULL; if(tree){ - ti_eir=proto_tree_add_text(tree, tvb, offset, 240, "Extended Inquiry Response Data"); + if(size == 240 ) { /* EIR data */ + ti_eir=proto_tree_add_text(tree, tvb, offset, 240, "Extended Inquiry Response Data"); + } + else { /* Advertising data */ + ti_eir=proto_tree_add_text(tree, tvb, offset, size, "Advertising Data"); + } ti_eir_subtree=proto_item_add_subtree(ti_eir, ett_eir_subtree); } i=0; - while(i<240){ + while(i<size){ length = tvb_get_guint8(tvb, offset+i); - if (length != 0) { + if( length != 0 ){ proto_item *ti_eir_struct=NULL; proto_tree *ti_eir_struct_subtree=NULL; @@ -1292,10 +1487,21 @@ dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *p proto_tree_add_item(ti_eir_struct_subtree,hf_bthci_evt_eir_struct_type, tvb, offset+i+1, 1, ENC_LITTLE_ENDIAN); switch(type) { + case 0x01: /* Flags */ + if(length-1 > 0) + { + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_limited_disc_mode, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_general_disc_mode, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_bredr_not_support, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_bredr_support_ctrl, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_bredr_support_host, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + } + break; case 0x02: /* 16-bit Service Class UUIDs, incomplete list */ case 0x03: /* 16-bit Service Class UUIDs, complete list */ + case 0x14: /* 16-bit Service Solicitation UUIDs */ j=0; - while(j<(guint)(length-1)) + while(j<(guint8)(length-1)) { proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_sc_uuid16, tvb, offset+i+j+2, 2, ENC_LITTLE_ENDIAN); j+=2; @@ -1304,7 +1510,7 @@ dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *p case 0x04: /* 32-bit Service Class UUIDs, incomplete list */ case 0x05: /* 32-bit Service Class UUIDs, complete list */ j=0; - while(j<(guint)(length-1)) + while(j<(guint8)(length-1)) { proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_sc_uuid32, tvb, offset+i+j+2, 4, ENC_LITTLE_ENDIAN); j+=4; @@ -1313,7 +1519,7 @@ dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *p case 0x06: /* 128-bit Service Class UUIDs, incomplete list */ case 0x07: /* 128-bit Service Class UUIDs, complete list */ j=0; - while(j<(guint)(length-1)) + while(j<(guint8)(length-1)) { proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_sc_uuid128, tvb, offset+i+j+2, 16, ENC_NA); j+=16; @@ -1327,8 +1533,56 @@ dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *p case 0x0A: /* Tx Power Level */ proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_transmit_power_level, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); break; + case 0x0D: /* Class of Device */ + dissect_bthci_evt_cod(tvb, offset+i+2, pinfo, ti_eir_struct_subtree); + break; + case 0x0E: /* Simple Pairing Hash C */ + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_hash_c, tvb, offset+i+2, 16, ENC_NA); + break; + case 0x0F: /* Simple Pairing Randomizer R */ + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_randomizer_r, tvb, offset+i+2, 16, ENC_NA); + break; + case 0x11: /* Security Manager OOB Flags */ + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_oob_data_present, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_oob_le_supported_host, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_oob_le_bredr_support, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_flags_le_oob_address_type, tvb, offset+i+2, 1, ENC_LITTLE_ENDIAN); + break; + case 0x12: /* Slave Connection Interval Range */ + { + proto_item *item; + + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_interval, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " Min (%g msec)", tvb_get_letohs(tvb, offset+i+2)*1.25); + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_interval, tvb, offset+i+4, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " Max (%g msec)", tvb_get_letohs(tvb, offset+i+4)*1.25); + proto_item_append_text(ti_eir_struct,": %g - %g msec", tvb_get_letohs(tvb, offset+i+2)*1.25, tvb_get_letohs(tvb, offset+i+4)*1.25); + break; + } + case 0x16: /* Service Data */ + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_sc_uuid16, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_data, tvb, offset+i+4, length-3, ENC_LITTLE_ENDIAN); + break; + case 0x17: /* Public Target Address */ + case 0x18: /* Random Target Address */ + { + j=0; + while(j<(guint8)(length-1)) + { + dissect_bthci_evt_bd_addr(tvb, offset+i+j+2, pinfo, ti_eir_struct_subtree); + j+=6; + } + break; + } + case 0x19: /* Appearance */ + { + guint16 appearance = tvb_get_letohs(tvb, offset+i+2); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_appearance, tvb, offset+i+2, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_eir_struct,": %s", val_to_str_ext(appearance, &bthci_cmd_appearance_vals_ext, "Unknown")); + break; + } default: - proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_eir_data, tvb, offset+i+2, length-1, ENC_NA); + proto_tree_add_item(ti_eir_struct_subtree, hf_bthci_evt_data, tvb, offset+i+2, length-1, ENC_NA); break; } i += length+1; @@ -1338,7 +1592,7 @@ dissect_bthci_evt_ext_inquiry_response(tvbuff_t *tvb, int offset, packet_info *p } } - return offset+240; + return offset+size; } static int @@ -1438,6 +1692,254 @@ 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 _U_, proto_tree *tree) +{ + proto_item *item; + guint8 subevent_code; + + subevent_code = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_bthci_evt_le_meta_subevent, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(subevent_code, evt_le_meta_subevent, "Unknown 0x%02x")); + + offset++; + + switch(subevent_code) { + case 0x01: /* LE Connection Complete */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_role, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_le_peer_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree); + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (number events)"); + offset+=2; + 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; + proto_tree_add_item(tree, hf_bthci_evt_le_master_clock_accuracy, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + case 0x02: /* LE Advertising Report */ + { + guint8 i, num_reports, length; + + num_reports = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_bthci_evt_num_reports, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + for(i=0; i<num_reports; i++) { + proto_tree_add_item(tree, hf_bthci_evt_advts_event_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_le_peer_address_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree); + length = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_bthci_evt_data_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + offset=dissect_bthci_evt_eir_ad_data(tvb, offset, pinfo, tree, length); + proto_tree_add_item(tree, hf_bthci_evt_rssi, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + } + } + break; + case 0x03: /* LE Connection Update Complete */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset+=2; + item = proto_tree_add_item(tree, hf_bthci_evt_le_con_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (number events)"); + offset+=2; + 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; + break; + case 0x04: /* LE Read Remote Used Features Complete */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_le_feature_00, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=8; + break; + case 0x05: /* LE Long Term Key Request */ + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_random_number, tvb, offset, 8, ENC_NA); + offset+=8; + proto_tree_add_item(tree, hf_bthci_evt_encrypted_diversifier, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + default: + break; + } + return offset; +} + +static int +dissect_bthci_evt_physical_link_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_channel_select_physical_link_recovery(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_disconnect_physical_link_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_physical_link_loss_early_warning(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_link_loss_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_logical_link_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_logical_link_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_flow_spec_identifier, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_disconnect_logical_link_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_logical_link_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_flow_spec_modify_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + return offset; +} + +static int +dissect_bthci_evt_num_completed_data_blocks(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + guint8 evt_num_handles; + + proto_tree_add_item(tree, hf_bthci_evt_total_num_data_blocks, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + evt_num_handles = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_bthci_evt_num_handles, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + while(evt_num_handles--){ + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_num_compl_packets, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_num_compl_blocks, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + } + return offset; +} + +static int +dissect_bthci_evt_amp_start_stop_test +(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_test_scenario, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_amp_receiver_test(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_amp_controller_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_report_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_report_event_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_num_frames, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_num_error_frames, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_num_bits, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_num_error_bits, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + return offset; +} + +static int +dissect_bthci_evt_short_range_mode_change_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_short_range_mode_state, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int +dissect_bthci_evt_amp_status_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_amp_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + return offset; +} + +static int dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { proto_item *ti_opcode=NULL; @@ -1500,10 +2002,34 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo case 0x0c56: /* Write Simple Pairing Mode */ case 0x0c59: /* Write Inquiry Tx Power Level */ case 0x0c5b: /* Write Default Erroneous Data Reporting */ - case 0x0c60: /* Send Keypress Notification */ + case 0x0c62: /* Write Logical Link Accept Timeout */ + case 0x0c63: /* Set Event Mask Page 2 */ + case 0x0c65: /* Write Location Data */ + case 0x0c67: /* Write Flow Control Mode */ + case 0x0c6a: /* Write Best Effort Timeout */ + case 0x0c6b: /* Short Range Mode */ + case 0x0c6d: /* Write LE Host Supported */ case 0x1802: /* Write Loopback Mode */ case 0x1803: /* Enable Device Under Test Mode */ case 0x1804: /* Write Simple Pairing Debug Mode */ + case 0x1807: /* Enable AMP Receiver Reports */ + case 0x1808: /* AMP Test End */ + case 0x1809: /* AMP Test */ + case 0x2001: /* LE Set Event Mask */ + case 0x2005: /* LE Set Random Address */ + case 0x2006: /* LE Set Advertising Parameters */ + case 0x2008: /* LE Set Advertising Data */ + case 0x2009: /* LE Set Scan Response Data */ + case 0x200a: /* LE Set Advertise Enable */ + case 0x200b: /* LE Set Scan Parameters */ + case 0x200c: /* LE Set Scan Enable */ + case 0x200e: /* LE Create Connection Cancel */ + case 0x2010: /* LE Clear White List */ + case 0x2011: /* LE Add Device To White List */ + case 0x2012: /* LE Remove Device From White List */ + case 0x2014: /* LE Set Host Channel Classification */ + case 0x201d: /* LE Receiver Test */ + case 0x201e: /* LE Transmitter Test */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; @@ -1515,13 +2041,15 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo case 0x040d: /* PIN Code Request Reply */ case 0x040e: /* PIN Code Request Negative Reply */ case 0x041a: /* Remote Name Request Cancel */ - case 0x042b: /* IO Capability Response */ + case 0x042b: /* IO Capability Request Reply */ + case 0x0434: /* IO Capability Request Negative Reply */ case 0x042c: /* User Confirmation Request Reply */ case 0x042d: /* User Confirmation Request Negative Reply */ case 0x042e: /* User Passkey Request Reply */ case 0x042f: /* User Passkey Request Negative Reply */ case 0x0430: /* Remote OOB Data Request Reply */ case 0x0433: /* Remote OOB Data Request Negative Reply */ + case 0x0c60: /* Send Keypress Notification */ case 0x1009: /* Read BD_ADDR */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1538,6 +2066,8 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo case 0x0c37: /* Write Link Supervision Timeout */ case 0x0c5f: /* Enhanced Flush */ case 0x1402: /* Reset Failed Contact Counter */ + case 0x201a: /* LE Long Term Key Request Reply */ + case 0x201b: /* LE Long Term Key Request Neg Reply */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1603,6 +2133,17 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo offset+=4; break; + case 0x043b: /* Logical Link Cancel */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_bthci_evt_flow_spec_identifier, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + break; case 0x0809: /* Role Discovery */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1848,7 +2389,7 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo proto_tree_add_item(tree, hf_bthci_evt_fec_required, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; - offset=dissect_bthci_evt_ext_inquiry_response(tvb, offset, pinfo, tree); + offset=dissect_bthci_evt_eir_ad_data(tvb, offset, pinfo, tree, 240); break; case 0x0c55: /* Read Simple Pairing Mode */ @@ -1862,10 +2403,10 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo case 0x0c57: /* Read Local OOB Data */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; - proto_tree_add_item(tree, hf_bthci_evt_hash_c, tvb, offset, 2, ENC_LITTLE_ENDIAN); - offset+=2; - proto_tree_add_item(tree, hf_bthci_evt_randomizer_r, tvb, offset, 2, ENC_LITTLE_ENDIAN); - offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_hash_c, tvb, offset, 16, ENC_NA); + offset+=16; + proto_tree_add_item(tree, hf_bthci_evt_randomizer_r, tvb, offset, 16, ENC_NA); + offset+=16; break; case 0x0c58: /* Read Inquiry Response Tx Power Level */ @@ -1885,6 +2426,63 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo break; + case 0x0c61: /* Read Logical Link Accept Timeout */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + item = proto_tree_add_item(tree, hf_bthci_evt_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " slots (%g msec)", tvb_get_letohs(tvb, offset)*0.625); + offset+=2; + break; + + case 0x0c64: /* Read Location Data */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_location_domain_aware, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_location_domain, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_location_domain_options, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_location_options, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0c66: /* Read Flow Control Mode */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_flow_control_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0c68: /* Read Enhanced Tx Power Level */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_transmit_power_level_gfsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_transmit_power_level_dqpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_transmit_power_level_8dpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x0c69: /* Read Best Effort Timeout */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + break; + + case 0x0c6c: /* Read LE Host Supported */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_le_supported_host, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_le_simultaneous_host, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + case 0x1001: /* Read Local Version Information */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1966,6 +2564,17 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo break; + case 0x100a: /* Read Data Block Size */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_max_acl_data_packet_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_data_block_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_total_num_data_blocks, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + case 0x1007: /* Read Country Code */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -2040,17 +2649,198 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, packet_info *pinfo item = proto_tree_add_item(tree, hf_bthci_evt_clock_accuracy, tvb, offset, 2, ENC_LITTLE_ENDIAN); proto_item_append_text(item, " %g msec", accuracy*0.3125); offset+=2; + break; + case 0x1408: /* Read Encryption Key Size */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_enc_key_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; break; - case 0x1801: /* Read Loopback Mode */ + case 0x1409: /* Read Local AMP Info */ proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; + proto_tree_add_item(tree, hf_bthci_evt_amp_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_total_bandwidth, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_max_guaranteed_bandwidth, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_min_latency, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_max_pdu_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_amp_controller_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_pal_capabilities_00, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_max_amp_assoc_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_max_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(tree, hf_bthci_evt_best_effort_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + break; + + case 0x140a: /* Read Local AMP Assoc */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_amp_remaining_assoc_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_amp_assoc_fragment, tvb, offset, -1, ENC_NA); + offset+=tvb_length_remaining(tvb, offset); + break; + case 0x140b: /* Write Remote AMP Assoc */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_physical_link_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x1801: /* Read Loopback Mode */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; proto_tree_add_item(tree, hf_bthci_evt_loopback_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; + break; + + case 0x2002: /* LE Read Buffer Size */ + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + item = proto_tree_add_item(tree, hf_bthci_evt_le_acl_data_pkt_len, tvb, offset, 2, ENC_LITTLE_ENDIAN); + if( (tvb_get_letohs(tvb, offset) == 0) && (tvb_get_guint8(tvb, offset+2) == 0) ) + proto_item_append_text(item, " (buffers shared between BR/EDR and LE) "); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_total_num_le_acl_data_pkts, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x2003: /* LE Read Local Supported Features */ + { + proto_item *ti_le_features=NULL; + proto_item *ti_le_subtree=NULL; + + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if(tree){ + ti_le_features=proto_tree_add_text(tree, tvb, offset, 8, "LE Features"); + ti_le_subtree=proto_item_add_subtree(ti_le_features, ett_lmp_subtree); + proto_tree_add_item(ti_le_subtree,hf_bthci_evt_le_feature_00, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=8; + } break; + } + + case 0x2007: /* LE Read Advertising Channel Tx Power */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_transmit_power_level, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + } + + case 0x200f: /* LE Read White List Size */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_white_list_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + } + + case 0x2015: /* LE Read Channel Map */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_bthci_evt_le_channel_map, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=5; + break; + } + + case 0x2017: /* LE Encrypt */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_encrypted_data, tvb, offset, 16, ENC_LITTLE_ENDIAN); + offset+=16; + break; + } + + case 0x2018: /* LE Rand */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_random_number, tvb, offset, 8, ENC_NA); + offset+=8; + break; + } + + case 0x201c: /* LE Read Supported States */ + { + proto_item *ti_le_states=NULL; + proto_item *ti_le_states_subtree=NULL; + + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + ti_le_states=proto_tree_add_text(tree, tvb, offset, 8, "Supported LE States"); + ti_le_states_subtree=proto_item_add_subtree(ti_le_states, ett_le_state_subtree); + + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_00, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_01, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_02, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_03, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_04, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_05, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_06, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_07, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_10, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_11, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_12, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_13, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_14, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_15, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_16, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_17, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_20, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_21, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_22, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_23, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_24, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_25, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_26, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_27, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_30, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_31, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_32, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_33, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ti_le_states_subtree,hf_bthci_evt_le_states_34, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=5; + break; + } + + case 0x201f: /* LE Test End */ + { + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_bthci_evt_le_num_packets, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + break; + } default: proto_tree_add_item(tree, hf_bthci_evt_ret_params, tvb, offset, -1, ENC_NA); @@ -2540,7 +3330,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat case 0x2f: /* Extended Inquiry Result */ offset=dissect_bthci_evt_inq_result_with_rssi(tvb, offset, pinfo, bthci_evt_tree); - offset=dissect_bthci_evt_ext_inquiry_response(tvb, offset, pinfo, bthci_evt_tree); + offset =dissect_bthci_evt_eir_ad_data(tvb, offset, pinfo, bthci_evt_tree, 240); break; case 0x30: /* Encryption Key Refresh Complete */ @@ -2591,6 +3381,60 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat offset=dissect_bthci_evt_remote_host_sup_feat_notification(tvb, offset, pinfo, bthci_evt_tree); break; + case 0x3e: /* LE Meta */ + offset=dissect_bthci_evt_le_meta(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x40: /* Physical Link Complete */ + offset=dissect_bthci_evt_physical_link_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x41: /* Channel Selected */ + case 0x44: /* Physical Link Recovery */ + offset=dissect_bthci_evt_channel_select_physical_link_recovery(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x42: /* Disconnect Physical Link Complete */ + offset=dissect_bthci_evt_disconnect_physical_link_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x43: /* Physical Link Loss Early Warning */ + offset=dissect_bthci_evt_physical_link_loss_early_warning(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x45: /* Logical Link Complete */ + offset=dissect_bthci_evt_logical_link_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x46: /* Disconnect Logical Link Complete */ + offset=dissect_bthci_evt_disconnect_logical_link_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x47: /* Flow Spec Modify Complete */ + offset=dissect_bthci_evt_flow_spec_modify_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x48: /* Number Of Completed Data Blocks */ + offset=dissect_bthci_evt_num_completed_data_blocks(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x49: /* AMP Start Test */ + case 0x4a: /* AMP Test End */ + offset=dissect_bthci_evt_amp_start_stop_test(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x4b: /* AMP Receiver Test */ + offset=dissect_bthci_evt_amp_receiver_test(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x4c: /* Short Range Mode Change Complete */ + offset=dissect_bthci_evt_short_range_mode_change_complete(tvb, offset, pinfo, bthci_evt_tree); + break; + + case 0x4d: /* AMP Status Change */ + offset=dissect_bthci_evt_amp_status_change(tvb, offset, pinfo, bthci_evt_tree); + break; + default: proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_params, tvb, 2, -1, ENC_NA); offset+=tvb_length_remaining(tvb, offset); @@ -2598,7 +3442,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat } } -return offset; + return offset; } @@ -2738,7 +3582,7 @@ proto_register_bthci_evt(void) }, { &hf_bthci_evt_comp_id, { "Manufacturer Name", "bthci_evt.comp_id", - FT_UINT16, BASE_HEX, VALS(evt_comp_id), 0x0, + FT_UINT16, BASE_HEX | BASE_EXT_STRING, &bthci_evt_comp_id_ext, 0x0, "Manufacturer Name of Bluetooth Hardware", HFILL } }, { &hf_bthci_evt_sub_vers_nr, @@ -2818,17 +3662,17 @@ proto_register_bthci_evt(void) }, { &hf_bthci_evt_page_scan_mode, { "Page Scan Mode", "bthci_evt.page_scan_mode", - FT_UINT8, BASE_HEX, VALS(evt_page_scan_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_modes), 0x0, NULL, HFILL } }, { &hf_bthci_evt_page_scan_repetition_mode, { "Page Scan Repetition Mode", "bthci_evt.page_scan_repetition_mode", - FT_UINT8, BASE_HEX, VALS(evt_page_scan_repetition_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_repetition_modes), 0x0, NULL, HFILL } }, { &hf_bthci_evt_page_scan_period_mode, { "Page Scan Period Mode", "bthci_evt.page_scan_period_mode", - FT_UINT8, BASE_HEX, VALS(evt_page_scan_period_modes), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_page_scan_period_modes), 0x0, NULL, HFILL } }, { &hf_bthci_evt_link_type_2dh1, @@ -3228,7 +4072,7 @@ proto_register_bthci_evt(void) }, { &hf_bthci_evt_scan_enable, { "Scan", "bthci_evt.scan_enable", - FT_UINT8, BASE_HEX, VALS(evt_scan_enable_values), 0x0, + FT_UINT8, BASE_HEX, VALS(bthci_cmd_scan_enable_values), 0x0, "Scan Enable", HFILL } }, { &hf_bthci_evt_authentication_enable, @@ -3493,12 +4337,12 @@ proto_register_bthci_evt(void) }, { &hf_bthci_evt_hash_c, {"Hash C", "bthci_evt.hash_c", - FT_UINT16, BASE_DEC, NULL, 0x0, + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }, { &hf_bthci_evt_randomizer_r, {"Randomizer R", "bthci_evt.randomizer_r", - FT_UINT16, BASE_DEC, NULL, 0x0, + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }, { &hf_bthci_evt_io_capability, @@ -3528,13 +4372,13 @@ proto_register_bthci_evt(void) }, { &hf_bthci_evt_notification_type, {"Notification Type", "bthci_evt.notification_type", - FT_UINT8, BASE_DEC, VALS(evt_notification_type_vals), 0x0, + FT_UINT8, BASE_DEC, VALS(bthci_cmd_notification_types), 0x0, NULL, HFILL} }, - { &hf_bthci_evt_eir_data, - {"Data", "bthci_evt.eir_data", + { &hf_bthci_evt_data, + {"Data", "bthci_evt.data", FT_BYTES, BASE_NONE, NULL, 0x0, - "EIR Data", HFILL} + NULL, HFILL} }, { &hf_bthci_evt_eir_struct_length, { "Length", "bthci_evt.eir_struct_length", @@ -3560,7 +4404,492 @@ proto_register_bthci_evt(void) { "UUID", "bthci_evt.service_class_uuid128", FT_BYTES, BASE_NONE, NULL, 0x0, "128-bit Service Class UUID", HFILL } - } + }, + { &hf_bthci_evt_data_length, + { "Data Length", "bthci_evt.data_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_location_domain_aware, + { "Location Domain Aware", "bthci_evt.location_domain_aware", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_location_domain, + { "Location Domain", "bthci_evt.location_domain", + FT_STRING, BASE_NONE, NULL, 0x0, + "ISO 3166-1 Country Code", HFILL } + }, + { &hf_bthci_evt_location_domain_options, + { "Location Domain Options", "bthci_evt.location_domain_options", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_location_options, + { "Location Options", "bthci_evt.location_options", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_flow_control_mode, + { "Flow Control Mode", "bthci_evt.flow_control_mode", + FT_UINT8, BASE_HEX, VALS(evt_flow_ctrl_mode), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_physical_link_handle, + { "Physical Link Handle", "bthci_evt.physical_link_handle", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_flow_spec_identifier, + { "Flow Spec Identifier", "bthci_evt.flow_spec_id", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_logical_link_handle, + { "Logical Link Handle", "bthci_evt.logical_link_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_evt_max_acl_data_packet_length, + { "Max. ACL Data Packet Length", "bthci_evt.max_acl_data_packet_length", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_evt_data_block_length, + { "Max. Data Block Length", "bthci_evt.data_block_length", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_evt_total_num_data_blocks, + { "Total Number of Data Blocks", "bthci_evt.total_num_data_blocks", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + { &hf_bthci_evt_enc_key_size, + { "Encryption Key Size", "bthci_evt.enc_key_size", + FT_INT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_amp_remaining_assoc_length, + { "AMP Remaining Assoc Length", "bthci_evt.amp_remaining_assoc_length", + FT_UINT16, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_amp_assoc_fragment, + { "AMP Assoc Fragment", "bthci_evt.amp_assoc_fragment", + FT_BYTES, BASE_NONE, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_amp_status, + { "AMP Status", "bthci_evt.amp_status", + FT_UINT8, BASE_HEX, VALS(evt_amp_status), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_total_bandwidth, + { "Total Bandwidth (kbps)", "bthci_evt.total_bandwidth", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_max_guaranteed_bandwidth, + { "Max Guaranteed Bandwidth (kbps)", "bthci_evt.max_guaranteed_bandwidth", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_min_latency, + { "Min Latency (us)", "bthci_evt.min_latency", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_max_pdu_size, + { "Max PDU Size", "bthci_evt.max_pdu_size", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_amp_controller_type, + { "Controller Type", "bthci_evt.controller_type", + FT_UINT8, BASE_HEX, VALS(evt_controller_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_pal_capabilities_00, + { "Guaranteed Service", "bthci_evt.pal_capabilities", + FT_UINT16, BASE_HEX, VALS(evt_boolean), 0x0001, + NULL, HFILL } + }, + { &hf_bthci_evt_max_amp_assoc_length, + { "Max AMP Assoc Length", "bthci_evt.max_amp_assoc_length", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_max_flush_to_us, + { "Max Flush Timeout (us)", "bthci_evt.max_flush_to", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_best_effort_flush_to_us, + { "Best Effort Flush Timeout (us)", "bthci_evt.best_effort_flush_to", + FT_UINT32, BASE_DEC, 0x0, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_link_loss_reason, + { "Reason", "bthci_evt.link_loss_reason", + FT_UINT8, BASE_HEX, VALS(evt_link_loss_reasons), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_compl_blocks, + { "Number Of Completed Blocks", "bthci_evt.num_compl_blocks", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_test_scenario, + { "Test Scenario", "bthci_evt.test_scenario", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_report_reason, + { "Reason", "bthci_evt.report_reason", + FT_UINT8, BASE_HEX, VALS(evt_report_reasons), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_report_event_type, + { "Report Event Type", "bthci_evt.report_event_type", + FT_UINT8, BASE_HEX, VALS(evt_report_event_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_frames, + { "Number Of Frames", "bthci_evt.num_frames", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_error_frames, + { "Number Of Error Frames", "bthci_evt.num_error_frames", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_bits, + { "Number Of Bits", "bthci_evt.num_bits", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_error_bits, + { "Number Of Error Bits", "bthci_evt.num_error_bits", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_short_range_mode_state, + { "Short Range Mode State", "bthci_evt.short_range_mode_state", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_transmit_power_level_gfsk, + { "Transmit Power Level GFSK (dBm)", "bthci_evt.transmit_power_level_gfsk", + FT_INT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_transmit_power_level_dqpsk, + { "Transmit Power Level DQPSK (dBm)", "bthci_evt.transmit_power_level_dqpsk", + FT_INT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_transmit_power_level_8dpsk, + { "Transmit Power Level 8DPSK (dBm)", "bthci_evt.transmit_power_level_8dpsk", + FT_INT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_flush_to_us, + { "Flush Timeout (us)", "bthci_evt.flushto", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_supported_host, + { "LE Supported Host", "bthci_evt.le_supported_host", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_simultaneous_host, + { "Simultaneous LE Host", "bthci_evt.le_simlutaneous_host", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x0, + "Support for both LE and BR/EDR to same device", HFILL } + }, + { &hf_bthci_evt_le_acl_data_pkt_len, + { "LE ACL Data Packet Length", "bthci_evt.le_acl_data_pkt_len", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_total_num_le_acl_data_pkts, + { "Total Number LE ACL Data Packets", "bthci_evt.le_total_num_acl_data_pkts", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_feature_00, + { "LE Encryption", "bthci_evt.le_feature", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_white_list_size, + { "White List Size", "bthci_evt.le_white_list_size", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Max. total whitelist entries storable in controller", HFILL } + }, + { &hf_bthci_evt_le_channel_map, + { "Channel Map", "bthci_evt.le_channel_map", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_encrypted_data, + { "Plaintext", "bthci_evt.le_encrypted_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_random_number, + { "Random Number", "bthci_evt.le_random_number", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_num_packets, + { "Number of Packets", "bthci_evt.le_num_packets", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_meta_subevent, + { "Sub Event", "bthci_evt.le_meta_subevent", + FT_UINT8, BASE_HEX, VALS(evt_le_meta_subevent), 0x00, + NULL, HFILL } + }, + { &hf_bthci_evt_le_peer_address_type, + { "Peer Address Type", "bthci_evt.le_peer_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_con_interval, + { "Connection Interval", "bthci_evt.le_con_interval", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_con_latency, + { "Connection Latency", "bthci_evt.le_con_latency", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_supervision_timeout, + { "Supervision Timeout", "bthci_evt.le_supv_timeout", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_encrypted_diversifier, + { "Encrypted Diversifier", "bthci_evt.le_encrypted_diversifier", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_le_master_clock_accuracy, + { "Master Clock Accuracy", "bthci_evt.le_master_clock_accuracy", + FT_UINT8, BASE_HEX, VALS(evt_master_clock_accuray), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_num_reports, + { "Num Reports", "bthci_evt.le_num_reports", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_advts_event_type, + { "Event Type", "bthci_evt.le_advts_event_type", + FT_UINT8, BASE_HEX, VALS(evt_le_advertising_evt_types), 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_appearance, + { "Appearance", "bthci_evt.le_appearance", + FT_UINT16, BASE_HEX |BASE_EXT_STRING, &bthci_cmd_appearance_vals_ext, 0x0, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_limited_disc_mode, + { "LE Limited Discoverable Mode", "bthci_evt.le_flags_limit_disc_mode", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_general_disc_mode, + { "LE General Discoverable Mode", "bthci_evt.le_flags_general_disc_mode", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_bredr_not_support, + { "BR/EDR Not Supported", "bthci_evt.le_flags_bredr_not_supported", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_bredr_support_ctrl, + { "Simultaneous LE and BR/EDR to Same Device Capable (Controller)", "bthci_evt.le_flags_bredr_support_ctrl", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_bredr_support_host, + { "Simultaneous LE and BR/EDR to Same Device Capable (Host)", "bthci_evt.le_flags_bredr_support_host", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x10, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_oob_data_present, + { "OOB Data Present", "bthci_evt.le_flags_le_oob_data_present", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_oob_le_supported_host, + { "LE Supported By Host", "bthci_evt.le_flags_le_oob_le_supported_host", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_oob_le_bredr_support, + { "Simultaneous LE and BR/EDR to Same Device Capable (Host)", "bthci_evt.le_flags_le_oob_le_bredr_support", + FT_UINT8, BASE_HEX, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_flags_le_oob_address_type, + { "Address Type", "bthci_evt.le_flags_le_oob_address_type", + FT_UINT8, BASE_HEX, VALS(bthci_cmd_address_types_vals), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_00, + { "Non-connectable Advertising State", "bthci_evt.le_states_00", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_01, + { "Scannable Advertising State", "bthci_evt.le_states_01", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_02, + { "Connectable Advertising State", "bthci_evt.le_states_02", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_03, + { "Directed Advertising State", "bthci_evt.le_states_03", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_04, + { "Passive Scanning State", "bthci_evt.le_states_04", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x10, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_05, + { "Active Scanning State", "bthci_evt.le_states_05", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x20, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_06, + { "Initiating State. Connection State in Master Role", "bthci_evt.le_states_06", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x40, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_07, + { "Connection State in Slave Role", "bthci_evt.le_states_07", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x80, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_10, + { "Non-connectable Advertising State and Passive Scanning State combination", "bthci_evt.le_states_10", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_11, + { "Scannable Advertising State and Passive Scanning State combination", "bthci_evt.le_states_11", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_12, + { "Connectable Advertising State and Passive Scanning State combination", "bthci_evt.le_states_12", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_13, + { "Directed Advertising State and Passive Scanning State combination", "bthci_evt.le_states_13", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_14, + { "Non-connectable Advertising State and Active Scanning State combination", "bthci_evt.le_states_14", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x10, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_15, + { "Scannable Advertising State and Active Scanning State combination", "bthci_evt.le_states_15", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x20, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_16, + { "Connectable Advertising State and Active Scanning State combination", "bthci_evt.le_states_16", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x40, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_17, + { "Directed Advertising State and Active Scanning State combination", "bthci_evt.le_states_17", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x80, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_20, + { "Non-connectable Advertising State and Initiating State combination", "bthci_evt.le_states_20", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_21, + { "Scannable Advertising State and Initiating State combination", "bthci_evt.le_states_21", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_22, + { "Non-connectable Advertising State and Master Role combination", "bthci_evt.le_states_22", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_23, + { "Scannable Advertising State and Master Role combination", "bthci_evt.le_states_23", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_24, + { "Non-connectable Advertising State and Slave Role combination", "bthci_evt.le_states_24", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x10, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_25, + { "Scannable Advertising State and Slave Role combination", "bthci_evt.le_states_25", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x20, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_26, + { "Passive Scanning State and Initiating State combination", "bthci_evt.le_states_26", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x40, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_27, + { "Active Scanning State and Initiating State combination", "bthci_evt.le_states_27", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x80, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_30, + { "Passive Scanning State and Master Role combination", "bthci_evt.le_states_30", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x01, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_31, + { "Active Scanning State and Master Role combination", "bthci_evt.le_states_31", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x02, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_32, + { "Passive Scanning state and Slave Role combination", "bthci_evt.le_states_32", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x04, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_33, + { "Active Scanning state and Slave Role combination", "bthci_evt.le_states_33", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x08, + NULL, HFILL } + }, + { &hf_bthci_evt_le_states_34, + { "Initiating State and Master Role combination. Master Role and Master Role combination", "bthci_evt.le_states_34", + FT_UINT8, BASE_DEC, VALS(evt_boolean), 0x10, + NULL, HFILL } + }, }; /* Setup protocol subtree array */ @@ -3570,7 +4899,8 @@ proto_register_bthci_evt(void) &ett_lmp_subtree, &ett_ptype_subtree, &ett_eir_subtree, - &ett_eir_struct_subtree + &ett_eir_struct_subtree, + &ett_le_state_subtree }; /* Register the protocol name and description */ diff --git a/epan/dissectors/packet-btl2cap.c b/epan/dissectors/packet-btl2cap.c index 6fe26d9976..61f8f4ae3c 100644 --- a/epan/dissectors/packet-btl2cap.c +++ b/epan/dissectors/packet-btl2cap.c @@ -118,6 +118,11 @@ static int hf_btl2cap_fcs = -1; static int hf_btl2cap_sdulength = -1; static int hf_btl2cap_continuation_to = -1; static int hf_btl2cap_reassembled_in = -1; +static int hf_btl2cap_min_interval = -1; +static int hf_btl2cap_max_interval = -1; +static int hf_btl2cap_slave_latency = -1; +static int hf_btl2cap_timeout_multiplier = -1; +static int hf_btl2cap_conn_param_result = -1; /* Initialize the subtree pointers */ static gint ett_btl2cap = -1; @@ -174,6 +179,8 @@ static const value_string command_code_vals[] = { { 0x0F, "Move Channel Response" }, { 0x10, "Move Channel Confirmation" }, { 0x11, "Move Channel Confirmation Response" }, + { 0x12, "Connection Parameter Update Request" }, + { 0x13, "Connection Parameter Update Response" }, { 0, NULL } }; @@ -232,6 +239,12 @@ static const value_string configuration_result_vals[] = { { 0, NULL } }; +static const value_string conn_param_result_vals[] = { + { 0x0000, "Accepted" }, + { 0x0001, "Rejected" }, + { 0, NULL } +}; + static const value_string status_vals[] = { { 0x0000, "No further information available" }, { 0x0001, "Authentication pending" }, @@ -914,6 +927,49 @@ dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pin } static int +dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + proto_item *item; + guint16 max_interval, slave_latency; + + item = proto_tree_add_item(tree, hf_btl2cap_min_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + offset += 2; + item = proto_tree_add_item(tree, hf_btl2cap_max_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25); + max_interval = tvb_get_letohs(tvb, offset); + offset += 2; + item = proto_tree_add_item(tree, hf_btl2cap_slave_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " LL Connection Events"); + slave_latency = tvb_get_letohs(tvb, offset); + + if(slave_latency >= 500 || slave_latency > 10.0*tvb_get_letohs(tvb, offset+2)/(max_interval *1.25)) + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Parameter mismatch"); + + offset += 2; + item = proto_tree_add_item(tree, hf_btl2cap_timeout_multiplier, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_item_append_text(item, " (%g sec)", tvb_get_letohs(tvb, offset)*0.01); + offset += 2; + + return offset; +} + +static int +dissect_connparamresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +{ + guint16 result; + + result = tvb_get_letohs(tvb, offset); + proto_tree_add_item(tree, hf_btl2cap_conn_param_result, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", + val_to_str_const(result, conn_param_result_vals, "Unknown result")); + + return offset; +} + +static int dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint16 scid, dcid; @@ -1234,7 +1290,8 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) pd_save = pinfo->private_data; pinfo->private_data = l2cap_data; - if (cid == BTL2CAP_FIXED_CID_SIGNAL) { /* This is a command packet*/ + if (cid == BTL2CAP_FIXED_CID_SIGNAL || cid == BTL2CAP_FIXED_CID_LE_SIGNAL) { + /* This is a command packet*/ while (offset < (length+4)) { proto_item *ti_command; proto_tree *btl2cap_cmd_tree; @@ -1333,6 +1390,14 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset = dissect_movechanconfirmationresponse(tvb, offset, pinfo, btl2cap_cmd_tree); break; + case 0x12: /* Connection Parameter Request */ + offset = dissect_connparamrequest(tvb, offset, pinfo, btl2cap_cmd_tree); + break; + + case 0x13: /* Connection Parameter Response */ + offset = dissect_connparamresponse(tvb, offset, pinfo, btl2cap_cmd_tree); + break; + default: proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_data, tvb, offset, -1, ENC_NA); offset += tvb_reported_length_remaining(tvb, offset); @@ -1868,6 +1933,31 @@ proto_register_btl2cap(void) { "This is a continuation to the SDU in frame", "btl2cap.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0, "This is a continuation to the SDU in frame #", HFILL } + }, + { &hf_btl2cap_min_interval, + { "Min. Interval", "btl2cap.min_interval", + FT_UINT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_btl2cap_max_interval, + { "Max. Interval", "btl2cap.max_interval", + FT_UINT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_btl2cap_slave_latency, + { "Slave Latency", "btl2cap.slave_latency", + FT_UINT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_btl2cap_timeout_multiplier, + { "Timeout Multiplier", "btl2cap.timeout_multiplier", + FT_UINT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_btl2cap_conn_param_result, + { "Move Result", "btl2cap.move_result", + FT_UINT16, BASE_HEX, VALS(conn_param_result_vals), 0x0, + NULL, HFILL } } }; diff --git a/epan/dissectors/packet-btl2cap.h b/epan/dissectors/packet-btl2cap.h index 0cced175fa..7f3399e558 100644 --- a/epan/dissectors/packet-btl2cap.h +++ b/epan/dissectors/packet-btl2cap.h @@ -32,6 +32,7 @@ #define BTL2CAP_PSM_AVCTP_CTRL 0x0017 #define BTL2CAP_PSM_AVDTP 0x0019 #define BTL2CAP_PSM_AVCTP_BRWS 0x001b +#define BTL2CAP_PSM_ATT 0x001f #define BTL2CAP_DYNAMIC_PSM_START 0x1000 @@ -39,6 +40,9 @@ #define BTL2CAP_FIXED_CID_SIGNAL 0x0001 #define BTL2CAP_FIXED_CID_CONNLESS 0x0002 #define BTL2CAP_FIXED_CID_AMP_MAN 0x0003 +#define BTL2CAP_FIXED_CID_ATT 0x0004 +#define BTL2CAP_FIXED_CID_LE_SIGNAL 0x0005 +#define BTL2CAP_FIXED_CID_SMP 0x0006 #define BTL2CAP_FIXED_CID_AMP_TEST 0x003F #define BTL2CAP_FIXED_CID_MAX 0x0040 diff --git a/epan/dissectors/packet-btsmp.c b/epan/dissectors/packet-btsmp.c new file mode 100644 index 0000000000..8c9aef0862 --- /dev/null +++ b/epan/dissectors/packet-btsmp.c @@ -0,0 +1,408 @@ +/* packet-btsmp.c + * Routines for Bluetooth Security Manager Protocol dissection + * + * Copyright 2012, Allan M. Madsen <allan.m@madsen.dk> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <epan/packet.h> +#include "packet-btl2cap.h" + +/* Initialize the protocol and registered fields */ +static int proto_btsmp = -1; + +static int hf_btsmp_opcode = -1; +static int hf_btsmp_io_capabilities = -1; +static int hf_btsmp_oob_data_flags = -1; +static int hf_btsmp_reason = -1; +static int hf_btsmp_cfm_value = -1; +static int hf_btsmp_random = -1; +static int hf_btsmp_long_term_key = -1; +static int hf_btsmp_id_resolving_key = -1; +static int hf_btsmp_signature_key = -1; +static int hf_btsmp_bonding_flags = -1; +static int hf_btsmp_mitm_flag = -1; +static int hf_btsmp_max_enc_key_size = -1; +static int hf_btsmp_key_dist_enc = -1; +static int hf_btsmp_key_dist_id = -1; +static int hf_btsmp_key_dist_sign = -1; +static int hf_btsmp_ediv = -1; + +/* Initialize the subtree pointers */ +static gint ett_btsmp = -1; +static gint ett_btsmp_auth_req = -1; +static gint ett_btsmp_key_dist = -1; + +/* Opcodes */ +static const value_string opcode_vals[] = { + {0x01, "Pairing Request"}, + {0x02, "Pairing Response"}, + {0x03, "Pairing Confirm"}, + {0x04, "Pairing Random"}, + {0x05, "Pairing Failed"}, + {0x06, "Encryption Information"}, + {0x07, "Master Identification"}, + {0x08, "Identity Information"}, + {0x09, "Identity Address Information"}, + {0x0a, "Signing Information"}, + {0x0b, "Security Request"}, + {0x0, NULL} +}; + +/* IO capabilities */ +static const value_string io_capability_vals[] = { + {0x00, "Display Only"}, + {0x01, "Display Yes/No"}, + {0x02, "Keyboard Only"}, + {0x03, "No Input, No Output"}, + {0x04, "Keyboard, Display"}, + {0x0, NULL} +}; + +/* OOB Data present Flag */ +static const value_string oob_data_flag_vals[] = { + {0x00, "OOB Auth. Data Not Present"}, + {0x01, "OOB Auth. Data From Remote Device Present"}, + {0x0, NULL} +}; + +/* Bonding flags */ +static const value_string bonding_flag_vals[] = { + {0x00, "No Bonding"}, + {0x01, "Bonding"}, + {0x0, NULL} +}; + +/* Reason codes */ +static const value_string reason_vals[] = { + {0x01, "Passkey Entry Failed"}, + {0x02, "OOB Not Available"}, + {0x03, "Authentication Requirements"}, + {0x04, "Confirm Value Failed"}, + {0x05, "Pairing Not Supported"}, + {0x06, "Encryption Key Size"}, + {0x07, "Command Not Supported"}, + {0x08, "Unspecified Reason"}, + {0x09, "Repeated Attempts"}, + {0x0a, "Invalid Parameters"}, + {0x0, NULL} +}; + +static int +dissect_btsmp_auth_req(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti_param; + proto_tree *st_param; + guint8 param; + + param = tvb_get_guint8(tvb, offset); + ti_param=proto_tree_add_text(tree, tvb, offset, 1, "AuthReq: "); + st_param=proto_item_add_subtree(ti_param, ett_btsmp_auth_req); + proto_tree_add_item(st_param, hf_btsmp_bonding_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_param, "%s, ", val_to_str(param&0x03, bonding_flag_vals, "<unknown>")); + proto_tree_add_item(st_param, hf_btsmp_mitm_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_param, "%s", (param&0x04)?"MITM":"No MITM"); + + col_append_fstr(pinfo->cinfo, COL_INFO, "%s, %s", val_to_str(param&0x03, bonding_flag_vals, "<unknown>"), (param&0x04)?"MITM":"No MITM"); + + return offset+1; +} + +static int +dissect_btsmp_key_dist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean initiator) +{ + proto_item *ti_param; + proto_tree *st_param; + guint8 param; + + param = tvb_get_guint8(tvb, offset); + if(initiator) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Initiator Key(s): "); + ti_param=proto_tree_add_text(tree, tvb, offset, 1, "Initiator Key Distribution: "); + } + else { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Responder Key(s): "); + ti_param=proto_tree_add_text(tree, tvb, offset, 1, "Responder Key Distribution: "); + } + + st_param=proto_item_add_subtree(ti_param, ett_btsmp_key_dist); + proto_tree_add_item(st_param, hf_btsmp_key_dist_enc, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(st_param, hf_btsmp_key_dist_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(st_param, hf_btsmp_key_dist_sign, tvb, offset, 1, ENC_LITTLE_ENDIAN); + if( param & 0x01 ) { + proto_item_append_text(ti_param, "LTK "); + col_append_fstr(pinfo->cinfo, COL_INFO, "LTK "); + } + if( param & 0x02 ) { + proto_item_append_text(ti_param, "IRK "); + col_append_fstr(pinfo->cinfo, COL_INFO, "IRK "); + } + if( param & 0x04 ) { + proto_item_append_text(ti_param, "CSRK "); + col_append_fstr(pinfo->cinfo, COL_INFO, "CSRK "); + } + + return offset+1; +} + +static void +dissect_btsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; + proto_item *ti; + proto_tree *st; + guint8 opcode; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMP"); + + switch (pinfo->p2p_dir) + { + case P2P_DIR_SENT: + col_add_fstr(pinfo->cinfo, COL_INFO, "Sent "); + break; + + case P2P_DIR_RECV: + col_add_fstr(pinfo->cinfo, COL_INFO, "Rcvd "); + break; + + case P2P_DIR_UNKNOWN: + break; + + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", + pinfo->p2p_dir); + break; + } + + if (tvb_length_remaining(tvb, 0) < 1) + return; + + ti = proto_tree_add_item(tree, proto_btsmp, tvb, 0, -1, ENC_NA); + st = proto_item_add_subtree(ti, ett_btsmp); + + proto_tree_add_item(st, hf_btsmp_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN); + opcode = tvb_get_guint8(tvb, 0); + offset++; + + col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, opcode_vals, "<unknown>")); + + switch (opcode) { + case 0x01: /* Pairing Request */ + case 0x02: /* Pairing Response */ + { + col_append_fstr(pinfo->cinfo, COL_INFO, ": "); + + proto_tree_add_item(st, hf_btsmp_io_capabilities, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(st, hf_btsmp_oob_data_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st); + + proto_tree_add_item(st, hf_btsmp_max_enc_key_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, TRUE); + offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, FALSE); + break; + } + + case 0x03: /* Pairing Confirm */ + proto_tree_add_item(st, hf_btsmp_cfm_value, tvb, offset, 16, ENC_NA); + offset += 16; + break; + + case 0x04: /* Pairing Random */ + proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 16, ENC_NA); + offset += 16; + break; + + case 0x05: /* Pairing Failed */ + proto_tree_add_item(st, hf_btsmp_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str(tvb_get_guint8(tvb, offset), reason_vals, "<unknown>")); + offset++; + break; + + case 0x06: /* Encryption Information */ + proto_tree_add_item(st, hf_btsmp_long_term_key, tvb, offset, 16, ENC_NA); + offset += 16; + break; + + case 0x07: /* Master Identification */ + proto_tree_add_item(st, hf_btsmp_ediv, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 8, ENC_NA); + offset += 8; + break; + + case 0x08: /* Identity Information */ + proto_tree_add_item(st, hf_btsmp_id_resolving_key, tvb, offset, 16, ENC_NA); + offset += 16; + break; + + case 0x0a: /* Signing Informationn */ + proto_tree_add_item(st, hf_btsmp_signature_key, tvb, offset, 16, ENC_NA); + offset += 16; + break; + + case 0x0b: /* Security Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ": "); + offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st); + break; + + default: + break; + } +} + +void +proto_register_btsmp(void) +{ + static hf_register_info hf[] = { + {&hf_btsmp_opcode, + {"Opcode", "btsmp.opcode", + FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, + NULL, HFILL} + }, + {&hf_btsmp_reason, + {"Reason", "btsmp.reason", + FT_UINT8, BASE_HEX, VALS(reason_vals), 0x0, + NULL, HFILL} + }, + {&hf_btsmp_io_capabilities, + {"IO Capability", "btsmp.io_capability", + FT_UINT8, BASE_HEX, VALS(io_capability_vals), 0x0, + NULL, HFILL} + }, + {&hf_btsmp_oob_data_flags, + {"OOB Data Flags", "btsmp.oob_data_flags", + FT_UINT8, BASE_HEX, VALS(oob_data_flag_vals), 0x0, + NULL, HFILL} + }, + {&hf_btsmp_cfm_value, + {"Confirm Value", "btsmp.cfm_value", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btsmp_random, + {"Random Value", "btsmp.random_value", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btsmp_long_term_key, + {"Long Term Key", "btsmp.long_term_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btsmp_id_resolving_key, + {"Identity Resolving Key", "btsmp.id_resolving_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btsmp_signature_key, + {"Signature Key", "btsmp.signature_key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btsmp_bonding_flags, + {"Bonding Flags", "btsmp.bonding_flags", + FT_UINT8, BASE_HEX, VALS(bonding_flag_vals), 0x03, + NULL, HFILL} + }, + {&hf_btsmp_mitm_flag, + {"MITM Flag", "btsmp.mitm_flag", + FT_UINT8, BASE_DEC, NULL, 0x04, + NULL, HFILL} + }, + {&hf_btsmp_max_enc_key_size, + {"Max Encryption Key Size", "btsmp.max_enc_key_size", + FT_UINT8, BASE_DEC, NULL, 0x00, + NULL, HFILL} + }, + {&hf_btsmp_key_dist_enc, + {"Encryption Key (LTK)", "btsmp.key_dist_enc", + FT_UINT8, BASE_DEC, NULL, 0x01, + NULL, HFILL} + }, + {&hf_btsmp_key_dist_id, + {"Id Key (IRK)", "btsmp.key_dist_id", + FT_UINT8, BASE_DEC, NULL, 0x02, + NULL, HFILL} + }, + {&hf_btsmp_key_dist_sign, + {"Signature Key (CSRK)", "btsmp.key_dist_sign", + FT_UINT8, BASE_DEC, NULL, 0x04, + NULL, HFILL} + }, + {&hf_btsmp_ediv, + {"Encrypted Diversifier (EDIV)", "btsmp.ediv", + FT_UINT16, BASE_HEX, NULL, 0x00, + NULL, HFILL} + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btsmp, + &ett_btsmp_auth_req, + &ett_btsmp_key_dist + }; + + /* Register the protocol name and description */ + proto_btsmp = proto_register_protocol("Bluetooth Security Manager Protocol", + "SMP", "btsmp"); + + register_dissector("btsmp", dissect_btsmp, proto_btsmp); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btsmp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_btsmp(void) +{ + dissector_handle_t btsmp_handle; + + btsmp_handle = find_dissector("btsmp"); + dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_SMP, btsmp_handle); +} + +/* + * 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-hci_h4.h b/epan/dissectors/packet-hci_h4.h index b8929ac1cf..cf1b3e7a51 100644 --- a/epan/dissectors/packet-hci_h4.h +++ b/epan/dissectors/packet-hci_h4.h @@ -37,6 +37,7 @@ extern value_string_ext bthci_cmd_opcode_vals_ext; #define HCI_OGF_INFORMATIONAL 0x04 #define HCI_OGF_STATUS 0x05 #define HCI_OGF_TESTING 0x06 +#define HCI_OGF_LOW_ENERGY 0x08 #define HCI_OGF_LOGO_TESTING 0x3e #define HCI_OGF_VENDOR_SPECIFIC 0x3f extern value_string_ext bthci_ogf_vals_ext; @@ -46,8 +47,16 @@ extern value_string_ext bthci_cmd_service_class_type_vals_ext; extern value_string_ext bthci_cmd_major_dev_class_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 value_string_ext bthci_evt_comp_id_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[]; #endif |