2014-12-18 14:54:38 +00:00
/* packet-btbredr_rf.c
* Routines for Bluetooth Pseudoheader for BR / EDR Baseband
*
2021-01-27 06:23:52 +00:00
* Copyright 2020 , Thomas Sailer < t . sailer @ alumni . ethz . ch >
2014-12-18 14:54:38 +00:00
* Copyright 2014 , Michal Labedzki for Tieto Corporation
* Copyright 2014 , Dominic Spill < dominicgs @ gmail . com >
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
2018-02-12 11:23:27 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2014-12-18 14:54:38 +00:00
*/
# include "config.h"
# include <epan/packet.h>
# include <epan/expert.h>
2021-01-27 06:23:52 +00:00
# include <epan/proto_data.h>
# include <epan/reassemble.h>
2014-12-18 14:54:38 +00:00
# include <wiretap/wtap.h>
# include "packet-bluetooth.h"
2021-04-16 20:47:50 +00:00
# include "packet-btbredr_rf.h"
2021-01-27 06:23:52 +00:00
# include "packet-bthci_acl.h"
/*
* Future Improvements :
* - De - Whiten if the capture hardware did not already do it and we have the UAP
*/
2014-12-18 14:54:38 +00:00
static int proto_btbredr_rf = - 1 ;
2021-01-27 06:23:52 +00:00
static int proto_btbredr_fhs = - 1 ;
2014-12-18 14:54:38 +00:00
static int hf_rf_channel = - 1 ;
static int hf_uncertain_rf_channel = - 1 ;
static int hf_signal_power = - 1 ;
static int hf_invalid_signal_power = - 1 ;
static int hf_noise_power = - 1 ;
static int hf_invalid_noise_power = - 1 ;
static int hf_access_address_offenses = - 1 ;
static int hf_payload_transport_rate = - 1 ;
static int hf_payload_transport_rate_payload = - 1 ;
static int hf_payload_transport_rate_transport = - 1 ;
static int hf_payload_transport_rate_ignored = - 1 ;
static int hf_corrected_header_bits = - 1 ;
static int hf_corrected_payload_bits = - 1 ;
static int hf_lower_address_part = - 1 ;
static int hf_reference_lower_address_part = - 1 ;
static int hf_invalid_reference_lower_address_part = - 1 ;
static int hf_reference_upper_addres_part = - 1 ;
static int hf_invalid_reference_upper_addres_part = - 1 ;
static int hf_whitened_packet_header = - 1 ;
2021-01-27 06:23:52 +00:00
static int hf_invalid_packet_header = - 1 ;
2014-12-18 14:54:38 +00:00
static int hf_packet_header = - 1 ;
static int hf_packet_header_reserved = - 1 ;
static int hf_packet_header_lt_addr = - 1 ;
static int hf_packet_header_type = - 1 ;
static int hf_packet_header_type_any = - 1 ;
static int hf_packet_header_type_sco_br = - 1 ;
static int hf_packet_header_type_esco_br = - 1 ;
static int hf_packet_header_type_esco_edr = - 1 ;
static int hf_packet_header_type_acl_br = - 1 ;
static int hf_packet_header_type_acl_edr = - 1 ;
static int hf_packet_header_type_csb_br = - 1 ;
static int hf_packet_header_type_csb_edr = - 1 ;
static int hf_packet_header_flow_control = - 1 ;
static int hf_packet_header_acknowledge_indication = - 1 ;
static int hf_packet_header_sequence_number = - 1 ;
static int hf_packet_header_header_error_check = - 1 ;
2021-01-27 06:23:52 +00:00
static int hf_packet_header_broken_lt_addr = - 1 ;
static int hf_packet_header_broken_type = - 1 ;
static int hf_packet_header_broken_type_any = - 1 ;
static int hf_packet_header_broken_type_sco_br = - 1 ;
static int hf_packet_header_broken_type_esco_br = - 1 ;
static int hf_packet_header_broken_type_esco_edr = - 1 ;
static int hf_packet_header_broken_type_acl_br = - 1 ;
static int hf_packet_header_broken_type_acl_edr = - 1 ;
static int hf_packet_header_broken_type_csb_br = - 1 ;
static int hf_packet_header_broken_type_csb_edr = - 1 ;
static int hf_packet_header_broken_flow_control = - 1 ;
static int hf_packet_header_broken_acknowledge_indication = - 1 ;
static int hf_packet_header_broken_sequence_number = - 1 ;
static int hf_packet_header_broken_header_error_check = - 1 ;
2014-12-18 14:54:38 +00:00
static int hf_flags = - 1 ;
static int hf_flags_reserved_15_14 = - 1 ;
static int hf_flags_mic_pass = - 1 ;
static int hf_flags_mic_checked = - 1 ;
static int hf_flags_crc_pass = - 1 ;
static int hf_flags_crc_checked = - 1 ;
static int hf_flags_hec_pass = - 1 ;
static int hf_flags_hec_checked = - 1 ;
static int hf_flags_reference_upper_addres_part_valid = - 1 ;
static int hf_flags_rf_channel_aliasing = - 1 ;
static int hf_flags_br_edr_data_present = - 1 ;
static int hf_flags_reference_lower_address_part_valid = - 1 ;
static int hf_flags_bredr_payload_decrypted = - 1 ;
static int hf_flags_noise_power_valid = - 1 ;
static int hf_flags_signal_power_valid = - 1 ;
static int hf_flags_packet_header_and_br_edr_payload_dewhitened = - 1 ;
static int hf_whitened_data = - 1 ;
static int hf_encrypted_data = - 1 ;
static int hf_data = - 1 ;
2021-01-27 06:23:52 +00:00
static int hf_isochronous_data = - 1 ;
static int hf_asynchronous_data = - 1 ;
static int hf_l2cap_fragment = - 1 ;
static int hf_crc = - 1 ;
static int hf_payload_header2 = - 1 ;
static int hf_payload_header2_llid = - 1 ;
static int hf_payload_header2_flow = - 1 ;
static int hf_payload_header2_length = - 1 ;
static int hf_payload_header2_rfu = - 1 ;
static int hf_payload_header1 = - 1 ;
static int hf_payload_header1_llid = - 1 ;
static int hf_payload_header1_flow = - 1 ;
static int hf_payload_header1_length = - 1 ;
static int hf_l2cap_msg_fragments = - 1 ;
static int hf_l2cap_msg_fragment = - 1 ;
static int hf_l2cap_msg_fragment_overlap = - 1 ;
static int hf_l2cap_msg_fragment_overlap_conflicts = - 1 ;
static int hf_l2cap_msg_fragment_multiple_tails = - 1 ;
static int hf_l2cap_msg_fragment_too_long_fragment = - 1 ;
static int hf_l2cap_msg_fragment_error = - 1 ;
static int hf_l2cap_msg_fragment_count = - 1 ;
static int hf_l2cap_msg_reassembled_in = - 1 ;
static int hf_l2cap_msg_reassembled_length = - 1 ;
static int hf_fhs_parity = - 1 ;
static int hf_fhs_lap = - 1 ;
static int hf_fhs_eir = - 1 ;
static int hf_fhs_reserved = - 1 ;
static int hf_fhs_sr = - 1 ;
static int hf_fhs_sp = - 1 ;
static int hf_fhs_uap = - 1 ;
static int hf_fhs_nap = - 1 ;
static int hf_fhs_class = - 1 ;
static int hf_fhs_ltaddr = - 1 ;
static int hf_fhs_clk = - 1 ;
static int hf_fhs_pagescanmode = - 1 ;
2014-12-18 14:54:38 +00:00
# define FLAGS_MIC_PASS 0x2000
# define FLAGS_MIC_CHECKED 0x1000
# define FLAGS_CRC_PASS 0x0800
# define FLAGS_CRC_CHECKED 0x0400
# define FLAGS_HEC_PASS 0x0200
# define FLAGS_HEC_CHECKED 0x0100
# define FLAGS_REFERENCE_UPPER_ADDRES_PART_VALID 0x0080
# define FLAGS_RF_CHANNEL_ALIASING 0x0040
# define FLAGS_BR_EDR_DATA_PRESENT 0x0020
# define FLAGS_REFERENCE_LOWER_ADDRESS_PART_VALID 0x0010
# define FLAGS_BREDR_PAYLOAD_DECRYPTED 0x0008
# define FLAGS_NOISE_POWER_VALID 0x0004
# define FLAGS_SIGNAL_POWER_VALID 0x0002
# define FLAGS_PACKET_HEADER_AND_BR_EDR_PAYLOAD_DEWHITENED 0x0001
2020-06-19 01:14:46 +00:00
static int * const hfx_payload_transport_rate [ ] = {
2014-12-18 14:54:38 +00:00
& hf_payload_transport_rate_payload ,
& hf_payload_transport_rate_transport ,
NULL
} ;
static expert_field ei_unexpected_data = EI_INIT ;
static expert_field ei_reserved_not_zero = EI_INIT ;
static expert_field ei_incorrect_packet_header_or_hec = EI_INIT ;
static expert_field ei_packet_header_with_hec_not_checked = EI_INIT ;
2021-01-27 06:23:52 +00:00
static expert_field ei_broken_packet_header_format = EI_INIT ;
static expert_field ei_incorrect_crc = EI_INIT ;
static expert_field ei_missing_fragment_start = EI_INIT ;
static expert_field ei_esco_incorrect_ltaddr = EI_INIT ;
static expert_field ei_esco_incorrect_length = EI_INIT ;
2014-12-18 14:54:38 +00:00
static gint ett_btbredr_rf = - 1 ;
static gint ett_flags = - 1 ;
static gint ett_payload_transport_rate = - 1 ;
static gint ett_packet_header = - 1 ;
static gint ett_bluetooth_header = - 1 ;
2021-01-27 06:23:52 +00:00
static gint ett_payload_header = - 1 ;
static gint ett_l2cap_msg_fragment = - 1 ;
static gint ett_l2cap_msg_fragments = - 1 ;
static gint ett_btbredr_fhs = - 1 ;
2014-12-18 14:54:38 +00:00
static dissector_table_t packet_type_sco_br_table ;
static dissector_table_t packet_type_esco_br_table ;
static dissector_table_t packet_type_esco_edr_table ;
static dissector_table_t packet_type_acl_br_table ;
static dissector_table_t packet_type_acl_edr_table ;
static dissector_table_t packet_type_csb_br_table ;
static dissector_table_t packet_type_csb_edr_table ;
2021-01-27 06:23:52 +00:00
static dissector_handle_t btlmp_handle ;
static dissector_handle_t btl2cap_handle ;
2014-12-18 14:54:38 +00:00
static dissector_handle_t btbredr_rf_handle ;
2021-01-27 06:23:52 +00:00
static dissector_handle_t btbredr_fhs_handle ;
static wmem_tree_t * connection_info_tree ;
static wmem_tree_t * device_info_tree ;
typedef struct _device_info_t {
guint32 interface_id ;
guint32 adapter_id ;
guint8 bd_addr [ 6 ] ;
gint8 dir ;
} device_info_t ;
# define BDADDR_MASTER 0
# define BDADDR_SLAVE 1
typedef struct _btbredr_frame_info_t {
guint retransmit : 1 ; /* 0 = No, 1 = Retransmitted frame */
guint ack : 1 ; /* 0 = Nack, 1 = Ack */
guint more_fragments : 1 ; /* 0 = Last fragment, 1 = More fragments */
guint missing_start : 1 ; /* 0 = No, 1 = Missing fragment start */
guint32 l2cap_index ; /* Unique identifier for each L2CAP message */
} btbredr_frame_info_t ;
typedef struct {
bluetooth_data_t * bluetooth_data ;
connection_info_t * connection_info ;
device_info_t * device_info ;
} btbredr_fhs_data_t ;
static const guint8 null_bd_addr [ 6 ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
/* Reassembly */
static reassembly_table l2cap_msg_reassembly_table ;
static const fragment_items l2cap_msg_frag_items = {
/* Fragment subtrees */
& ett_l2cap_msg_fragment ,
& ett_l2cap_msg_fragments ,
/* Fragment fields */
& hf_l2cap_msg_fragments ,
& hf_l2cap_msg_fragment ,
& hf_l2cap_msg_fragment_overlap ,
& hf_l2cap_msg_fragment_overlap_conflicts ,
& hf_l2cap_msg_fragment_multiple_tails ,
& hf_l2cap_msg_fragment_too_long_fragment ,
& hf_l2cap_msg_fragment_error ,
& hf_l2cap_msg_fragment_count ,
/* Reassembled in field */
& hf_l2cap_msg_reassembled_in ,
/* Reassembled length field */
& hf_l2cap_msg_reassembled_length ,
/* Reassembled data field */
NULL ,
/* Tag */
" BT BR/EDR L2CAP fragments "
} ;
2014-12-18 14:54:38 +00:00
static const value_string payload_transport_rate_transport_vals [ ] = {
{ 0x00 , " Any " } ,
{ 0x01 , " SCO " } ,
{ 0x02 , " eSCO " } ,
{ 0x03 , " ACL " } ,
{ 0x04 , " CSB " } ,
{ 0 , NULL }
} ;
# define TRANSPORT_ANY 0x00
# define TRANSPORT_SCO 0x10
# define TRANSPORT_eSCO 0x20
# define TRANSPORT_ACL 0x30
# define TRANSPORT_CSB 0x40
static const value_string payload_transport_rate_payload_vals [ ] = {
{ 0x00 , " Basic Rate with GFSK demodulation " } ,
{ 0x01 , " Enhanced Data Rate with PI/2-DQPSK demodulation " } ,
{ 0x02 , " Enhanced Data Rate with 8DPSK demodulation " } ,
{ 0 , NULL }
} ;
static const value_string payload_transport_rate_payload_abbrev_vals [ ] = {
{ 0x00 , " BR 1Mbps " } ,
{ 0x01 , " EDR 2Mbps " } ,
{ 0x02 , " EDR 3Mbps " } ,
{ 0 , NULL }
} ;
# define PAYLOAD_BR 0x00
# define PAYLOAD_EDR_2 0x01
# define PAYLOAD_EDR_3 0x02
# define PACKET_TYPE_UNKNOWN -1
static const value_string packet_type_any_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " FHS " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " DH1/2-DH1 " } ,
{ 0x05 , " HV1 " } ,
{ 0x06 , " HV2/2-EV3 " } ,
{ 0x07 , " HV3/EV3/3-EV3 " } ,
{ 0x08 , " DV/3-DH1 " } ,
{ 0x09 , " AUX1 " } ,
{ 0x0A , " DM3/2-DH3 " } ,
{ 0x0B , " DH3/3-DH3 " } ,
{ 0x0C , " EV4/2-EV5 " } ,
{ 0x0D , " EV5/3-EV5 " } ,
{ 0x0E , " DM5/2-DH5 " } ,
{ 0x0F , " DH5/3-DH5 " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_sco_br_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " FHS " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " undefined " } ,
{ 0x05 , " HV1 " } ,
{ 0x06 , " HV2 " } ,
{ 0x07 , " HV3 " } ,
{ 0x08 , " DV " } ,
{ 0x09 , " undefined " } ,
{ 0x0A , " undefined " } ,
{ 0x0B , " undefined " } ,
{ 0x0C , " undefined " } ,
{ 0x0D , " undefined " } ,
{ 0x0E , " undefined " } ,
{ 0x0F , " undefined " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_esco_br_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " reserved " } ,
{ 0x03 , " reserved " } ,
{ 0x04 , " undefined " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " undefined " } ,
{ 0x07 , " EV3 " } ,
{ 0x08 , " undefined " } ,
{ 0x09 , " undefined " } ,
{ 0x0A , " undefined " } ,
{ 0x0B , " undefined " } ,
{ 0x0C , " EV4 " } ,
{ 0x0D , " EV5 " } ,
{ 0x0E , " undefined " } ,
{ 0x0F , " undefined " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_esco_edr_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " reserved " } ,
{ 0x03 , " reserved " } ,
{ 0x04 , " undefined " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " 2-EV3 " } ,
{ 0x07 , " 3-EV3 " } ,
{ 0x08 , " undefined " } ,
{ 0x09 , " undefined " } ,
{ 0x0A , " undefined " } ,
{ 0x0B , " undefined " } ,
{ 0x0C , " 2-EV5 " } ,
{ 0x0D , " 3-EV5 " } ,
{ 0x0E , " undefined " } ,
{ 0x0F , " undefined " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_acl_br_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " FHS " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " DH1 " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " undefined " } ,
{ 0x07 , " undefined " } ,
{ 0x08 , " undefined " } ,
{ 0x09 , " AUX1 " } ,
{ 0x0A , " DM3 " } ,
{ 0x0B , " DH3 " } ,
{ 0x0C , " undefined " } ,
{ 0x0D , " undefined " } ,
{ 0x0E , " DM5 " } ,
{ 0x0F , " DH5 " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_acl_edr_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " POLL " } ,
{ 0x02 , " FHS " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " 2-DH1 " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " undefined " } ,
{ 0x07 , " undefined " } ,
{ 0x08 , " 3-DH1 " } ,
{ 0x09 , " AUX1 " } ,
{ 0x0A , " 2-DH3 " } ,
{ 0x0B , " 3-DH3 " } ,
{ 0x0C , " undefined " } ,
{ 0x0D , " undefined " } ,
{ 0x0E , " 2-DH5 " } ,
{ 0x0F , " 3-DH5 " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_csb_br_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " reserved " } ,
{ 0x02 , " reserved " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " DH1 " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " undefined " } ,
{ 0x07 , " undefined " } ,
{ 0x08 , " undefined " } ,
{ 0x09 , " undefined " } ,
{ 0x0A , " DM3 " } ,
{ 0x0B , " DH3 " } ,
{ 0x0C , " undefined " } ,
{ 0x0D , " undefined " } ,
{ 0x0E , " DM5 " } ,
{ 0x0F , " DH5 " } ,
{ 0 , NULL }
} ;
static const value_string packet_type_csb_edr_vals [ ] = {
{ 0x00 , " NULL " } ,
{ 0x01 , " reserved " } ,
{ 0x02 , " reserved " } ,
{ 0x03 , " DM1 " } ,
{ 0x04 , " 2-DH1 " } ,
{ 0x05 , " undefined " } ,
{ 0x06 , " undefined " } ,
{ 0x07 , " undefined " } ,
{ 0x08 , " 3-DH1 " } ,
{ 0x09 , " undefined " } ,
{ 0x0A , " 2-DH3 " } ,
{ 0x0B , " 3-DH3 " } ,
{ 0x0C , " undefined " } ,
{ 0x0D , " undefined " } ,
{ 0x0E , " 2-DH5 " } ,
{ 0x0F , " 3-DH5 " } ,
{ 0 , NULL }
} ;
2021-01-27 06:23:52 +00:00
static const val64_string fhs_scan_repetition_vals [ ] = {
{ 0x00 , " R0 " } ,
{ 0x01 , " R1 " } ,
{ 0x02 , " R2 " } ,
{ 0 , NULL }
} ;
static const value_string fhs_page_scan_mode_vals [ ] = {
{ 0x00 , " Mandatory Scan Mode " } ,
{ 0 , NULL }
} ;
2014-12-18 14:54:38 +00:00
void proto_register_btbredr_rf ( void ) ;
void proto_reg_handoff_btbredr_rf ( void ) ;
2021-01-27 06:23:52 +00:00
static guint8
reverse_bits ( guint8 value )
2014-12-18 14:54:38 +00:00
{
2021-01-27 06:23:52 +00:00
value = ( ( value > > 1 ) & 0x55 ) | ( ( value < < 1 ) & 0xaa ) ;
value = ( ( value > > 2 ) & 0x33 ) | ( ( value < < 2 ) & 0xcc ) ;
value = ( ( value > > 4 ) & 0x0f ) | ( ( value < < 4 ) & 0xf0 ) ;
return value ;
2014-12-18 14:54:38 +00:00
}
2021-01-27 06:23:52 +00:00
static gboolean
broken_check_hec ( guint8 uap , guint32 header )
2014-12-18 14:54:38 +00:00
{
guint8 hec ;
guint16 header_data ;
guint8 lfsr ;
gint8 i ;
hec = header & 0xFF ;
header_data = ( header > > 8 ) & 0x3F ;
lfsr = uap ;
for ( i = 9 ; i > = 0 ; i - = 1 ) {
if ( lfsr & 0x80 )
lfsr ^ = 0x65 ;
lfsr = ( lfsr < < 1 ) | ( ( ( lfsr > > 7 ) ^ ( header_data > > i ) ) & 0x01 ) ;
}
lfsr = reverse_bits ( lfsr ) ;
return lfsr = = hec ;
}
2021-01-27 06:23:52 +00:00
static gboolean
check_hec ( guint8 uap , guint32 header )
{
static const guint32 crc_poly_rev_bt_hec = 0xe5 ;
header & = 0x3ffff ;
header ^ = reverse_bits ( uap ) & 0xff ;
for ( guint i = 0 ; i < 10 ; + + i , header > > = 1 )
if ( header & 1 )
header ^ = ( crc_poly_rev_bt_hec < < 1 ) ;
return ! header ;
}
static gboolean
check_crc ( guint8 uap , tvbuff_t * tvb , gint offset , gint len )
{
static const guint16 crc_poly_rev_bt_pdu = 0x8408 ;
guint16 crc = reverse_bits ( uap ) ;
crc < < = 8 ;
for ( ; len > 0 ; - - len , + + offset ) {
crc ^ = tvb_get_guint8 ( tvb , offset ) & 0xff ;
for ( guint i = 0 ; i < 8 ; + + i ) {
guint16 x = crc & 1 ;
crc > > = 1 ;
crc ^ = crc_poly_rev_bt_pdu & - x ;
}
}
return ! crc ;
}
static guint32
extract_lap ( const guint8 bd_addr [ 6 ] )
{
guint32 lap = bd_addr [ 3 ] ;
lap < < = 8 ;
lap | = bd_addr [ 4 ] ;
lap < < = 8 ;
lap | = bd_addr [ 5 ] ;
return lap ;
}
static gboolean
is_reserved_lap ( guint32 lap )
{
return ( lap > = 0x9e8b00 ) & & ( lap < = 0x9e8b3f ) ;
}
static connection_info_t *
lookup_connection_info ( guint32 interface_id , guint32 adapter_id , guint32 lap , guint32 ltaddr , guint32 pktnum )
{
connection_info_t * cinfo ;
wmem_tree_key_t key [ 6 ] ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 1 ;
key [ 3 ] . key = & ltaddr ;
key [ 4 ] . length = 1 ;
key [ 4 ] . key = & pktnum ;
key [ 5 ] . length = 0 ;
key [ 5 ] . key = NULL ;
cinfo = ( connection_info_t * ) wmem_tree_lookup32_array_le ( connection_info_tree , key ) ;
if ( ! cinfo )
return NULL ;
if ( cinfo - > interface_id ! = interface_id | | cinfo - > adapter_id ! = adapter_id | |
extract_lap ( cinfo - > bd_addr [ BDADDR_MASTER ] ) ! = lap | | cinfo - > lt_addr ! = ltaddr )
return NULL ;
return cinfo ;
}
connection_info_t *
btbredr_rf_add_esco_link ( connection_info_t * cinfo , packet_info * pinfo , guint8 handle , guint32 ltaddr , guint16 pktszms , guint16 pktszsm )
{
connection_info_t * ecinfo ;
guint32 lap ;
wmem_tree_key_t key [ 6 ] ;
if ( ! cinfo | | ! pinfo | | ltaddr > = 8 | | ! ltaddr )
return NULL ;
lap = extract_lap ( cinfo - > bd_addr [ BDADDR_MASTER ] ) ;
ecinfo = lookup_connection_info ( cinfo - > interface_id , cinfo - > adapter_id , lap , ltaddr , pinfo - > num ) ;
if ( ecinfo & & ( memcmp ( cinfo - > bd_addr [ BDADDR_MASTER ] , ecinfo - > bd_addr [ BDADDR_MASTER ] , 6 ) | |
memcmp ( cinfo - > bd_addr [ BDADDR_SLAVE ] , ecinfo - > bd_addr [ BDADDR_SLAVE ] , 6 ) | |
! ecinfo - > esco | | ecinfo - > escohandle ! = handle | | ecinfo - > escosize [ 0 ] ! = pktszms | |
ecinfo - > escosize [ 1 ] ! = pktszsm ) )
ecinfo = NULL ;
if ( ecinfo )
return ecinfo ;
ecinfo = wmem_new0 ( wmem_file_scope ( ) , connection_info_t ) ;
ecinfo - > interface_id = cinfo - > interface_id ;
ecinfo - > adapter_id = cinfo - > adapter_id ;
ecinfo - > lt_addr = ltaddr ;
ecinfo - > timestamp = cinfo - > timestamp ;
ecinfo - > btclock = cinfo - > btclock ;
memcpy ( ecinfo - > bd_addr [ BDADDR_MASTER ] , cinfo - > bd_addr [ BDADDR_MASTER ] , 6 ) ;
memcpy ( ecinfo - > bd_addr [ BDADDR_SLAVE ] , cinfo - > bd_addr [ BDADDR_SLAVE ] , 6 ) ;
ecinfo - > escosize [ 0 ] = pktszms ;
ecinfo - > escosize [ 1 ] = pktszsm ;
ecinfo - > escohandle = handle ;
ecinfo - > esco = 1 ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & cinfo - > interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & cinfo - > adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 1 ;
key [ 3 ] . key = & ltaddr ;
key [ 4 ] . length = 1 ;
key [ 4 ] . key = & pinfo - > num ;
key [ 5 ] . length = 0 ;
key [ 5 ] . key = NULL ;
wmem_tree_insert32_array ( connection_info_tree , key , ecinfo ) ;
return ecinfo ;
}
void
btbredr_rf_remove_esco_link ( connection_info_t * cinfo , packet_info * pinfo , guint8 handle )
{
connection_info_t * ecinfo ;
guint32 lap ;
wmem_tree_key_t key [ 6 ] ;
if ( ! cinfo | | ! pinfo )
return ;
lap = extract_lap ( cinfo - > bd_addr [ BDADDR_MASTER ] ) ;
for ( guint32 ltaddr = 1 ; ltaddr < 8 ; + + ltaddr ) {
ecinfo = lookup_connection_info ( cinfo - > interface_id , cinfo - > adapter_id , lap , ltaddr , pinfo - > num ) ;
if ( ! ecinfo )
continue ;
if ( memcmp ( cinfo - > bd_addr [ BDADDR_MASTER ] , ecinfo - > bd_addr [ BDADDR_MASTER ] , 6 ) | |
memcmp ( cinfo - > bd_addr [ BDADDR_SLAVE ] , ecinfo - > bd_addr [ BDADDR_SLAVE ] , 6 ) | |
! ecinfo - > esco | | ecinfo - > escohandle ! = handle )
continue ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & cinfo - > interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & cinfo - > adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 1 ;
key [ 3 ] . key = & ltaddr ;
key [ 4 ] . length = 1 ;
key [ 4 ] . key = & pinfo - > num ;
key [ 5 ] . length = 0 ;
key [ 5 ] . key = NULL ;
wmem_tree_insert32_array ( connection_info_tree , key , ecinfo ) ;
}
}
2014-12-18 14:54:38 +00:00
static gint
dissect_btbredr_rf ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
{
2021-01-27 06:23:52 +00:00
proto_item * btbredr_rf_item ;
proto_tree * btbredr_rf_tree ;
proto_item * flags_item ;
proto_tree * flags_tree ;
proto_item * header_item = NULL ;
proto_tree * header_tree ;
proto_item * reserved_item ;
proto_item * hec_item = NULL ;
gint offset = 0 ;
gint hf_x ;
gint header_mode ;
guint32 interface_id ;
guint32 adapter_id ;
guint16 flags ;
guint32 lap ;
guint8 uap = 0 ;
guint32 ltaddr ;
guint8 payload_and_transport ;
gint16 packet_type = PACKET_TYPE_UNKNOWN ;
const gchar * packet_type_str = " Unknown " ;
dissector_table_t packet_type_table = NULL ;
gboolean decrypted ;
gint isochronous_length = 0 ;
gboolean isochronous_crc = FALSE ;
gboolean isochronous_esco = FALSE ;
gint data_length = 0 ;
gint data_header = 0 ;
gboolean data_crc = FALSE ;
gboolean arqn = FALSE ;
gboolean seqn = FALSE ;
gint direction = - 1 ;
btbredr_frame_info_t * frame_info = NULL ;
connection_info_t * connection_info = NULL ;
device_info_t * device_info = NULL ;
bluetooth_data_t * bluetooth_data = ( bluetooth_data_t * ) data ;
if ( bluetooth_data )
interface_id = bluetooth_data - > interface_id ;
else if ( pinfo - > rec - > presence_flags & WTAP_HAS_INTERFACE_ID )
interface_id = pinfo - > rec - > rec_header . packet_header . interface_id ;
else
interface_id = HCI_INTERFACE_DEFAULT ;
if ( bluetooth_data )
adapter_id = bluetooth_data - > adapter_id ;
else
adapter_id = HCI_ADAPTER_DEFAULT ;
2014-12-18 14:54:38 +00:00
btbredr_rf_item = proto_tree_add_item ( tree , proto_btbredr_rf , tvb , offset , - 1 , ENC_NA ) ;
btbredr_rf_tree = proto_item_add_subtree ( btbredr_rf_item , ett_btbredr_rf ) ;
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " BT BR/EDR RF " ) ;
if ( tvb_captured_length ( tvb ) > = 21 ) {
flags = tvb_get_guint16 ( tvb , 20 , ENC_LITTLE_ENDIAN ) ;
} else {
flags = 0 ;
}
if ( flags & FLAGS_RF_CHANNEL_ALIASING )
hf_x = hf_uncertain_rf_channel ;
else
hf_x = hf_rf_channel ;
proto_tree_add_item ( btbredr_rf_tree , hf_x , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
if ( flags & FLAGS_SIGNAL_POWER_VALID )
hf_x = hf_signal_power ;
else
hf_x = hf_invalid_signal_power ;
proto_tree_add_item ( btbredr_rf_tree , hf_x , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
if ( flags & FLAGS_NOISE_POWER_VALID )
hf_x = hf_noise_power ;
else
hf_x = hf_invalid_noise_power ;
proto_tree_add_item ( btbredr_rf_tree , hf_x , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
proto_tree_add_item ( btbredr_rf_tree , hf_access_address_offenses , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
payload_and_transport = tvb_get_guint8 ( tvb , offset ) ;
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Transport: %s (%s), RF Channel: %s%2u " ,
val_to_str_const ( payload_and_transport > > 4 , payload_transport_rate_transport_vals , " Unknown " ) ,
val_to_str_const ( payload_and_transport & 0xF , payload_transport_rate_payload_abbrev_vals , " Unknown " ) ,
( flags & FLAGS_RF_CHANNEL_ALIASING ) ? " ~ " : " " ,
tvb_get_guint8 ( tvb , 0 ) ) ;
if ( payload_and_transport = = 0xFF )
proto_tree_add_item ( btbredr_rf_tree , hf_payload_transport_rate_ignored , tvb , offset , 1 , ENC_NA ) ;
else
proto_tree_add_bitmask ( btbredr_rf_tree , tvb , offset , hf_payload_transport_rate , ett_payload_transport_rate , hfx_payload_transport_rate , ENC_LITTLE_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item ( btbredr_rf_tree , hf_corrected_header_bits , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
proto_tree_add_item ( btbredr_rf_tree , hf_corrected_payload_bits , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
offset + = 2 ;
proto_tree_add_item ( btbredr_rf_tree , hf_lower_address_part , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
lap = tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) & 0xffffff ;
2014-12-18 14:54:38 +00:00
offset + = 4 ;
2021-01-27 06:23:52 +00:00
if ( ! is_reserved_lap ( lap ) ) {
wmem_tree_key_t key [ 4 ] ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 0 ;
key [ 3 ] . key = NULL ;
device_info = ( device_info_t * ) wmem_tree_lookup32_array ( device_info_tree , key ) ;
}
if ( device_info ) {
direction = ( device_info - > dir = = pinfo - > p2p_dir ) ? BDADDR_MASTER : BDADDR_SLAVE ;
uap = device_info - > bd_addr [ 2 ] ;
}
2014-12-18 14:54:38 +00:00
if ( flags & FLAGS_REFERENCE_LOWER_ADDRESS_PART_VALID )
hf_x = hf_reference_lower_address_part ;
else
hf_x = hf_invalid_reference_lower_address_part ;
proto_tree_add_item ( btbredr_rf_tree , hf_x , tvb , offset , 3 , ENC_LITTLE_ENDIAN ) ;
offset + = 3 ;
2021-01-27 06:23:52 +00:00
if ( flags & FLAGS_REFERENCE_UPPER_ADDRES_PART_VALID ) {
2014-12-18 14:54:38 +00:00
hf_x = hf_reference_upper_addres_part ;
2021-01-27 06:23:52 +00:00
uap = tvb_get_guint8 ( tvb , offset ) ;
} else {
2014-12-18 14:54:38 +00:00
hf_x = hf_invalid_reference_upper_addres_part ;
2021-01-27 06:23:52 +00:00
}
2014-12-18 14:54:38 +00:00
proto_tree_add_item ( btbredr_rf_tree , hf_x , tvb , offset , 1 , ENC_NA ) ;
offset + = 1 ;
2021-01-27 06:23:52 +00:00
{
guint32 hdr = tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
gboolean have_uap = device_info | | ! ! ( flags & FLAGS_REFERENCE_UPPER_ADDRES_PART_VALID ) ;
gboolean is_inquiry = is_reserved_lap ( lap ) ;
gboolean is_inquiry_fhs = is_inquiry & & ( ( ( hdr > > 3 ) & 0x0f ) = = 2 ) ;
gboolean is_inquiry_broken_fhs = is_inquiry & & ( ( ( hdr > > 11 ) & 0x0f ) = = 2 ) ;
if ( is_inquiry & & ! ( is_inquiry_fhs | | is_inquiry_broken_fhs ) )
header_mode = - 2 ;
else if ( ! ( flags & FLAGS_PACKET_HEADER_AND_BR_EDR_PAYLOAD_DEWHITENED ) )
header_mode = - 1 ;
else if ( ( have_uap | | is_inquiry_fhs ) & & check_hec ( is_inquiry_fhs ? 0 : uap , hdr ) )
header_mode = 1 ;
else if ( ( have_uap | | is_inquiry_broken_fhs ) & & broken_check_hec ( is_inquiry_broken_fhs ? 0 : uap , hdr ) )
header_mode = 2 ;
else if ( ! have_uap )
header_mode = - 1 ;
else
header_mode = 0 ;
}
decrypted = ! ! ( flags & FLAGS_BREDR_PAYLOAD_DECRYPTED ) ;
if ( header_mode = = - 1 ) {
proto_tree_add_item ( btbredr_rf_tree , hf_whitened_packet_header , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
} else if ( header_mode = = - 2 ) {
proto_tree_add_item ( btbredr_rf_tree , hf_invalid_packet_header , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
} else if ( header_mode = = 2 ) {
// broken header format
2014-12-18 14:54:38 +00:00
header_item = proto_tree_add_item ( btbredr_rf_tree , hf_packet_header , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
header_tree = proto_item_add_subtree ( header_item , ett_bluetooth_header ) ;
proto_tree_add_item ( header_tree , hf_packet_header_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
proto_tree_add_item ( header_tree , hf_packet_header_broken_lt_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
ltaddr = ( tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) > > 15 ) & 7 ;
arqn = ( tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) > > 9 ) & 1 ;
seqn = ( tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) > > 8 ) & 1 ;
if ( payload_and_transport = = ( TRANSPORT_SCO | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_sco_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_sco_br_vals , " Unknown " ) ;
packet_type_table = packet_type_sco_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_esco_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_esco_br_vals , " Unknown " ) ;
packet_type_table = packet_type_esco_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_esco_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_esco_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_esco_edr_table ;
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_acl_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_acl_br_vals , " Unknown " ) ;
packet_type_table = packet_type_acl_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_acl_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_acl_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_acl_edr_table ;
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_csb_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_csb_br_vals , " Unknown " ) ;
packet_type_table = packet_type_csb_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_csb_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_csb_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_csb_edr_table ;
} else if ( ( payload_and_transport > > 4 ) = = TRANSPORT_ANY ) {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type_any , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
packet_type = ( tvb_get_guint8 ( tvb , offset + 1 ) > > 3 ) & 0xF ;
packet_type_str = val_to_str_const ( packet_type , packet_type_any_vals , " Unknown " ) ;
} else {
proto_tree_add_item ( header_tree , hf_packet_header_broken_type , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
}
proto_tree_add_item ( header_tree , hf_packet_header_broken_flow_control , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_packet_header_broken_acknowledge_indication , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_packet_header_broken_sequence_number , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
hec_item = proto_tree_add_item ( header_tree , hf_packet_header_broken_header_error_check , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
} else if ( header_mode > = 0 ) {
// header format according to Core_v5.2.pdf Vol 2 Part B Chapter 6.4
header_item = proto_tree_add_item ( btbredr_rf_tree , hf_packet_header , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
header_tree = proto_item_add_subtree ( header_item , ett_bluetooth_header ) ;
2014-12-18 14:54:38 +00:00
proto_tree_add_item ( header_tree , hf_packet_header_lt_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
ltaddr = tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) & 7 ;
arqn = ( tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) > > 8 ) & 1 ;
seqn = ( tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) > > 9 ) & 1 ;
2014-12-18 14:54:38 +00:00
if ( payload_and_transport = = ( TRANSPORT_SCO | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_sco_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_sco_br_vals , " Unknown " ) ;
packet_type_table = packet_type_sco_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_esco_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_esco_br_vals , " Unknown " ) ;
packet_type_table = packet_type_esco_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_esco_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_esco_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_esco_edr_table ;
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_acl_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_acl_br_vals , " Unknown " ) ;
packet_type_table = packet_type_acl_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_acl_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_acl_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_acl_edr_table ;
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_BR ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_csb_br , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_csb_br_vals , " Unknown " ) ;
packet_type_table = packet_type_csb_br_table ;
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_csb_edr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_csb_edr_vals , " Unknown " ) ;
packet_type_table = packet_type_csb_edr_table ;
} else if ( ( payload_and_transport > > 4 ) = = TRANSPORT_ANY ) {
proto_tree_add_item ( header_tree , hf_packet_header_type_any , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
packet_type = ( tvb_get_guint8 ( tvb , offset ) > > 3 ) & 0xF ;
2014-12-18 14:54:38 +00:00
packet_type_str = val_to_str_const ( packet_type , packet_type_any_vals , " Unknown " ) ;
} else {
proto_tree_add_item ( header_tree , hf_packet_header_type , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
}
proto_tree_add_item ( header_tree , hf_packet_header_flow_control , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_packet_header_acknowledge_indication , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_packet_header_sequence_number , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
hec_item = proto_tree_add_item ( header_tree , hf_packet_header_header_error_check , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2021-01-27 06:23:52 +00:00
proto_tree_add_item ( header_tree , hf_packet_header_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2014-12-18 14:54:38 +00:00
}
2021-01-27 06:23:52 +00:00
switch ( header_mode ) {
case - 2 :
col_set_str ( pinfo - > cinfo , COL_INFO , ( lap = = 0x9e8b33 ) ? " GIAC " : " DIAC " ) ;
break ;
case - 1 :
expert_add_info ( pinfo , hec_item , & ei_packet_header_with_hec_not_checked ) ;
break ;
case 0 :
2014-12-18 14:54:38 +00:00
expert_add_info ( pinfo , hec_item , & ei_incorrect_packet_header_or_hec ) ;
2021-01-27 06:23:52 +00:00
break ;
case 2 :
expert_add_info ( pinfo , header_item , & ei_broken_packet_header_format ) ;
break ;
default :
break ;
2014-12-18 14:54:38 +00:00
}
2021-01-27 06:23:52 +00:00
if ( header_mode > 0 & & ltaddr )
connection_info = lookup_connection_info ( interface_id , adapter_id , lap , ltaddr , pinfo - > num ) ;
if ( connection_info & & direction > = 0 ) {
set_address ( & pinfo - > dl_src , AT_ETHER , sizeof ( connection_info - > bd_addr [ 0 ] ) , connection_info - > bd_addr [ direction ] ) ;
set_address ( & pinfo - > dl_dst , AT_ETHER , sizeof ( connection_info - > bd_addr [ 0 ] ) , connection_info - > bd_addr [ 1 - direction ] ) ;
set_address ( & pinfo - > net_src , AT_ETHER , sizeof ( connection_info - > bd_addr [ 0 ] ) , connection_info - > bd_addr [ direction ] ) ;
set_address ( & pinfo - > net_dst , AT_ETHER , sizeof ( connection_info - > bd_addr [ 0 ] ) , connection_info - > bd_addr [ 1 - direction ] ) ;
} else {
clear_address ( & pinfo - > dl_dst ) ;
clear_address ( & pinfo - > net_dst ) ;
if ( header_mode > 0 & & ! ltaddr & & device_info ) {
set_address ( & pinfo - > dl_src , AT_ETHER , sizeof ( device_info - > bd_addr ) , device_info - > bd_addr ) ;
set_address ( & pinfo - > net_src , AT_ETHER , sizeof ( device_info - > bd_addr ) , device_info - > bd_addr ) ;
} else {
clear_address ( & pinfo - > dl_src ) ;
clear_address ( & pinfo - > net_src ) ;
}
2014-12-18 14:54:38 +00:00
}
2021-01-27 06:23:52 +00:00
copy_address_shallow ( & pinfo - > src , & pinfo - > net_src ) ;
copy_address_shallow ( & pinfo - > dst , & pinfo - > net_dst ) ;
2014-12-18 14:54:38 +00:00
offset + = 4 ;
flags_item = proto_tree_add_item ( btbredr_rf_tree , hf_flags , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
flags_tree = proto_item_add_subtree ( flags_item , ett_flags ) ;
flags = tvb_get_guint16 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
reserved_item = proto_tree_add_item ( flags_tree , hf_flags_reserved_15_14 , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
if ( flags & 0xC000 ) {
expert_add_info ( pinfo , reserved_item , & ei_reserved_not_zero ) ;
}
proto_tree_add_item ( flags_tree , hf_flags_mic_pass , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_mic_checked , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_crc_pass , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_crc_checked , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_hec_pass , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_hec_checked , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_reference_upper_addres_part_valid , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_rf_channel_aliasing , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_br_edr_data_present , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_reference_lower_address_part_valid , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_bredr_payload_decrypted , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_noise_power_valid , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_signal_power_valid , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_flags_packet_header_and_br_edr_payload_dewhitened , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
offset + = 2 ;
if ( ( flags & ( FLAGS_SIGNAL_POWER_VALID | FLAGS_NOISE_POWER_VALID ) ) = = ( FLAGS_SIGNAL_POWER_VALID | FLAGS_NOISE_POWER_VALID ) ) {
col_append_fstr ( pinfo - > cinfo , COL_INFO , " (SP: %4i, NP: %4i) " ,
2018-04-10 06:06:47 +00:00
( gint ) tvb_get_gint8 ( tvb , 1 ) , ( gint ) tvb_get_gint8 ( tvb , 2 ) ) ;
2014-12-18 14:54:38 +00:00
} else if ( flags & FLAGS_SIGNAL_POWER_VALID ) {
col_append_fstr ( pinfo - > cinfo , COL_INFO , " (SP: %4i) " ,
2018-04-10 06:06:47 +00:00
( gint ) tvb_get_gint8 ( tvb , 1 ) ) ;
2014-12-18 14:54:38 +00:00
} else if ( flags & FLAGS_NOISE_POWER_VALID ) {
col_append_fstr ( pinfo - > cinfo , COL_INFO , " (NP: %4i) " ,
2018-04-10 06:06:47 +00:00
( gint ) tvb_get_gint8 ( tvb , 2 ) ) ;
2014-12-18 14:54:38 +00:00
}
if ( flags & FLAGS_PACKET_HEADER_AND_BR_EDR_PAYLOAD_DEWHITENED )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , Packet Type: %s " , packet_type_str ) ;
2021-01-27 06:23:52 +00:00
// Packet Type Table
if ( payload_and_transport = = ( TRANSPORT_SCO | PAYLOAD_BR ) ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 2 : // FHS
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 0 ;
data_crc = TRUE ;
decrypted = TRUE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 5 : // HV1
isochronous_length = 10 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 6 : // HV2
isochronous_length = 20 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 7 : // HV3
isochronous_length = 30 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 8 : // DV
isochronous_length = 10 ;
isochronous_crc = FALSE ;
data_length = 10 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_BR ) ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 7 : // EV3
isochronous_length = 30 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 12 : // EV4
isochronous_length = 120 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 13 : // EV5
isochronous_length = 180 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_eSCO | PAYLOAD_EDR_3 ) ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 6 : // 2-EV3
isochronous_length = 60 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 7 : // 3-EV3
isochronous_length = 90 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 12 : // 2-EV5
isochronous_length = 360 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 13 : // 3-EV5
isochronous_length = 540 ;
isochronous_crc = TRUE ;
isochronous_esco = TRUE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_BR ) ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 2 : // FHS
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 0 ;
data_crc = TRUE ;
decrypted = TRUE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 4 : // DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 28 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 9 : // AUX1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 30 ;
data_header = 1 ;
data_crc = FALSE ;
break ;
case 10 : // DM3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 123 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 11 : // DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 185 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 14 : // DM5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 226 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 15 : // DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 341 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 2 : // FHS
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 0 ;
data_crc = TRUE ;
decrypted = TRUE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 4 : // 2-DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 56 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 8 : // 3-DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 85 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 9 : // AUX1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 30 ;
data_header = 1 ;
data_crc = FALSE ;
break ;
case 10 : // 2-DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 369 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 11 : // 3-DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 554 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 14 : // 2-DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 681 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 15 : // 3-DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 1023 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_BR ) ) {
switch ( packet_type ) {
case 0 : // NULL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 4 : // DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 28 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 10 : // DM3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 123 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 11 : // DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 185 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 14 : // DM5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 226 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 15 : // DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 341 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
default :
break ;
}
} else if ( payload_and_transport = = ( TRANSPORT_CSB | PAYLOAD_EDR_2 ) | | payload_and_transport = = ( TRANSPORT_ACL | PAYLOAD_EDR_3 ) ) {
switch ( packet_type ) {
case 0 : // NULL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
case 4 : // 2-DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 56 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 8 : // 3-DH1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 85 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 10 : // 2-DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 369 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 11 : // 3-DH3
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 554 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 14 : // 2-DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 681 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
case 15 : // 3-DH5
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 1023 ;
data_header = 2 ;
data_crc = TRUE ;
break ;
default :
break ;
}
} else if ( ( payload_and_transport > > 4 ) = = TRANSPORT_ANY ) {
switch ( packet_type ) {
case 0 : // NULL
case 1 : // POLL
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 0 ;
data_header = 0 ;
data_crc = FALSE ;
break ;
case 2 : // FHS
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 0 ;
data_crc = TRUE ;
decrypted = TRUE ;
break ;
case 3 : // DM1
isochronous_length = 0 ;
isochronous_crc = FALSE ;
data_length = 18 ;
data_header = 1 ;
data_crc = TRUE ;
break ;
default :
break ;
}
}
if ( flags & FLAGS_BR_EDR_DATA_PRESENT ) {
2014-12-18 14:54:38 +00:00
if ( flags & FLAGS_PACKET_HEADER_AND_BR_EDR_PAYLOAD_DEWHITENED ) {
2021-01-27 06:23:52 +00:00
if ( decrypted ) {
tvbuff_t * next_tvb ;
next_tvb = tvb_new_subset_remaining ( tvb , offset ) ;
if ( packet_type_table & & packet_type > PACKET_TYPE_UNKNOWN & &
dissector_try_uint_new ( packet_type_table , packet_type , next_tvb , pinfo , tree , TRUE , bluetooth_data ) ) {
offset = tvb_reported_length ( tvb ) ;
} else {
if ( isochronous_length > 0 & &
( ! isochronous_crc | | ( flags & ( FLAGS_CRC_PASS | FLAGS_CRC_CHECKED ) ) = = ( FLAGS_CRC_PASS | FLAGS_CRC_CHECKED ) ) ) {
gint len = tvb_captured_length_remaining ( tvb , offset ) ;
if ( isochronous_crc )
len - = 2 ;
if ( isochronous_length > len )
isochronous_length = len ;
if ( isochronous_length > 0 ) {
//next_tvb = tvb_new_subset_length(tvb, offset, isochronous_length);
proto_item * iso_item = proto_tree_add_item ( btbredr_rf_tree , hf_isochronous_data , tvb , offset , isochronous_length , ENC_NA ) ;
if ( isochronous_crc ) {
proto_item * crc_item = NULL ;
crc_item = proto_tree_add_item ( btbredr_rf_tree , hf_crc , tvb , offset + isochronous_length , 2 , ENC_LITTLE_ENDIAN ) ;
if ( ( flags & FLAGS_REFERENCE_UPPER_ADDRES_PART_VALID ) & & ! check_crc ( uap , tvb , offset , isochronous_length + 2 ) )
expert_add_info ( pinfo , crc_item , & ei_incorrect_crc ) ;
offset + = 2 ;
}
offset + = isochronous_length ;
if ( connection_info ) {
if ( connection_info - > esco ! = isochronous_esco )
expert_add_info ( pinfo , iso_item , & ei_esco_incorrect_ltaddr ) ;
if ( direction > = 0 & & connection_info - > esco & &
connection_info - > escosize [ direction ] ! = isochronous_length )
expert_add_info ( pinfo , iso_item , & ei_esco_incorrect_length ) ;
}
}
}
if ( data_length > 0 & &
( ! data_crc | | ( flags & ( FLAGS_CRC_PASS | FLAGS_CRC_CHECKED ) ) = = ( FLAGS_CRC_PASS | FLAGS_CRC_CHECKED ) ) ) {
gint len = tvb_captured_length_remaining ( tvb , offset ) ;
gboolean error = FALSE ;
gint llid = - 1 ;
if ( data_crc )
len - = 2 ;
if ( data_length > len )
data_length = len ;
if ( data_header > 0 ) {
if ( len < data_header ) {
error = TRUE ;
} else if ( data_header = = 1 ) {
guint8 hdr = tvb_get_guint8 ( tvb , offset ) ;
llid = hdr & 3 ;
hdr > > = 3 ;
hdr & = 0x1f ;
+ + hdr ;
if ( hdr > len )
error = TRUE ;
else
data_length = hdr ;
} else if ( data_header = = 2 ) {
guint16 hdr = tvb_get_guint16 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
llid = hdr & 3 ;
hdr > > = 3 ;
hdr & = 0x3ff ;
hdr + = 2 ;
if ( hdr > len )
error = TRUE ;
else
data_length = hdr ;
} else {
error = TRUE ;
}
}
if ( data_length > 0 & & ! error ) {
gboolean handled = FALSE ;
fragment_head * frag_l2cap_msg = NULL ;
if ( data_header = = 1 ) {
proto_item * pheader_item = proto_tree_add_item ( btbredr_rf_tree , hf_payload_header1 , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree * pheader_tree = proto_item_add_subtree ( pheader_item , ett_payload_header ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header1_llid , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header1_flow , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header1_length , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
} else if ( data_header = = 2 ) {
proto_item * pheader_item = proto_tree_add_item ( btbredr_rf_tree , hf_payload_header2 , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree * pheader_tree = proto_item_add_subtree ( pheader_item , ett_payload_header ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header2_llid , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header2_flow , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header2_length , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( pheader_tree , hf_payload_header2_rfu , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
}
if ( ! pinfo - > fd - > visited ) {
frame_info = wmem_new0 ( wmem_file_scope ( ) , btbredr_frame_info_t ) ;
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_btbredr_rf , pinfo - > curr_layer_num , frame_info ) ;
if ( connection_info & & direction > = 0 ) {
frame_info - > retransmit = ( seqn = = connection_info - > reassembly [ direction ] . seqn ) ;
frame_info - > ack = arqn ;
frame_info - > l2cap_index = pinfo - > num ;
connection_info - > reassembly [ direction ] . seqn = seqn ;
}
} else {
frame_info = ( btbredr_frame_info_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_btbredr_rf , pinfo - > curr_layer_num ) ;
}
if ( packet_type = = 2 ) {
// FHS
next_tvb = tvb_new_subset_length ( tvb , offset + data_header , data_length - data_header ) ;
if ( next_tvb ) {
btbredr_fhs_data_t * fhs_data = wmem_new0 ( wmem_packet_scope ( ) , btbredr_fhs_data_t ) ;
fhs_data - > bluetooth_data = bluetooth_data ;
fhs_data - > device_info = device_info ;
fhs_data - > connection_info = connection_info ;
call_dissector_with_data ( btbredr_fhs_handle , next_tvb , pinfo , tree , fhs_data ) ;
handled = TRUE ;
}
}
switch ( llid ) {
case 0x03 : // LMP
if ( ! btlmp_handle )
break ;
next_tvb = tvb_new_subset_length ( tvb , offset + data_header , data_length - data_header ) ;
if ( ! next_tvb )
break ;
call_dissector_with_data ( btlmp_handle , next_tvb , pinfo , tree , connection_info ) ;
handled = TRUE ;
break ;
case 0x02 : // Start of or complete L2CAP message
if ( ! btl2cap_handle )
break ;
if ( frame_info & & data_length > data_header ) {
guint pdu_len = data_length - data_header ;
guint l2cap_len = tvb_get_letohs ( tvb , offset + data_header ) ;
if ( l2cap_len + 4 < = pdu_len ) {
bthci_acl_data_t * acl_data = wmem_new ( wmem_packet_scope ( ) , bthci_acl_data_t ) ;
acl_data - > interface_id = interface_id ;
acl_data - > adapter_id = adapter_id ;
acl_data - > chandle = 0 ; /* No connection handle at this layer */
acl_data - > remote_bd_addr_oui = 0 ;
acl_data - > remote_bd_addr_id = 0 ;
acl_data - > is_btle = TRUE ;
acl_data - > is_btle_retransmit = FALSE ;
acl_data - > adapter_disconnect_in_frame = & max_disconnect_in_frame ;
acl_data - > disconnect_in_frame = & max_disconnect_in_frame ;
next_tvb = tvb_new_subset_length ( tvb , offset + data_header , pdu_len ) ;
call_dissector_with_data ( btl2cap_handle , next_tvb , pinfo , tree , acl_data ) ;
handled = TRUE ;
col_set_str ( pinfo - > cinfo , COL_INFO , " L2CAP Data " ) ;
if ( ! pinfo - > fd - > visited & & connection_info & & direction > = 0 ) {
connection_info - > reassembly [ direction ] . l2cap_index = pinfo - > num ;
connection_info - > reassembly [ direction ] . segment_len_rem = 0 ;
}
break ;
}
pinfo - > fragmented = TRUE ;
if ( ! frame_info - > retransmit & & connection_info & & direction > = 0 ) {
if ( ! pinfo - > fd - > visited ) {
connection_info - > reassembly [ direction ] . l2cap_index = pinfo - > num ;
connection_info - > reassembly [ direction ] . segment_len_rem = l2cap_len + 4 - pdu_len ;
frame_info - > more_fragments = 1 ;
}
frag_l2cap_msg = fragment_add_seq_next ( & l2cap_msg_reassembly_table ,
tvb , offset + data_header ,
pinfo ,
frame_info - > l2cap_index , /* guint32 ID for fragments belonging together */
NULL , /* data* */
pdu_len , /* Fragment length */
frame_info - > more_fragments ) ; /* More fragments */
process_reassembled_data ( tvb , offset + data_header , pinfo ,
" Reassembled L2CAP " ,
frag_l2cap_msg ,
& l2cap_msg_frag_items ,
NULL ,
btbredr_rf_tree ) ;
}
proto_tree_add_item ( btbredr_rf_tree , hf_l2cap_fragment , tvb , offset + data_header , pdu_len , ENC_NA ) ;
handled = TRUE ;
col_set_str ( pinfo - > cinfo , COL_INFO , " L2CAP Fragment Start " ) ;
}
break ;
case 0x01 : /* Continuation fragment of an L2CAP message, or an Empty PDU */
if ( ! btl2cap_handle )
break ;
if ( ! frame_info | | data_length < = data_header ) {
col_set_str ( pinfo - > cinfo , COL_INFO , " Empty PDU " ) ;
break ;
}
pinfo - > fragmented = TRUE ;
if ( ! frame_info - > retransmit & & connection_info & & direction > = 0 ) {
guint pdu_len = data_length - data_header ;
if ( ! pinfo - > fd - > visited ) {
if ( connection_info - > reassembly [ direction ] . segment_len_rem > 0 ) {
if ( connection_info - > reassembly [ direction ] . segment_len_rem > = pdu_len ) {
connection_info - > reassembly [ direction ] . segment_len_rem - = pdu_len ;
frame_info - > l2cap_index = connection_info - > reassembly [ direction ] . l2cap_index ;
} else {
/*
* Missing fragment for previous L2CAP and fragment start for this .
* Set more_fragments and increase l2cap_index to avoid reassembly .
*/
frame_info - > more_fragments = 1 ;
frame_info - > missing_start = 1 ;
connection_info - > reassembly [ direction ] . l2cap_index = pinfo - > num ;
connection_info - > reassembly [ direction ] . segment_len_rem = 0 ;
}
frame_info - > more_fragments = ( connection_info - > reassembly [ direction ] . segment_len_rem > 0 ) ;
} else {
/*
* Missing fragment start .
* Set more_fragments and increase l2cap_index to avoid reassembly .
*/
frame_info - > more_fragments = 1 ;
frame_info - > missing_start = 1 ;
connection_info - > reassembly [ direction ] . l2cap_index = pinfo - > num ;
connection_info - > reassembly [ direction ] . segment_len_rem = 0 ;
}
}
frag_l2cap_msg = fragment_add_seq_next ( & l2cap_msg_reassembly_table ,
tvb , offset + data_header ,
pinfo ,
frame_info - > l2cap_index , /* guint32 ID for fragments belonging together */
NULL , /* data* */
pdu_len , /* Fragment length */
frame_info - > more_fragments ) ; /* More fragments */
next_tvb = process_reassembled_data ( tvb , offset , pinfo ,
" Reassembled L2CAP " ,
frag_l2cap_msg ,
& l2cap_msg_frag_items ,
NULL ,
btbredr_rf_tree ) ;
}
if ( next_tvb ) {
bthci_acl_data_t * acl_data = wmem_new ( wmem_packet_scope ( ) , bthci_acl_data_t ) ;
acl_data - > interface_id = interface_id ;
acl_data - > adapter_id = adapter_id ;
acl_data - > chandle = 0 ; /* No connection handle at this layer */
acl_data - > remote_bd_addr_oui = 0 ;
acl_data - > remote_bd_addr_id = 0 ;
acl_data - > is_btle = TRUE ;
acl_data - > is_btle_retransmit = FALSE ;
acl_data - > adapter_disconnect_in_frame = & max_disconnect_in_frame ;
acl_data - > disconnect_in_frame = & max_disconnect_in_frame ;
call_dissector_with_data ( btl2cap_handle , next_tvb , pinfo , tree , acl_data ) ;
handled = TRUE ;
col_set_str ( pinfo - > cinfo , COL_INFO , " L2CAP Data " ) ;
} else {
proto_item * item = proto_tree_add_item ( btbredr_rf_tree , hf_l2cap_fragment , tvb , offset + data_header , data_length - data_header , ENC_NA ) ;
if ( frame_info - > missing_start )
expert_add_info ( pinfo , item , & ei_missing_fragment_start ) ;
handled = TRUE ;
col_set_str ( pinfo - > cinfo , COL_INFO , " L2CAP Fragment " ) ;
}
break ;
default :
break ;
}
if ( ! handled )
proto_tree_add_item ( btbredr_rf_tree , hf_asynchronous_data , tvb , offset + data_header , data_length - data_header , ENC_NA ) ;
if ( data_crc ) {
proto_item * crc_item = NULL ;
crc_item = proto_tree_add_item ( btbredr_rf_tree , hf_crc , tvb , offset + data_length , 2 , ENC_LITTLE_ENDIAN ) ;
if ( ( flags & FLAGS_REFERENCE_UPPER_ADDRES_PART_VALID ) & & ! check_crc ( uap , tvb , offset , data_length + 2 ) )
expert_add_info ( pinfo , crc_item , & ei_incorrect_crc ) ;
offset + = 2 ;
}
offset + = data_length ;
}
}
if ( tvb_captured_length_remaining ( tvb , offset ) > 0 )
proto_tree_add_item ( btbredr_rf_tree , hf_data , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) , ENC_NA ) ;
}
} else {
proto_tree_add_item ( btbredr_rf_tree , hf_encrypted_data , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) , ENC_NA ) ;
offset = tvb_reported_length ( tvb ) ;
}
2014-12-18 14:54:38 +00:00
} else {
2021-01-27 06:23:52 +00:00
proto_tree_add_item ( btbredr_rf_tree , hf_whitened_data , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) , ENC_NA ) ;
offset = tvb_reported_length ( tvb ) ;
2014-12-18 14:54:38 +00:00
}
2021-01-27 06:23:52 +00:00
} else {
if ( tvb_captured_length_remaining ( tvb , offset ) > 0 )
proto_tree_add_expert ( btbredr_rf_tree , pinfo , & ei_unexpected_data , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) ) ;
offset = tvb_reported_length ( tvb ) ;
}
if ( ! pinfo - > fd - > visited ) {
address * addr ;
addr = ( address * ) wmem_memdup ( wmem_file_scope ( ) , & pinfo - > dl_src , sizeof ( address ) ) ;
addr - > data = wmem_memdup ( wmem_file_scope ( ) , pinfo - > dl_src . data , pinfo - > dl_src . len ) ;
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_bluetooth , BLUETOOTH_DATA_SRC , addr ) ;
2014-12-18 14:54:38 +00:00
2021-01-27 06:23:52 +00:00
addr = ( address * ) wmem_memdup ( wmem_file_scope ( ) , & pinfo - > dl_dst , sizeof ( address ) ) ;
addr - > data = wmem_memdup ( wmem_file_scope ( ) , pinfo - > dl_dst . data , pinfo - > dl_dst . len ) ;
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_bluetooth , BLUETOOTH_DATA_DST , addr ) ;
}
return offset ;
}
static gint
dissect_btbredr_fhs ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
{
proto_item * btbredr_fhs_item ;
proto_tree * btbredr_fhs_tree ;
gint offset = 0 ;
guint32 interface_id ;
guint32 adapter_id ;
guint64 parity_lap_eir_sp_sr ;
guint32 lap ;
guint8 uap ;
guint16 nap ;
guint32 ltaddr_clk_pgscan ;
guint32 ltaddr ;
device_info_t * device_info = NULL ;
connection_info_t * connection_info = NULL ;
btbredr_fhs_data_t * fhs_data = ( btbredr_fhs_data_t * ) data ;
btbredr_fhs_item = proto_tree_add_item ( tree , proto_btbredr_fhs , tvb , offset , - 1 , ENC_NA ) ;
btbredr_fhs_tree = proto_item_add_subtree ( btbredr_fhs_item , ett_btbredr_fhs ) ;
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " BT BR/EDR FHS " ) ;
if ( fhs_data - > bluetooth_data )
interface_id = fhs_data - > bluetooth_data - > interface_id ;
else if ( pinfo - > rec - > presence_flags & WTAP_HAS_INTERFACE_ID )
interface_id = pinfo - > rec - > rec_header . packet_header . interface_id ;
else
interface_id = HCI_INTERFACE_DEFAULT ;
if ( fhs_data - > bluetooth_data )
adapter_id = fhs_data - > bluetooth_data - > adapter_id ;
else
adapter_id = HCI_ADAPTER_DEFAULT ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_parity , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_lap , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_eir , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_reserved , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_sr , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_sp , tvb , offset , 8 , ENC_LITTLE_ENDIAN ) ;
parity_lap_eir_sp_sr = tvb_get_guint64 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
lap = ( parity_lap_eir_sp_sr > > 34 ) & 0xffffff ;
offset + = 8 ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_uap , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
uap = tvb_get_guint8 ( tvb , offset ) ;
offset + = 1 ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_nap , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
nap = tvb_get_guint16 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
offset + = 2 ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_class , tvb , offset , 3 , ENC_LITTLE_ENDIAN ) ;
offset + = 3 ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_ltaddr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_clk , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( btbredr_fhs_tree , hf_fhs_pagescanmode , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
ltaddr_clk_pgscan = tvb_get_guint32 ( tvb , offset , ENC_LITTLE_ENDIAN ) ;
offset + = 4 ;
ltaddr = ltaddr_clk_pgscan & 0x00000007 ;
{
wmem_tree_key_t key [ 4 ] ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 0 ;
key [ 3 ] . key = NULL ;
device_info = ( device_info_t * ) wmem_tree_lookup32_array ( device_info_tree , key ) ;
if ( ! device_info & & ! pinfo - > fd - > visited ) {
device_info = wmem_new0 ( wmem_file_scope ( ) , device_info_t ) ;
device_info - > interface_id = interface_id ;
device_info - > adapter_id = adapter_id ;
device_info - > bd_addr [ 0 ] = nap > > 8 ;
device_info - > bd_addr [ 1 ] = nap > > 0 ;
device_info - > bd_addr [ 2 ] = uap ;
device_info - > bd_addr [ 3 ] = lap > > 16 ;
device_info - > bd_addr [ 4 ] = lap > > 8 ;
device_info - > bd_addr [ 5 ] = lap ;
device_info - > dir = pinfo - > p2p_dir ;
wmem_tree_insert32_array ( device_info_tree , key , device_info ) ;
}
}
if ( ltaddr ) {
connection_info = lookup_connection_info ( interface_id , adapter_id , lap , ltaddr , pinfo - > num ) ;
if ( ! pinfo - > fd - > visited ) {
if ( connection_info & & fhs_data - > device_info & &
! memcmp ( connection_info - > bd_addr [ BDADDR_SLAVE ] , null_bd_addr , 6 ) )
memcpy ( connection_info - > bd_addr [ BDADDR_SLAVE ] , fhs_data - > device_info - > bd_addr , 6 ) ;
if ( ! connection_info & & device_info ) {
wmem_tree_key_t key [ 6 ] ;
key [ 0 ] . length = 1 ;
key [ 0 ] . key = & interface_id ;
key [ 1 ] . length = 1 ;
key [ 1 ] . key = & adapter_id ;
key [ 2 ] . length = 1 ;
key [ 2 ] . key = & lap ;
key [ 3 ] . length = 1 ;
key [ 3 ] . key = & ltaddr ;
key [ 4 ] . length = 1 ;
key [ 4 ] . key = & pinfo - > num ;
key [ 5 ] . length = 0 ;
key [ 5 ] . key = NULL ;
connection_info = wmem_new0 ( wmem_file_scope ( ) , connection_info_t ) ;
connection_info - > interface_id = interface_id ;
connection_info - > adapter_id = adapter_id ;
connection_info - > lt_addr = ltaddr ;
connection_info - > timestamp = pinfo - > abs_ts ;
connection_info - > btclock = ( ltaddr_clk_pgscan > > 3 ) & 0x3ffffff ;
memcpy ( connection_info - > bd_addr [ BDADDR_MASTER ] , device_info - > bd_addr , 6 ) ;
if ( fhs_data - > device_info )
memcpy ( connection_info - > bd_addr [ BDADDR_SLAVE ] , fhs_data - > device_info - > bd_addr , 6 ) ;
wmem_tree_insert32_array ( connection_info_tree , key , connection_info ) ;
}
}
}
if ( device_info ) {
set_address ( & pinfo - > dl_src , AT_ETHER , sizeof ( device_info - > bd_addr ) , device_info - > bd_addr ) ;
set_address ( & pinfo - > net_src , AT_ETHER , sizeof ( device_info - > bd_addr ) , device_info - > bd_addr ) ;
copy_address_shallow ( & pinfo - > src , & pinfo - > net_src ) ;
}
if ( fhs_data - > device_info ) {
set_address ( & pinfo - > dl_dst , AT_ETHER , sizeof ( fhs_data - > device_info - > bd_addr ) , fhs_data - > device_info - > bd_addr ) ;
set_address ( & pinfo - > net_dst , AT_ETHER , sizeof ( fhs_data - > device_info - > bd_addr ) , fhs_data - > device_info - > bd_addr ) ;
copy_address_shallow ( & pinfo - > dst , & pinfo - > net_dst ) ;
}
2014-12-18 14:54:38 +00:00
return offset ;
}
void
proto_register_btbredr_rf ( void )
{
expert_module_t * expert_module ;
static hf_register_info hf [ ] = {
{ & hf_rf_channel ,
{ " RF Channel " , " btbredr_rf.rf_channel " ,
FT_UINT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_uncertain_rf_channel ,
{ " Uncertain RF Channel " , " btbredr_rf.uncertain_rf_channel " ,
FT_UINT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_signal_power ,
{ " Signal Power " , " btbredr_rf.signal_power " ,
FT_INT8 , BASE_DEC , NULL , 0x00 ,
" Signal Power in dBm " , HFILL }
} ,
{ & hf_invalid_signal_power ,
{ " Invalid Signal Power " , " btbredr_rf.invalid.signal_power " ,
FT_INT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_noise_power ,
{ " Noise Power " , " btbredr_rf.noise_power " ,
FT_INT8 , BASE_DEC , NULL , 0x00 ,
" Noise Power in dBm " , HFILL }
} ,
{ & hf_invalid_noise_power ,
{ " Invalid Noise Power " , " btbredr_rf.invalid.noise_power " ,
FT_INT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_access_address_offenses ,
{ " Access Address Offenses " , " btbredr_rf.access_address_offenses " ,
FT_UINT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_payload_transport_rate ,
{ " Payload Transport Rate " , " btbredr_rf.payload_transport_rate " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_payload_transport_rate_ignored ,
{ " Payload Transport Rate: Ignored " , " btbredr_rf.payload_transport_rate.ignored " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
" BT Packet Header is ignored and there is no payload " , HFILL }
} ,
{ & hf_payload_transport_rate_transport ,
{ " Transport " , " btbredr_rf.payload_transport_rate.transport " ,
FT_UINT8 , BASE_HEX , VALS ( payload_transport_rate_transport_vals ) , 0xF0 ,
NULL , HFILL }
} ,
{ & hf_payload_transport_rate_payload ,
{ " Payload " , " btbredr_rf.payload_transport_rate.payload " ,
FT_UINT8 , BASE_HEX , VALS ( payload_transport_rate_payload_vals ) , 0x0F ,
NULL , HFILL }
} ,
{ & hf_corrected_header_bits ,
{ " Corrected Header Bits " , " btbredr_rf.corrected_header_bits " ,
FT_UINT8 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_corrected_payload_bits ,
{ " Corrected Payload Bits " , " btbredr_rf.corrected_payload_bits " ,
FT_INT16 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_lower_address_part ,
{ " Lower Address Part " , " btbredr_rf.lower_address_part " ,
FT_UINT32 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_reference_lower_address_part ,
{ " Reference Lower Address Part " , " btbredr_rf.reference_lower_address_part " ,
FT_UINT24 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_invalid_reference_lower_address_part ,
{ " Invalid Reference Lower Address Part " , " btbredr_rf.invalid.reference_lower_address_part " ,
FT_UINT24 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_reference_upper_addres_part ,
{ " Reference Upper Address Part " , " btbredr_rf.reference_upper_addres_part " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_invalid_reference_upper_addres_part ,
{ " Invalid Reference Upper Address Part " , " btbredr_rf.invalid.reference_upper_addres_part " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_whitened_packet_header ,
{ " Whitened Packet Header " , " btbredr_rf.whitened.packet_header " ,
FT_UINT32 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_invalid_packet_header ,
{ " Invalid Packet Header " , " btbredr_rf.invalid.packet_header " ,
FT_UINT32 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
2014-12-18 14:54:38 +00:00
{ & hf_packet_header ,
{ " Packet Header " , " btbredr_rf.packet_header " ,
FT_UINT32 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_lt_addr ,
{ " LT_ADDR " , " btbredr_rf.packet_header.lt_addr " ,
FT_UINT32 , BASE_HEX , NULL , 0x00000007 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , NULL , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_any ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_any_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_sco_br ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_sco_br_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_esco_br ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_esco_br_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_esco_edr ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_esco_edr_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_acl_br ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_acl_br_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_acl_edr ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_acl_edr_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_csb_br ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_csb_br_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_type_csb_edr ,
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_csb_edr_vals ) , 0x00000078 ,
NULL , HFILL }
} ,
{ & hf_packet_header_flow_control ,
{ " Flow Control " , " btbredr_rf.packet_header.flow_control " ,
FT_BOOLEAN , 32 , NULL , 0x00000080 ,
NULL , HFILL }
} ,
{ & hf_packet_header_acknowledge_indication ,
{ " ARQN " , " btbredr_rf.packet_header.arqn " ,
FT_BOOLEAN , 32 , NULL , 0x00000100 ,
" Acknowledge Indication " , HFILL }
} ,
{ & hf_packet_header_sequence_number ,
{ " SEQN " , " btbredr_rf.packet_header.seqn " ,
FT_BOOLEAN , 32 , NULL , 0x00000200 ,
" Sequence Number " , HFILL }
} ,
{ & hf_packet_header_header_error_check ,
{ " HEC " , " btbredr_rf.packet_header.hec " ,
FT_UINT32 , BASE_HEX , NULL , 0x0003FC00 ,
" Header Error Check " , HFILL }
} ,
2014-12-18 14:54:38 +00:00
{ & hf_packet_header_reserved ,
{ " Reserved " , " btbredr_rf.packet_header.reserved " ,
FT_UINT32 , BASE_HEX , NULL , 0xFFFC0000 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_lt_addr ,
2014-12-18 14:54:38 +00:00
{ " LT_ADDR " , " btbredr_rf.packet_header.lt_addr " ,
FT_UINT32 , BASE_HEX , NULL , 0x00038000 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , NULL , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_any ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_any_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_sco_br ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_sco_br_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_esco_br ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_esco_br_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_esco_edr ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_esco_edr_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_acl_br ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_acl_br_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_acl_edr ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_acl_edr_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_csb_br ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_csb_br_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_type_csb_edr ,
2014-12-18 14:54:38 +00:00
{ " Type " , " btbredr_rf.packet_header.type " ,
FT_UINT32 , BASE_HEX , VALS ( packet_type_csb_edr_vals ) , 0x00007800 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_flow_control ,
2014-12-18 14:54:38 +00:00
{ " Flow Control " , " btbredr_rf.packet_header.flow_control " ,
FT_BOOLEAN , 32 , NULL , 0x00000400 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_acknowledge_indication ,
2014-12-18 14:54:38 +00:00
{ " ARQN " , " btbredr_rf.packet_header.arqn " ,
FT_BOOLEAN , 32 , NULL , 0x00000200 ,
" Acknowledge Indication " , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_sequence_number ,
2014-12-18 14:54:38 +00:00
{ " SEQN " , " btbredr_rf.packet_header.seqn " ,
FT_BOOLEAN , 32 , NULL , 0x00000100 ,
" Sequence Number " , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_packet_header_broken_header_error_check ,
2014-12-18 14:54:38 +00:00
{ " HEC " , " btbredr_rf.packet_header.hec " ,
FT_UINT32 , BASE_HEX , NULL , 0x000000FF ,
" Header Error Check " , HFILL }
} ,
{ & hf_whitened_data ,
{ " Whitened Data " , " btbredr_rf.whitened.data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_encrypted_data ,
{ " Encrypted Data " , " btbredr_rf.encrypted.data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_data ,
{ " Data " , " btbredr_rf.data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
2021-01-27 06:23:52 +00:00
{ & hf_isochronous_data ,
{ " Isochronous Data " , " btbredr_rf.isochronous_data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_asynchronous_data ,
{ " Asynchronous Data " , " btbredr_rf.asynchronous_data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_fragment ,
{ " L2CAP Fragment " , " btbredr_rf.l2cap_data " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_crc ,
{ " CRC " , " btbredr_rf.crc " ,
FT_UINT16 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_flags ,
{ " Flags " , " btbredr_rf.flags " ,
FT_UINT16 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
2014-12-18 14:54:38 +00:00
{ & hf_flags_reserved_15_14 ,
{ " Reserved " , " btbredr_rf.flags.reserved.15_14 " ,
FT_UINT16 , BASE_HEX , NULL , 0xC000 ,
NULL , HFILL }
} ,
{ & hf_flags_mic_pass ,
{ " MIC Pass " , " btbredr_rf.flags.mic_pass " ,
FT_BOOLEAN , 16 , NULL , 0x2000 ,
NULL , HFILL }
} ,
{ & hf_flags_mic_checked ,
{ " MIC Checked " , " btbredr_rf.flags.mic_check " ,
FT_BOOLEAN , 16 , NULL , 0x1000 ,
NULL , HFILL }
} ,
{ & hf_flags_crc_pass ,
{ " CRC Pass " , " btbredr_rf.flags.crc_pass " ,
FT_BOOLEAN , 16 , NULL , 0x0800 ,
NULL , HFILL }
} ,
{ & hf_flags_crc_checked ,
{ " CRC Checked " , " btbredr_rf.flags.crc_check " ,
FT_BOOLEAN , 16 , NULL , 0x0400 ,
NULL , HFILL }
} ,
{ & hf_flags_hec_pass ,
{ " HEC Pass " , " btbredr_rf.flags.hec_pass " ,
FT_BOOLEAN , 16 , NULL , 0x0200 ,
NULL , HFILL }
} ,
{ & hf_flags_hec_checked ,
{ " HEC Checked " , " btbredr_rf.flags.hec_check " ,
FT_BOOLEAN , 16 , NULL , 0x0100 ,
NULL , HFILL }
} ,
{ & hf_flags_reference_upper_addres_part_valid ,
{ " Reference Upper Address Part Valid " , " btbredr_rf.flags.reference_upper_addres_part_valid " ,
FT_BOOLEAN , 16 , NULL , 0x0080 ,
NULL , HFILL }
} ,
{ & hf_flags_rf_channel_aliasing ,
{ " RF Channel Aliasing " , " btbredr_rf.flags.rf_channel_aliasing " ,
FT_BOOLEAN , 16 , NULL , 0x0040 ,
NULL , HFILL }
} ,
{ & hf_flags_br_edr_data_present ,
{ " BR or EDR Data Present " , " btbredr_rf.flags.bredr_data_present " ,
FT_BOOLEAN , 16 , NULL , 0x0020 ,
NULL , HFILL }
} ,
{ & hf_flags_reference_lower_address_part_valid ,
{ " Reference Lower Address Part Valid " , " btbredr_rf.flags.reference_lower_address_part_valid " ,
FT_BOOLEAN , 16 , NULL , 0x0010 ,
NULL , HFILL }
} ,
{ & hf_flags_bredr_payload_decrypted ,
{ " BR or EDR Payload Decrypted " , " btbredr_rf.flags.bredr_payload_decrypted " ,
FT_BOOLEAN , 16 , NULL , 0x0008 ,
NULL , HFILL }
} ,
{ & hf_flags_noise_power_valid ,
{ " Noise Power Valid " , " btbredr_rf.flags.noise_power_valid " ,
FT_BOOLEAN , 16 , NULL , 0x0004 ,
NULL , HFILL }
} ,
{ & hf_flags_signal_power_valid ,
{ " Signal Power Valid " , " btbredr_rf.flags.signal_power_valid " ,
FT_BOOLEAN , 16 , NULL , 0x0002 ,
NULL , HFILL }
} ,
{ & hf_flags_packet_header_and_br_edr_payload_dewhitened ,
{ " Packet Header and BR/EDR Payload Dewhitened " , " btbredr_rf.flags.pkt_hdr_and_br_edr_payload_dewhitened " ,
FT_BOOLEAN , 16 , NULL , 0x0001 ,
NULL , HFILL }
2021-01-27 06:23:52 +00:00
} ,
{ & hf_payload_header2 ,
{ " Payload Header " , " btbredr_rf.payload_header " ,
FT_UINT16 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_payload_header2_llid ,
{ " LLID " , " btbredr_rf.payload_header.llid " ,
FT_UINT16 , BASE_HEX , NULL , 0x0003 ,
NULL , HFILL }
} ,
{ & hf_payload_header2_flow ,
{ " Flow " , " btbredr_rf.payload_header.flow " ,
FT_UINT16 , BASE_HEX , NULL , 0x0004 ,
NULL , HFILL }
} ,
{ & hf_payload_header2_length ,
{ " Length " , " btbredr_rf.payload_header.length " ,
FT_UINT16 , BASE_HEX , NULL , 0x1ff8 ,
NULL , HFILL }
} ,
{ & hf_payload_header2_rfu ,
{ " RFU " , " btbredr_rf.payload_header.rfu " ,
FT_UINT16 , BASE_HEX , NULL , 0xe000 ,
NULL , HFILL }
} ,
{ & hf_payload_header1 ,
{ " Payload Header " , " btbredr_rf.payload_header " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_payload_header1_llid ,
{ " LLID " , " btbredr_rf.payload_header.llid " ,
FT_UINT8 , BASE_HEX , NULL , 0x03 ,
NULL , HFILL }
} ,
{ & hf_payload_header1_flow ,
{ " Flow " , " btbredr_rf.payload_header.flow " ,
FT_UINT8 , BASE_HEX , NULL , 0x04 ,
NULL , HFILL }
} ,
{ & hf_payload_header1_length ,
{ " Length " , " btbredr_rf.payload_header.length " ,
FT_UINT8 , BASE_HEX , NULL , 0xf8 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragments ,
{ " L2CAP fragments " , " btbredr_rf.l2cap.fragments " ,
FT_NONE , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment ,
{ " L2CAP fragment " , " btbredr_rf.l2cap.fragment " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_overlap ,
{ " L2CAP fragment overlap " , " btbredr_rf.l2cap.fragment.overlap " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_overlap_conflicts ,
{ " L2CAP fragment overlapping with conflicting data " , " btbredr_rf.l2cap.fragment.overlap.conflicts " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_multiple_tails ,
{ " L2CAP has multiple tail fragments " , " btbredr_rf.l2cap.fragment.multiple_tails " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_too_long_fragment ,
{ " L2CAP fragment too long " , " btbredr_rf.l2cap.fragment.too_long_fragment " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_error ,
{ " L2CAP defragmentation error " , " btbredr_rf.l2cap.fragment.error " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_fragment_count ,
{ " L2CAP fragment count " , " btbredr_rf.l2cap.fragment.count " ,
FT_UINT32 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_reassembled_in ,
{ " Reassembled in " , " btbredr_rf.l2cap.reassembled.in " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_l2cap_msg_reassembled_length ,
{ " Reassembled L2CAP length " , " btbredr_rf.l2cap.reassembled.length " ,
FT_UINT32 , BASE_DEC , NULL , 0x00 ,
NULL , HFILL }
}
} ;
static hf_register_info hf_fhs [ ] = {
{ & hf_fhs_parity ,
{ " Parity Bits " , " btbredr_fhs.parity " ,
FT_UINT64 , BASE_HEX , NULL , 0x00000003ffffffff ,
NULL , HFILL }
} ,
{ & hf_fhs_lap ,
{ " Lower Address Part " , " btbredr_fhs.lap " ,
FT_UINT64 , BASE_HEX , NULL , 0x03fffffc00000000 ,
NULL , HFILL }
} ,
{ & hf_fhs_eir ,
{ " Extended Inquiry Response " , " btbredr_fhs.eir " ,
FT_UINT64 , BASE_DEC , NULL , 0x0400000000000000 ,
NULL , HFILL }
} ,
{ & hf_fhs_reserved ,
{ " Reserved " , " btbredr_fhs.reserved " ,
FT_UINT64 , BASE_DEC , NULL , 0x0800000000000000 ,
NULL , HFILL }
} ,
{ & hf_fhs_sr ,
{ " Scan Repetition " , " btbredr_fhs.sr " ,
FT_UINT64 , BASE_DEC | BASE_VAL64_STRING , VALS64 ( fhs_scan_repetition_vals ) , 0x3000000000000000 ,
NULL , HFILL }
} ,
{ & hf_fhs_sp ,
{ " SP " , " btbredr_fhs.sp " ,
FT_UINT64 , BASE_DEC , NULL , 0xc000000000000000 ,
" shall be set to 10 " , HFILL }
} ,
{ & hf_fhs_uap ,
{ " Upper Address Part " , " btbredr_fhs.uap " ,
FT_UINT8 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_fhs_nap ,
{ " Non-Significant Address Part " , " btbredr_fhs.nap " ,
FT_UINT16 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_fhs_class ,
{ " Class of Device " , " btbredr_fhs.class " ,
FT_UINT24 , BASE_HEX , NULL , 0x00 ,
NULL , HFILL }
} ,
{ & hf_fhs_ltaddr ,
{ " LT_ADDR " , " btbredr_fhs.ltaddr " ,
FT_UINT32 , BASE_DEC , NULL , 0x00000007 ,
NULL , HFILL }
} ,
{ & hf_fhs_clk ,
{ " CLK " , " btbredr_fhs.clk " ,
FT_UINT32 , BASE_HEX , NULL , 0x1ffffff8 ,
NULL , HFILL }
} ,
{ & hf_fhs_pagescanmode ,
{ " Page Scan Mode " , " btbredr_fhs.pagescanmode " ,
FT_UINT32 , BASE_DEC , VALS ( fhs_page_scan_mode_vals ) , 0xe0000000 ,
NULL , HFILL }
2014-12-18 14:54:38 +00:00
}
} ;
static gint * ett [ ] = {
& ett_btbredr_rf ,
& ett_flags ,
& ett_payload_transport_rate ,
& ett_packet_header ,
2021-01-27 06:23:52 +00:00
& ett_bluetooth_header ,
& ett_payload_header ,
& ett_l2cap_msg_fragment ,
& ett_l2cap_msg_fragments ,
& ett_btbredr_fhs
2014-12-18 14:54:38 +00:00
} ;
static ei_register_info ei [ ] = {
{ & ei_unexpected_data , { " btbredr_rf.unexpected_data " , PI_PROTOCOL , PI_WARN , " Unexpected data, BR or EDR Data Present flag is set to False " , EXPFILL } } ,
{ & ei_reserved_not_zero , { " btbredr_rf.reserved_not_zero " , PI_PROTOCOL , PI_WARN , " Reserved values are not zeros " , EXPFILL } } ,
{ & ei_incorrect_packet_header_or_hec , { " btbredr_rf.incorrect_packet_header_or_hec " , PI_PROTOCOL , PI_WARN , " Incorrect Packet Header or HEC " , EXPFILL } } ,
{ & ei_packet_header_with_hec_not_checked , { " btbredr_rf.packet_header_with_hec_not_checked " , PI_PROTOCOL , PI_NOTE , " Packet Header with HEC is not checked " , EXPFILL } } ,
2021-01-27 06:23:52 +00:00
{ & ei_broken_packet_header_format , { " btbredr_rf.broken_packet_header_format " , PI_PROTOCOL , PI_WARN , " Broken Packet Header Format " , EXPFILL } } ,
{ & ei_incorrect_crc , { " btbredr_rf.incorrect_crc " , PI_PROTOCOL , PI_WARN , " Incorrect CRC " , EXPFILL } } ,
{ & ei_missing_fragment_start , { " btbredr_rf.missing_fragment_start " , PI_SEQUENCE , PI_WARN , " Missing Fragment Start " , EXPFILL } } ,
{ & ei_esco_incorrect_ltaddr , { " btbredr_rf.esco_incorrect_ltaddr " , PI_PROTOCOL , PI_WARN , " Incorrect (e)SCO LT_ADDR " , EXPFILL } } ,
{ & ei_esco_incorrect_length , { " btbredr_rf.esco_incorrect_length " , PI_PROTOCOL , PI_WARN , " Incorrect eSCO Packet Length " , EXPFILL } }
2014-12-18 14:54:38 +00:00
} ;
2021-01-27 06:23:52 +00:00
connection_info_tree = wmem_tree_new_autoreset ( wmem_epan_scope ( ) , wmem_file_scope ( ) ) ;
device_info_tree = wmem_tree_new_autoreset ( wmem_epan_scope ( ) , wmem_file_scope ( ) ) ;
2014-12-18 14:54:38 +00:00
proto_btbredr_rf = proto_register_protocol ( " Bluetooth Pseudoheader for BR/EDR " , " BT BR/EDR RF " , " btbredr_rf " ) ;
proto_register_field_array ( proto_btbredr_rf , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
btbredr_rf_handle = register_dissector ( " btbredr_rf " , dissect_btbredr_rf , proto_btbredr_rf ) ;
2021-01-27 06:23:52 +00:00
proto_btbredr_fhs = proto_register_protocol ( " Bluetooth BR/EDR FHS " , " BT BR/EDR FHS " , " btbredr_fhs " ) ;
proto_register_field_array ( proto_btbredr_fhs , hf_fhs , array_length ( hf_fhs ) ) ;
btbredr_fhs_handle = register_dissector ( " btbredr_fhs " , dissect_btbredr_fhs , proto_btbredr_fhs ) ;
2016-08-30 22:51:54 +00:00
packet_type_sco_br_table = register_dissector_table ( " btbredr_rf.packet_type.sco.br " , " BT Packet Type for SCO BR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_esco_br_table = register_dissector_table ( " btbredr_rf.packet_type.esco.br " , " BT Packet Type for eSCO BR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_esco_edr_table = register_dissector_table ( " btbredr_rf.packet_type.esco.edr " , " BT Packet Type for eSCO EDR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_acl_br_table = register_dissector_table ( " btbredr_rf.packet_type.acl.br " , " BT Packet Type for ACL BR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_acl_edr_table = register_dissector_table ( " btbredr_rf.packet_type.acl.edr " , " BT Packet Type for ACL EDR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_csb_br_table = register_dissector_table ( " btbredr_rf.packet_type.csb.br " , " BT Packet Type for CSB BR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
packet_type_csb_edr_table = register_dissector_table ( " btbredr_rf.packet_type.csb.edr " , " BT Packet Type for CSB EDR " , proto_btbredr_rf , FT_UINT8 , BASE_HEX ) ;
2014-12-18 14:54:38 +00:00
expert_module = expert_register_protocol ( proto_btbredr_rf ) ;
expert_register_field_array ( expert_module , ei , array_length ( ei ) ) ;
}
void
proto_reg_handoff_btbredr_rf ( void )
{
2021-01-27 06:23:52 +00:00
btlmp_handle = find_dissector_add_dependency ( " btlmp " , proto_btbredr_rf ) ;
btl2cap_handle = find_dissector_add_dependency ( " btl2cap " , proto_btbredr_rf ) ;
2014-12-18 14:54:38 +00:00
dissector_add_uint ( " bluetooth.encap " , WTAP_ENCAP_BLUETOOTH_BREDR_BB , btbredr_rf_handle ) ;
}
/*
2019-07-26 18:43:17 +00:00
* Editor modelines - https : //www.wireshark.org/tools/modelines.html
2014-12-18 14:54:38 +00:00
*
* 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 :
*/