2 * Routines for Bluetooth Low Energy Link Layer dissection
3 * https://www.bluetooth.org/Technical/Specifications/adopted.htm
5 * Copyright 2013, Mike Ryan, mikeryan /at/ isecpartners /dot/ com
6 * Copyright 2013, Michal Labedzki for Tieto Corporation
7 * Copyright 2014, Christopher D. Kilgour, techie at whiterocker dot com
8 * Copyright 2017, Stig Bjorlykke for Nordic Semiconductor
9 * Copyright 2021, Thomas Sailer
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
22 #include <epan/expert.h>
23 #include <epan/proto_data.h>
24 #include <epan/reassemble.h>
26 #include <epan/unit_strings.h>
28 #include <wiretap/wtap.h>
30 #include "packet-btle.h"
31 #include "packet-bthci_cmd.h"
32 #include "packet-bthci_acl.h"
34 static int proto_btle
;
35 static int proto_btle_rf
;
36 static int proto_nordic_ble
;
38 static int hf_access_address
;
39 static int hf_coding_indicator
;
41 static int hf_central_bd_addr
;
42 static int hf_peripheral_bd_addr
;
44 static int hf_advertising_header
;
45 static int hf_advertising_header_pdu_type
;
46 static int hf_advertising_header_ch_sel
;
47 static int hf_advertising_header_rfu_1
;
48 static int hf_advertising_header_rfu_2
;
49 static int hf_advertising_header_rfu_3
;
50 static int hf_advertising_header_rfu_4
;
51 static int hf_advertising_header_randomized_tx
;
52 static int hf_advertising_header_randomized_rx
;
53 static int hf_advertising_header_length
;
54 static int hf_advertising_address
;
55 static int hf_initiator_addresss
;
56 static int hf_target_addresss
;
57 static int hf_scanning_address
;
58 static int hf_scan_response_data
;
59 static int hf_link_layer_data
;
60 static int hf_link_layer_data_access_address
;
61 static int hf_link_layer_data_crc_init
;
62 static int hf_link_layer_data_window_size
;
63 static int hf_link_layer_data_window_offset
;
64 static int hf_link_layer_data_interval
;
65 static int hf_link_layer_data_latency
;
66 static int hf_link_layer_data_timeout
;
67 static int hf_link_layer_data_channel_map
;
68 static int hf_link_layer_data_hop
;
69 static int hf_link_layer_data_sleep_clock_accuracy
;
70 static int hf_extended_advertising_header
;
71 static int hf_extended_advertising_header_length
;
72 static int hf_extended_advertising_mode
;
73 static int hf_extended_advertising_flags
;
74 static int hf_extended_advertising_flags_adva
;
75 static int hf_extended_advertising_flags_targeta
;
76 static int hf_extended_advertising_flags_cte_info
;
77 static int hf_extended_advertising_flags_advdatainfo
;
78 static int hf_extended_advertising_flags_aux_ptr
;
79 static int hf_extended_advertising_flags_sync_info
;
80 static int hf_extended_advertising_flags_tx_power
;
81 static int hf_extended_advertising_flags_reserved
;
82 static int hf_extended_advertising_cte_info
;
83 static int hf_extended_advertising_cte_info_time
;
84 static int hf_extended_advertising_cte_info_rfu
;
85 static int hf_extended_advertising_cte_info_type
;
86 static int hf_extended_advertising_data_info
;
87 static int hf_extended_advertising_data_info_did
;
88 static int hf_extended_advertising_data_info_sid
;
89 static int hf_extended_advertising_aux_ptr
;
90 static int hf_extended_advertising_aux_ptr_channel
;
91 static int hf_extended_advertising_aux_ptr_ca
;
92 static int hf_extended_advertising_aux_ptr_offset_units
;
93 static int hf_extended_advertising_aux_ptr_aux_offset
;
94 static int hf_extended_advertising_aux_ptr_aux_phy
;
95 static int hf_extended_advertising_sync_info
;
96 static int hf_extended_advertising_sync_info_offset
;
97 static int hf_extended_advertising_sync_info_offset_units
;
98 static int hf_extended_advertising_sync_info_offset_adjust
;
99 static int hf_extended_advertising_sync_info_reserved
;
100 static int hf_extended_advertising_sync_info_interval
;
101 static int hf_extended_advertising_sync_info_channel_map
;
102 static int hf_extended_advertising_sync_info_sleep_clock_accuracy
;
103 static int hf_extended_advertising_sync_info_access_address
;
104 static int hf_extended_advertising_sync_info_crc_init
;
105 static int hf_extended_advertising_sync_info_event_counter
;
106 static int hf_extended_advertising_tx_power
;
107 static int hf_extended_advertising_header_acad
;
108 static int hf_extended_advertising_had_fragment
;
109 static int hf_data_header
;
110 static int hf_data_header_length
;
111 static int hf_data_header_rfu
;
112 static int hf_data_header_llid
;
113 static int hf_data_header_llid_connectediso
;
114 static int hf_data_header_llid_broadcastiso
;
115 static int hf_data_header_more_data
;
116 static int hf_data_header_cte_info_present
;
117 static int hf_data_header_sequence_number
;
118 static int hf_data_header_next_expected_sequence_number
;
119 static int hf_data_header_rfu_57
;
120 static int hf_data_header_rfu_67
;
121 static int hf_data_header_close_isochronous_event
;
122 static int hf_data_header_null_pdu_indicator
;
123 static int hf_data_header_control_subevent_sequence_number
;
124 static int hf_data_header_control_subevent_transmission_flag
;
125 static int hf_data_header_cte_info
;
126 static int hf_data_header_cte_info_time
;
127 static int hf_data_header_cte_info_rfu
;
128 static int hf_data_header_cte_info_type
;
129 static int hf_control_opcode
;
130 static int hf_l2cap_index
;
131 static int hf_l2cap_fragment
;
132 static int hf_connection_parameters_in
;
133 static int hf_control_reject_opcode
;
134 static int hf_control_error_code
;
135 static int hf_control_unknown_type
;
136 static int hf_control_version_number
;
137 static int hf_control_company_id
;
138 static int hf_control_subversion_number
;
139 static int hf_control_feature_set
;
140 static int hf_control_feature_set_le_encryption
;
141 static int hf_control_feature_set_connection_parameters_request_procedure
;
142 static int hf_control_feature_set_extended_reject_indication
;
143 static int hf_control_feature_set_peripheral_initiated_features_exchange
;
144 static int hf_control_feature_set_le_ping
;
145 static int hf_control_feature_set_le_pkt_len_ext
;
146 static int hf_control_feature_set_ll_privacy
;
147 static int hf_control_feature_set_ext_scan_flt_pol
;
148 static int hf_control_feature_set_le_2m_phy
;
149 static int hf_control_feature_set_stable_modulation_index_transmitter
;
150 static int hf_control_feature_set_stable_modulation_index_receiver
;
151 static int hf_control_feature_set_le_coded_phy
;
152 static int hf_control_feature_set_le_extended_advertising
;
153 static int hf_control_feature_set_le_periodic_advertising
;
154 static int hf_control_feature_set_channel_selection_algorithm_2
;
155 static int hf_control_feature_set_le_power_class_1
;
156 static int hf_control_feature_set_minimum_number_of_used_channels_procedure
;
157 static int hf_control_feature_set_connection_cte_request
;
158 static int hf_control_feature_set_connection_cte_response
;
159 static int hf_control_feature_set_connectionless_cte_tx
;
160 static int hf_control_feature_set_connectionless_cte_rx
;
161 static int hf_control_feature_set_antenna_switching_tx_aod
;
162 static int hf_control_feature_set_antenna_switching_rx_aoa
;
163 static int hf_control_feature_set_cte_rx
;
164 static int hf_control_feature_set_past_sender
;
165 static int hf_control_feature_set_past_receiver
;
166 static int hf_control_feature_set_sca_updates
;
167 static int hf_control_feature_set_remote_public_key_validation
;
168 static int hf_control_feature_set_cis_central
;
169 static int hf_control_feature_set_cis_peripheral
;
170 static int hf_control_feature_set_iso_broadcast
;
171 static int hf_control_feature_set_synchronized_receiver
;
172 static int hf_control_feature_set_connected_iso_host_support
;
173 static int hf_control_feature_set_le_power_control_request1
;
174 static int hf_control_feature_set_le_power_control_request2
;
175 static int hf_control_feature_set_le_path_loss_monitoring
;
176 static int hf_control_feature_set_le_periodic_adv_adi_support
;
177 static int hf_control_feature_set_connection_subrating
;
178 static int hf_control_feature_set_connection_subrating_host_support
;
179 static int hf_control_feature_set_channel_classification
;
180 static int hf_control_feature_set_adv_coding_selection
;
181 static int hf_control_feature_set_adv_coding_selection_host_support
;
182 static int hf_control_feature_set_decision_based_advertising_filtering
;
183 static int hf_control_feature_set_periodic_adv_with_responses_advertiser
;
184 static int hf_control_feature_set_periodic_adv_with_responses_scanner
;
185 static int hf_control_feature_set_unsegmented_frame_mode
;
186 static int hf_control_feature_set_channel_sounding
;
187 static int hf_control_feature_set_channel_sounding_host_support
;
188 static int hf_control_feature_set_channel_sounding_tone_quality_indication
;
189 static int hf_control_feature_set_reserved_bits_page_7
;
190 static int hf_control_feature_set_reserved_bits_page_8
;
191 static int hf_control_feature_set_ll_extended_feature_set
;
192 static int hf_control_feature_set_monitoring_advertisers
;
193 static int hf_control_feature_set_frame_space_update
;
194 static int hf_control_feature_set_reserved_bits_page_9
;
195 static int hf_control_window_size
;
196 static int hf_control_window_offset
;
197 static int hf_control_interval
;
198 static int hf_control_latency
;
199 static int hf_control_timeout
;
200 static int hf_control_instant
;
201 static int hf_control_rfu_5
;
202 static int hf_control_interval_min
;
203 static int hf_control_interval_max
;
204 static int hf_control_preferred_periodicity
;
205 static int hf_control_reference_connection_event_count
;
206 static int hf_control_offset_0
;
207 static int hf_control_offset_1
;
208 static int hf_control_offset_2
;
209 static int hf_control_offset_3
;
210 static int hf_control_offset_4
;
211 static int hf_control_offset_5
;
212 static int hf_control_channel_map
;
213 static int hf_control_random_number
;
214 static int hf_control_encrypted_diversifier
;
215 static int hf_control_central_session_key_diversifier
;
216 static int hf_control_central_session_initialization_vector
;
217 static int hf_control_peripheral_session_key_diversifier
;
218 static int hf_control_peripheral_session_initialization_vector
;
219 static int hf_control_max_rx_octets
;
220 static int hf_control_max_rx_time
;
221 static int hf_control_max_tx_octets
;
222 static int hf_control_max_tx_time
;
223 static int hf_control_phys_sender_le_1m_phy
;
224 static int hf_control_phys_sender_le_2m_phy
;
225 static int hf_control_phys_sender_le_coded_phy
;
226 static int hf_control_phys_update_le_1m_phy
;
227 static int hf_control_phys_update_le_2m_phy
;
228 static int hf_control_phys_update_le_coded_phy
;
229 static int hf_control_phys_reserved_bits
;
230 static int hf_control_tx_phys
;
231 static int hf_control_rx_phys
;
232 static int hf_control_c_to_p_phy
;
233 static int hf_control_c_to_p_phy_le_1m_phy
;
234 static int hf_control_c_to_p_phy_le_2m_phy
;
235 static int hf_control_c_to_p_phy_le_coded_phy
;
236 static int hf_control_c_to_p_phy_reserved_bits
;
237 static int hf_control_p_to_c_phy
;
238 static int hf_control_p_to_c_phy_le_1m_phy
;
239 static int hf_control_p_to_c_phy_le_2m_phy
;
240 static int hf_control_p_to_c_phy_le_coded_phy
;
241 static int hf_control_p_to_c_phy_reserved_bits
;
242 static int hf_control_phys
;
243 static int hf_control_phys_le_1m_phy
;
244 static int hf_control_phys_le_2m_phy
;
245 static int hf_control_phys_le_coded_phy
;
246 static int hf_control_min_used_channels
;
247 static int hf_control_cte_min_len_req
;
248 static int hf_control_cte_rfu
;
249 static int hf_control_cte_type_req
;
250 static int hf_control_sync_id
;
251 static int hf_control_sync_info_offset
;
252 static int hf_control_sync_info_offset_units
;
253 static int hf_control_sync_info_offset_adjust
;
254 static int hf_control_sync_info_reserved
;
255 static int hf_control_sync_info_interval
;
256 static int hf_control_sync_info_channel_map
;
257 static int hf_control_sync_info_sleep_clock_accuracy
;
258 static int hf_control_sync_info_access_address
;
259 static int hf_control_sync_info_crc_init
;
260 static int hf_control_sync_info_event_counter
;
261 static int hf_control_sync_conn_event_count
;
262 static int hf_control_sync_last_pa_event_counter
;
263 static int hf_control_sync_sid
;
264 static int hf_control_sync_atype
;
265 static int hf_control_sync_sleep_clock_accuracy
;
266 static int hf_control_sync_sync_conn_event_counter
;
267 static int hf_control_sleep_clock_accuracy
;
268 static int hf_control_cig_id
;
269 static int hf_control_cis_id
;
270 static int hf_control_max_sdu_c_to_p
;
271 static int hf_control_rfu_1
;
272 static int hf_control_framed
;
273 static int hf_control_max_sdu_p_to_c
;
274 static int hf_control_rfu_2
;
275 static int hf_control_sdu_interval_c_to_p
;
276 static int hf_control_rfu_3
;
277 static int hf_control_sdu_interval_p_to_c
;
278 static int hf_control_rfu_4
;
279 static int hf_control_max_pdu_c_to_p
;
280 static int hf_control_max_pdu_p_to_c
;
281 static int hf_control_num_sub_events
;
282 static int hf_control_sub_interval
;
283 static int hf_control_bn_c_to_p
;
284 static int hf_control_bn_p_to_c
;
285 static int hf_control_ft_c_to_p
;
286 static int hf_control_ft_p_to_c
;
287 static int hf_control_iso_interval
;
288 static int hf_control_cis_offset_min
;
289 static int hf_control_cis_offset_max
;
290 static int hf_control_conn_event_count
;
291 static int hf_control_access_address
;
292 static int hf_control_cis_offset
;
293 static int hf_control_cig_sync_delay
;
294 static int hf_control_cis_sync_delay
;
295 static int hf_control_pwr_phy
;
296 static int hf_control_pwr_phy_le_1m_phy
;
297 static int hf_control_pwr_phy_le_2m_phy
;
298 static int hf_control_pwr_phy_le_coded_s8_phy
;
299 static int hf_control_pwr_phy_le_coded_s2_phy
;
300 static int hf_control_pwr_phy_reserved_bits
;
301 static int hf_control_delta
;
302 static int hf_control_txpwr
;
303 static int hf_control_pwrflags
;
304 static int hf_control_pwrflags_min
;
305 static int hf_control_pwrflags_max
;
306 static int hf_control_pwrflags_reserved_bits
;
307 static int hf_control_acceptable_power_reduction
;
308 static int hf_control_subrate_factor_min
;
309 static int hf_control_subrate_factor_max
;
310 static int hf_control_max_latency
;
311 static int hf_control_continuation_number
;
312 static int hf_control_subrate_factor
;
313 static int hf_control_subrate_base_event
;
314 static int hf_control_channel_reporting_enable
;
315 static int hf_control_channel_reporting_min_spacing
;
316 static int hf_control_channel_reporting_max_delay
;
317 static int hf_control_channel_classification
;
318 static int hf_control_sync_info_rsp_access_address
;
319 static int hf_control_sync_info_num_subevents
;
320 static int hf_control_sync_info_subevent_interval
;
321 static int hf_control_sync_info_response_slot_delay
;
322 static int hf_control_sync_info_response_slot_spacing
;
323 static int hf_big_control_opcode
;
324 static int hf_isochronous_data
;
325 static int hf_btle_l2cap_msg_fragments
;
326 static int hf_btle_l2cap_msg_fragment
;
327 static int hf_btle_l2cap_msg_fragment_overlap
;
328 static int hf_btle_l2cap_msg_fragment_overlap_conflicts
;
329 static int hf_btle_l2cap_msg_fragment_multiple_tails
;
330 static int hf_btle_l2cap_msg_fragment_too_long_fragment
;
331 static int hf_btle_l2cap_msg_fragment_error
;
332 static int hf_btle_l2cap_msg_fragment_count
;
333 static int hf_btle_l2cap_msg_reassembled_in
;
334 static int hf_btle_l2cap_msg_reassembled_length
;
335 static int hf_btle_ea_host_advertising_data_fragments
;
336 static int hf_btle_ea_host_advertising_data_fragment
;
337 static int hf_btle_ea_host_advertising_data_fragment_overlap
;
338 static int hf_btle_ea_host_advertising_data_fragment_overlap_conflicts
;
339 static int hf_btle_ea_host_advertising_data_fragment_multiple_tails
;
340 static int hf_btle_ea_host_advertising_data_fragment_too_long_fragment
;
341 static int hf_btle_ea_host_advertising_data_fragment_error
;
342 static int hf_btle_ea_host_advertising_data_fragment_count
;
343 static int hf_btle_ea_host_advertising_data_reassembled_in
;
344 static int hf_btle_ea_host_advertising_data_reassembled_length
;
346 static int hf_request_in_frame
;
347 static int hf_response_in_frame
;
350 static int ett_advertising_header
;
351 static int ett_link_layer_data
;
352 static int ett_data_header
;
353 static int ett_data_header_cte_info
;
354 static int ett_features
;
355 static int ett_tx_phys
;
356 static int ett_rx_phys
;
357 static int ett_c_to_p_phy
;
358 static int ett_p_to_c_phy
;
360 static int ett_pwr_phy
;
362 static int ett_channel_map
;
363 static int ett_scan_response_data
;
364 static int ett_pwrflags
;
365 static int ett_btle_l2cap_msg_fragment
;
366 static int ett_btle_l2cap_msg_fragments
;
367 static int ett_btle_ea_host_advertising_data_fragment
;
368 static int ett_btle_ea_host_advertising_data_fragments
;
369 static int ett_extended_advertising_header
;
370 static int ett_extended_advertising_flags
;
371 static int ett_extended_advertising_cte_info
;
372 static int ett_extended_advertising_data_info
;
373 static int ett_extended_advertising_aux_pointer
;
374 static int ett_extended_advertising_sync_info
;
375 static int ett_extended_advertising_acad
;
377 static int * const hfx_extended_advertising_flags
[] = {
378 &hf_extended_advertising_flags_adva
,
379 &hf_extended_advertising_flags_targeta
,
380 &hf_extended_advertising_flags_cte_info
,
381 &hf_extended_advertising_flags_advdatainfo
,
382 &hf_extended_advertising_flags_aux_ptr
,
383 &hf_extended_advertising_flags_sync_info
,
384 &hf_extended_advertising_flags_tx_power
,
385 &hf_extended_advertising_flags_reserved
,
389 static int * const hfx_control_feature_set_1
[] = {
390 &hf_control_feature_set_le_encryption
,
391 &hf_control_feature_set_connection_parameters_request_procedure
,
392 &hf_control_feature_set_extended_reject_indication
,
393 &hf_control_feature_set_peripheral_initiated_features_exchange
,
394 &hf_control_feature_set_le_ping
,
395 &hf_control_feature_set_le_pkt_len_ext
,
396 &hf_control_feature_set_ll_privacy
,
397 &hf_control_feature_set_ext_scan_flt_pol
,
401 static int * const hfx_control_feature_set_2
[] = {
402 &hf_control_feature_set_le_2m_phy
,
403 &hf_control_feature_set_stable_modulation_index_transmitter
,
404 &hf_control_feature_set_stable_modulation_index_receiver
,
405 &hf_control_feature_set_le_coded_phy
,
406 &hf_control_feature_set_le_extended_advertising
,
407 &hf_control_feature_set_le_periodic_advertising
,
408 &hf_control_feature_set_channel_selection_algorithm_2
,
409 &hf_control_feature_set_le_power_class_1
,
413 static int * const hfx_control_feature_set_3
[] = {
414 &hf_control_feature_set_minimum_number_of_used_channels_procedure
,
415 &hf_control_feature_set_connection_cte_request
,
416 &hf_control_feature_set_connection_cte_response
,
417 &hf_control_feature_set_connectionless_cte_tx
,
418 &hf_control_feature_set_connectionless_cte_rx
,
419 &hf_control_feature_set_antenna_switching_tx_aod
,
420 &hf_control_feature_set_antenna_switching_rx_aoa
,
421 &hf_control_feature_set_cte_rx
,
425 static int * const hfx_control_feature_set_4
[] = {
426 &hf_control_feature_set_past_sender
,
427 &hf_control_feature_set_past_receiver
,
428 &hf_control_feature_set_sca_updates
,
429 &hf_control_feature_set_remote_public_key_validation
,
430 &hf_control_feature_set_cis_central
,
431 &hf_control_feature_set_cis_peripheral
,
432 &hf_control_feature_set_iso_broadcast
,
433 &hf_control_feature_set_synchronized_receiver
,
437 static int * const hfx_control_feature_set_5
[] = {
438 &hf_control_feature_set_connected_iso_host_support
,
439 &hf_control_feature_set_le_power_control_request1
,
440 &hf_control_feature_set_le_power_control_request2
,
441 &hf_control_feature_set_le_path_loss_monitoring
,
442 &hf_control_feature_set_le_periodic_adv_adi_support
,
443 &hf_control_feature_set_connection_subrating
,
444 &hf_control_feature_set_connection_subrating_host_support
,
445 &hf_control_feature_set_channel_classification
,
449 static int *const hfx_control_feature_set_6
[] = {
450 &hf_control_feature_set_adv_coding_selection
,
451 &hf_control_feature_set_adv_coding_selection_host_support
,
452 &hf_control_feature_set_decision_based_advertising_filtering
,
453 &hf_control_feature_set_periodic_adv_with_responses_advertiser
,
454 &hf_control_feature_set_periodic_adv_with_responses_scanner
,
455 &hf_control_feature_set_unsegmented_frame_mode
,
456 &hf_control_feature_set_channel_sounding
,
457 &hf_control_feature_set_channel_sounding_host_support
,
461 static int *const hfx_control_feature_set_7
[] = {
462 &hf_control_feature_set_channel_sounding_tone_quality_indication
,
463 &hf_control_feature_set_reserved_bits_page_7
,
467 static int *const hfx_control_feature_set_8
[] = {
468 &hf_control_feature_set_reserved_bits_page_8
,
469 &hf_control_feature_set_ll_extended_feature_set
,
473 static int * const hfx_control_phys_sender
[] = {
474 &hf_control_phys_sender_le_1m_phy
,
475 &hf_control_phys_sender_le_2m_phy
,
476 &hf_control_phys_sender_le_coded_phy
,
477 &hf_control_phys_reserved_bits
,
481 static int * const hfx_control_phys_update
[] = {
482 &hf_control_phys_update_le_1m_phy
,
483 &hf_control_phys_update_le_2m_phy
,
484 &hf_control_phys_update_le_coded_phy
,
485 &hf_control_phys_reserved_bits
,
489 static int * const hfx_control_c_to_p_phy
[] = {
490 &hf_control_c_to_p_phy_le_1m_phy
,
491 &hf_control_c_to_p_phy_le_2m_phy
,
492 &hf_control_c_to_p_phy_le_coded_phy
,
493 &hf_control_c_to_p_phy_reserved_bits
,
497 static int * const hfx_control_p_to_c_phy
[] = {
498 &hf_control_p_to_c_phy_le_1m_phy
,
499 &hf_control_p_to_c_phy_le_2m_phy
,
500 &hf_control_p_to_c_phy_le_coded_phy
,
501 &hf_control_p_to_c_phy_reserved_bits
,
505 static int * const hfx_control_phys
[] = {
506 &hf_control_phys_le_1m_phy
,
507 &hf_control_phys_le_2m_phy
,
508 &hf_control_phys_le_coded_phy
,
509 &hf_control_phys_reserved_bits
,
513 static int * const hfx_control_pwr_phy
[] = {
514 &hf_control_pwr_phy_le_1m_phy
,
515 &hf_control_pwr_phy_le_2m_phy
,
516 &hf_control_pwr_phy_le_coded_s8_phy
,
517 &hf_control_pwr_phy_le_coded_s2_phy
,
518 &hf_control_pwr_phy_reserved_bits
,
522 static int * const hfx_control_cte
[] = {
523 &hf_control_cte_min_len_req
,
525 &hf_control_cte_type_req
,
529 static int * const hfx_control_periodicsyncflags
[] = {
530 &hf_control_sync_sid
,
531 &hf_control_sync_atype
,
532 &hf_control_sync_sleep_clock_accuracy
,
536 static int * const hfx_control_pwrflags
[] = {
537 &hf_control_pwrflags_min
,
538 &hf_control_pwrflags_max
,
539 &hf_control_pwrflags_reserved_bits
,
543 static expert_field ei_unknown_data
;
544 static expert_field ei_access_address_matched
;
545 static expert_field ei_access_address_bit_errors
;
546 static expert_field ei_access_address_illegal
;
547 static expert_field ei_crc_cannot_be_determined
;
548 static expert_field ei_crc_incorrect
;
549 static expert_field ei_missing_fragment_start
;
550 static expert_field ei_retransmit
;
551 static expert_field ei_nack
;
552 static expert_field ei_control_proc_overlapping
;
553 static expert_field ei_control_proc_invalid_collision
;
554 static expert_field ei_control_proc_wrong_seq
;
555 static expert_field ei_control_proc_invalid_conflict_resolution
;
557 static dissector_handle_t btle_handle
;
558 static dissector_handle_t btcommon_ad_handle
;
559 static dissector_handle_t btcommon_le_channel_map_handle
;
560 static dissector_handle_t btl2cap_handle
;
562 static wmem_tree_t
*connection_info_tree
;
563 static wmem_tree_t
*periodic_adv_info_tree
;
564 static wmem_tree_t
*connectediso_connection_info_tree
;
565 static wmem_tree_t
*broadcastiso_connection_info_tree
;
566 static wmem_tree_t
*connection_parameter_info_tree
;
567 static wmem_tree_t
*adi_to_first_frame_tree
;
568 static uint32_t l2cap_index
;
571 static reassembly_table btle_l2cap_msg_reassembly_table
;
573 static const fragment_items btle_l2cap_msg_frag_items
= {
574 /* Fragment subtrees */
575 &ett_btle_l2cap_msg_fragment
,
576 &ett_btle_l2cap_msg_fragments
,
577 /* Fragment fields */
578 &hf_btle_l2cap_msg_fragments
,
579 &hf_btle_l2cap_msg_fragment
,
580 &hf_btle_l2cap_msg_fragment_overlap
,
581 &hf_btle_l2cap_msg_fragment_overlap_conflicts
,
582 &hf_btle_l2cap_msg_fragment_multiple_tails
,
583 &hf_btle_l2cap_msg_fragment_too_long_fragment
,
584 &hf_btle_l2cap_msg_fragment_error
,
585 &hf_btle_l2cap_msg_fragment_count
,
586 /* Reassembled in field */
587 &hf_btle_l2cap_msg_reassembled_in
,
588 /* Reassembled length field */
589 &hf_btle_l2cap_msg_reassembled_length
,
590 /* Reassembled data field */
593 "BTLE L2CAP fragments"
596 /* Extended Advertising Host Advertising Data Reassembly */
597 static reassembly_table btle_ea_host_advertising_data_reassembly_table
;
599 static const fragment_items btle_ea_host_advertising_data_frag_items
= {
600 /* Fragment subtrees */
601 &ett_btle_ea_host_advertising_data_fragment
,
602 &ett_btle_ea_host_advertising_data_fragments
,
603 /* Fragment fields */
604 &hf_btle_ea_host_advertising_data_fragments
,
605 &hf_btle_ea_host_advertising_data_fragment
,
606 &hf_btle_ea_host_advertising_data_fragment_overlap
,
607 &hf_btle_ea_host_advertising_data_fragment_overlap_conflicts
,
608 &hf_btle_ea_host_advertising_data_fragment_multiple_tails
,
609 &hf_btle_ea_host_advertising_data_fragment_too_long_fragment
,
610 &hf_btle_ea_host_advertising_data_fragment_error
,
611 &hf_btle_ea_host_advertising_data_fragment_count
,
612 /* Reassembled in field */
613 &hf_btle_ea_host_advertising_data_reassembled_in
,
614 /* Reassembled length field */
615 &hf_btle_ea_host_advertising_data_reassembled_length
,
616 /* Reassembled data field */
619 "BTLE EA HAD fragments"
622 typedef struct _ae_had_info_t
{
623 unsigned fragment_counter
;
624 uint32_t first_frame_num
;
628 typedef struct _control_proc_info_t
{
629 /* Sequence of frame numbers of the control procedure used for request/response matching.
630 * The first entry corresponds to the request, the remaining frames are responses.
631 * The longest sequence is needed for the encryption start procedure,
632 * which consists of 5 frames. */
635 /* Opcode of the first control procedure packet. */
638 /* The frame where the procedure completes. Set to 0 when not yet known.
639 * This is used to avoid adding another frame to the control procedure
640 * sequence after the procedure was aborted early.
642 * This frame number may be ignored in the case where an LL_UNKNOWN_RSP is
643 * received after a procedure involving only one packet, like the
644 * LL_MIN_USED_CHANNELS_IND. */
647 /* The frame number of the packet containing the instant value.
648 * If set to 0, there is no such frame.
650 * We need to store this frame number, as any event counter is
651 * a valid instant. */
652 unsigned frame_with_instant_value
;
654 /* The event counter corresponding to the instant of the control procedure. */
656 } control_proc_info_t
;
658 /* Store information about a connection direction */
659 typedef struct _direction_info_t
{
660 unsigned prev_seq_num
: 1; /* Previous sequence number for this direction */
661 unsigned segmentation_started
: 1; /* 0 = No, 1 = Yes */
662 unsigned segment_len_rem
; /* The remaining segment length, used to find last segment */
663 uint32_t l2cap_index
; /* Unique identifier for each L2CAP message */
665 wmem_tree_t
*control_procs
; /* Control procedures initiated from this direction. */
668 typedef struct _connection_parameter_info_t
{
669 uint32_t parameters_frame
;
670 } connection_parameter_info_t
;
672 /* Store information about a connection */
673 typedef struct _connection_info_t
{
676 uint8_t central_bd_addr
[6];
677 uint8_t peripheral_bd_addr
[6];
679 uint16_t connection_parameter_update_instant
;
680 connection_parameter_info_t
*connection_parameter_update_info
;
682 /* Connection information */
683 /* Data used on the first pass to get info from previous frame, result will be in per_packet_data */
684 unsigned first_data_frame_seen
: 1;
685 direction_info_t direction_info
[3]; /* UNKNOWN, CENTRAL_PERIPHERAL and PERIPHERAL_CENTRAL */
689 /* Store information about a connected ISO connection */
690 typedef struct _connectediso_connection_info_t
{
691 uint8_t central_bd_addr
[6];
692 uint8_t peripheral_bd_addr
[6];
693 } connectediso_connection_info_t
;
696 /* Store information about a broadcast isochronous connection */
697 typedef struct _broadcastiso_connection_info_t
{
698 uint8_t central_bd_addr
[6];
699 } broadcastiso_connection_info_t
;
702 typedef struct _btle_frame_info_t
{
703 unsigned retransmit
: 1; /* 0 = No, 1 = Retransmitted frame */
704 unsigned ack
: 1; /* 0 = Nack, 1 = Ack */
705 unsigned more_fragments
: 1; /* 0 = Last fragment, 1 = More fragments */
706 unsigned missing_start
: 1; /* 0 = No, 1 = Missing fragment start */
707 uint32_t l2cap_index
; /* Unique identifier for each L2CAP message */
710 static const value_string pdu_type_vals
[] = {
712 { 0x01, "ADV_DIRECT_IND" },
713 { 0x02, "ADV_NONCONN_IND" },
714 { 0x03, "SCAN_REQ" },
715 { 0x04, "SCAN_RSP" },
716 { 0x05, "CONNECT_IND" },
717 { 0x06, "ADV_SCAN_IND" },
718 { 0x07, "ADV_EXT_IND" },
719 { 0x08, "AUX_CONNECT_RSP" },
720 { 0x09, "ADV_DECISION_IND" },
723 static value_string_ext pdu_type_vals_ext
= VALUE_STRING_EXT_INIT(pdu_type_vals
);
725 static const value_string aux_pdu_type_vals
[] = {
726 { 0x03, "AUX_SCAN_REQ" },
727 { 0x05, "AUX_CONNECT_REQ" },
728 { 0x07, "AUX_COMMON" },
729 { 0x08, "AUX_CONNECT_RSP" },
732 static value_string_ext aux_pdu_type_vals_ext
= VALUE_STRING_EXT_INIT(aux_pdu_type_vals
);
734 static const value_string aux_pdu_common_vals
[] = {
735 { 0, "AUX_ADV_IND" },
736 { 1, "AUX_CHAIN_IND" },
737 { 2, "AUX_SYNC_IND" },
738 { 3, "AUX_SCAN_RSP" },
741 static value_string_ext aux_pdu_common_vals_ext
= VALUE_STRING_EXT_INIT(aux_pdu_common_vals
);
743 static const value_string le_coding_indicators
[] =
745 { 0, "FEC Block 2 coded using S=8" },
746 { 1, "FEC Block 2 coded using S=2" },
752 static const value_string sleep_clock_accuracy_vals
[] = {
753 { 0x00, "251 ppm to 500 ppm" },
754 { 0x01, "151 ppm to 250 ppm" },
755 { 0x02, "101 ppm to 150 ppm" },
756 { 0x03, "76 ppm to 100 ppm" },
757 { 0x04, "51 ppm to 75 ppm" },
758 { 0x05, "31 ppm to 50 ppm" },
759 { 0x06, "21 ppm to 30 ppm" },
760 { 0x07, "0 ppm to 20 ppm" },
763 static value_string_ext sleep_clock_accuracy_vals_ext
= VALUE_STRING_EXT_INIT(sleep_clock_accuracy_vals
);
765 static const value_string llid_codes_vals
[] = {
766 { 0x01, "Continuation fragment of an L2CAP message, or an Empty PDU" },
767 { 0x02, "Start of an L2CAP message or a complete L2CAP message with no fragmentation" },
768 { 0x03, "Control PDU" },
771 static value_string_ext llid_codes_vals_ext
= VALUE_STRING_EXT_INIT(llid_codes_vals
);
773 static const value_string llid_connectediso_codes_vals
[] = {
774 { 0x00, "Unframed CIS Data PDU; end fragment of an SDU or a complete SDU" },
775 { 0x01, "Unframed CIS Data PDU; start or continuation fragment of an SDU" },
776 { 0x02, "Framed CIS Data PDU; one or more segments of an SDU" },
779 static value_string_ext llid_connectediso_codes_vals_ext
= VALUE_STRING_EXT_INIT(llid_connectediso_codes_vals
);
781 static const value_string llid_broadcastiso_codes_vals
[] = {
782 { 0x00, "Unframed BIS Data PDU; end fragment of an SDU or a complete SDU" },
783 { 0x01, "Unframed BIS Data PDU; start or continuation fragment of an SDU" },
784 { 0x02, "Framed BIS Data PDU; one or more segments of an SDU" },
785 { 0x03, "BIG Control PDU" },
788 static value_string_ext llid_broadcastiso_codes_vals_ext
= VALUE_STRING_EXT_INIT(llid_broadcastiso_codes_vals
);
792 LL_CTRL_OPCODE_CONNECTION_UPDATE_IND
= 0x00,
793 LL_CTRL_OPCODE_CHANNEL_MAP_IND
= 0x01,
794 LL_CTRL_OPCODE_TERMINATE_IND
= 0x02,
795 LL_CTRL_OPCODE_ENC_REQ
= 0x03,
796 LL_CTRL_OPCODE_ENC_RSP
= 0x04,
797 LL_CTRL_OPCODE_START_ENC_REQ
= 0x05,
798 LL_CTRL_OPCODE_START_ENC_RSP
= 0x06,
799 LL_CTRL_OPCODE_UNKNOWN_RSP
= 0x07,
800 LL_CTRL_OPCODE_FEATURE_REQ
= 0x08,
801 LL_CTRL_OPCODE_FEATURE_RSP
= 0x09,
802 LL_CTRL_OPCODE_PAUSE_ENC_REQ
= 0x0A,
803 LL_CTRL_OPCODE_PAUSE_ENC_RSP
= 0x0B,
804 LL_CTRL_OPCODE_VERSION_IND
= 0x0C,
805 LL_CTRL_OPCODE_REJECT_IND
= 0x0D,
806 LL_CTRL_OPCODE_PERIPHERAL_FEATURE_REQ
= 0x0E,
807 LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
= 0x0F,
808 LL_CTRL_OPCODE_CONNECTION_PARAM_RSP
= 0x10,
809 LL_CTRL_OPCODE_REJECT_EXT_IND
= 0x11,
810 LL_CTRL_OPCODE_PING_REQ
= 0x12,
811 LL_CTRL_OPCODE_PING_RSP
= 0x13,
812 LL_CTRL_OPCODE_LENGTH_REQ
= 0x14,
813 LL_CTRL_OPCODE_LENGTH_RSP
= 0x15,
814 LL_CTRL_OPCODE_PHY_REQ
= 0x16,
815 LL_CTRL_OPCODE_PHY_RSP
= 0x17,
816 LL_CTRL_OPCODE_PHY_UPDATE_IND
= 0x18,
817 LL_CTRL_OPCODE_MIN_USED_CHANNELS_IND
= 0x19,
818 LL_CTRL_OPCODE_CTE_REQ
= 0x1A,
819 LL_CTRL_OPCODE_CTE_RSP
= 0x1B,
820 LL_CTRL_OPCODE_PERIODIC_SYNC_IND
= 0x1C,
821 LL_CTRL_OPCODE_CLOCK_ACCURACY_REQ
= 0x1D,
822 LL_CTRL_OPCODE_CLOCK_ACCURACY_RSP
= 0x1E,
823 LL_CTRL_OPCODE_CIS_REQ
= 0x1F,
824 LL_CTRL_OPCODE_CIS_RSP
= 0x20,
825 LL_CTRL_OPCODE_CIS_IND
= 0x21,
826 LL_CTRL_OPCODE_CIS_TERMINATE_IND
= 0x22,
827 LL_CTRL_OPCODE_POWER_CONTROL_REQ
= 0x23,
828 LL_CTRL_OPCODE_POWER_CONTROL_RSP
= 0x24,
829 LL_CTRL_OPCODE_POWER_CHANGE_IND
= 0x25,
830 LL_CTRL_OPCODE_SUBRATE_REQ
= 0x26,
831 LL_CTRL_OPCODE_SUBRATE_IND
= 0x27,
832 LL_CTRL_OPCODE_CHANNEL_REPORTING_IND
= 0x28,
833 LL_CTRL_OPCODE_CHANNEL_STATUS_IND
= 0x29,
834 LL_CTRL_OPCODE_PERIODIC_SYNC_WR_IND
= 0x2A,
835 LL_CTRL_OPCODE_LL_FEATURE_EXT_REQ
= 0x2B,
836 LL_CTRL_OPCODE_LL_FEATURE_EXT_RSP
= 0x2C,
837 LL_CTRL_OPCODE_LL_CS_SEC_RSP
= 0x2D,
838 LL_CTRL_OPCODE_LL_CS_CAPABILITIES_REQ
= 0x2E,
839 LL_CTRL_OPCODE_LL_CS_CAPABILITIES_RSP
= 0x2F,
840 LL_CTRL_OPCODE_LL_CS_CONFIG_REQ
= 0x30,
841 LL_CTRL_OPCODE_LL_CS_CONFIG_RSP
= 0x31,
842 LL_CTRL_OPCODE_LL_CS_REQ
= 0x32,
843 LL_CTRL_OPCODE_LL_CS_RSP
= 0x33,
844 LL_CTRL_OPCODE_LL_CS_IND
= 0x34,
845 LL_CTRL_OPCODE_LL_CS_TERMINATE_REQ
= 0x35,
846 LL_CTRL_OPCODE_LL_CS_FAE_REQ
= 0x36,
847 LL_CTRL_OPCODE_LL_CS_FAE_RSP
= 0x37,
848 LL_CTRL_OPCODE_LL_CS_CHANNEL_MAP_IND
= 0x38,
849 LL_CTRL_OPCODE_LL_CS_SEQ_REQ
= 0x39,
850 LL_CTRL_OPCODE_LL_CS_TERMINATE_RSP
= 0x3A,
851 LL_CTRL_OPCODE_LL_FRAME_SPACE_REQ
= 0x3B,
852 LL_CTRL_OPCODE_LL_FRAME_SPACE_RSP
= 0x3C,
853 } ll_ctrl_proc_opcodes_t
;
855 static const value_string control_opcode_vals
[] = {
856 { LL_CTRL_OPCODE_CONNECTION_UPDATE_IND
, "LL_CONNECTION_UPDATE_IND" },
857 { LL_CTRL_OPCODE_CHANNEL_MAP_IND
, "LL_CHANNEL_MAP_IND" },
858 { LL_CTRL_OPCODE_TERMINATE_IND
, "LL_TERMINATE_IND" },
859 { LL_CTRL_OPCODE_ENC_REQ
, "LL_ENC_REQ" },
860 { LL_CTRL_OPCODE_ENC_RSP
, "LL_ENC_RSP" },
861 { LL_CTRL_OPCODE_START_ENC_REQ
, "LL_START_ENC_REQ" },
862 { LL_CTRL_OPCODE_START_ENC_RSP
, "LL_START_ENC_RSP" },
863 { LL_CTRL_OPCODE_UNKNOWN_RSP
, "LL_UNKNOWN_RSP" },
864 { LL_CTRL_OPCODE_FEATURE_REQ
, "LL_FEATURE_REQ" },
865 { LL_CTRL_OPCODE_FEATURE_RSP
, "LL_FEATURE_RSP" },
866 { LL_CTRL_OPCODE_PAUSE_ENC_REQ
, "LL_PAUSE_ENC_REQ" },
867 { LL_CTRL_OPCODE_PAUSE_ENC_RSP
, "LL_PAUSE_ENC_RSP" },
868 { LL_CTRL_OPCODE_VERSION_IND
, "LL_VERSION_IND" },
869 { LL_CTRL_OPCODE_REJECT_IND
, "LL_REJECT_IND" },
870 { LL_CTRL_OPCODE_PERIPHERAL_FEATURE_REQ
, "LL_PERIPHERAL_FEATURE_REQ" },
871 { LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
, "LL_CONNECTION_PARAM_REQ" },
872 { LL_CTRL_OPCODE_CONNECTION_PARAM_RSP
, "LL_CONNECTION_PARAM_RSP" },
873 { LL_CTRL_OPCODE_REJECT_EXT_IND
, "LL_REJECT_EXT_IND" },
874 { LL_CTRL_OPCODE_PING_REQ
, "LL_PING_REQ" },
875 { LL_CTRL_OPCODE_PING_RSP
, "LL_PING_RSP" },
876 { LL_CTRL_OPCODE_LENGTH_REQ
, "LL_LENGTH_REQ" },
877 { LL_CTRL_OPCODE_LENGTH_RSP
, "LL_LENGTH_RSP" },
878 { LL_CTRL_OPCODE_PHY_REQ
, "LL_PHY_REQ" },
879 { LL_CTRL_OPCODE_PHY_RSP
, "LL_PHY_RSP" },
880 { LL_CTRL_OPCODE_PHY_UPDATE_IND
, "LL_PHY_UPDATE_IND" },
881 { LL_CTRL_OPCODE_MIN_USED_CHANNELS_IND
, "LL_MIN_USED_CHANNELS_IND" },
882 { LL_CTRL_OPCODE_CTE_REQ
, "LL_CTE_REQ" },
883 { LL_CTRL_OPCODE_CTE_RSP
, "LL_CTE_RSP" },
884 { LL_CTRL_OPCODE_PERIODIC_SYNC_IND
, "LL_PERIODIC_SYNC_IND" },
885 { LL_CTRL_OPCODE_CLOCK_ACCURACY_REQ
, "LL_CLOCK_ACCURACY_REQ" },
886 { LL_CTRL_OPCODE_CLOCK_ACCURACY_RSP
, "LL_CLOCK_ACCURACY_RSP" },
887 { LL_CTRL_OPCODE_CIS_REQ
, "LL_CIS_REQ" },
888 { LL_CTRL_OPCODE_CIS_RSP
, "LL_CIS_RSP" },
889 { LL_CTRL_OPCODE_CIS_IND
, "LL_CIS_IND" },
890 { LL_CTRL_OPCODE_CIS_TERMINATE_IND
, "LL_CIS_TERMINATE_IND" },
891 { LL_CTRL_OPCODE_POWER_CONTROL_REQ
, "LL_POWER_CONTROL_REQ" },
892 { LL_CTRL_OPCODE_POWER_CONTROL_RSP
, "LL_POWER_CONTROL_RSP" },
893 { LL_CTRL_OPCODE_POWER_CHANGE_IND
, "LL_POWER_CHANGE_IND" },
894 { LL_CTRL_OPCODE_SUBRATE_REQ
, "LL_SUBRATE_REQ" },
895 { LL_CTRL_OPCODE_SUBRATE_IND
, "LL_SUBRATE_IND" },
896 { LL_CTRL_OPCODE_CHANNEL_REPORTING_IND
, "LL_CHANNEL_REPORTING_IND" },
897 { LL_CTRL_OPCODE_CHANNEL_STATUS_IND
, "LL_CHANNEL_STATUS_IND" },
898 { LL_CTRL_OPCODE_PERIODIC_SYNC_WR_IND
, "LL_PERIODIC_SYNC_WR_IND" },
899 { LL_CTRL_OPCODE_LL_FEATURE_EXT_REQ
, "LL_CTRL_OPCODE_LL_FEATURE_EXT_REQ" },
900 { LL_CTRL_OPCODE_LL_FEATURE_EXT_RSP
, "LL_CTRL_OPCODE_LL_FEATURE_EXT_RSP" },
901 { LL_CTRL_OPCODE_LL_CS_SEC_RSP
, "LL_CTRL_OPCODE_LL_CS_SEC_RSP" },
902 { LL_CTRL_OPCODE_LL_CS_CAPABILITIES_REQ
, "LL_CTRL_OPCODE_LL_CS_CAPABILITIES_REQ" },
903 { LL_CTRL_OPCODE_LL_CS_CAPABILITIES_RSP
, "LL_CTRL_OPCODE_LL_CS_CAPABILITIES_RSP" },
904 { LL_CTRL_OPCODE_LL_CS_CONFIG_REQ
, "LL_CTRL_OPCODE_LL_CS_CONFIG_REQ" },
905 { LL_CTRL_OPCODE_LL_CS_CONFIG_RSP
, "LL_CTRL_OPCODE_LL_CS_CONFIG_RSP" },
906 { LL_CTRL_OPCODE_LL_CS_REQ
, "LL_CTRL_OPCODE_LL_CS_REQ" },
907 { LL_CTRL_OPCODE_LL_CS_RSP
, "LL_CTRL_OPCODE_LL_CS_RSP" },
908 { LL_CTRL_OPCODE_LL_CS_IND
, "LL_CTRL_OPCODE_LL_CS_IND" },
909 { LL_CTRL_OPCODE_LL_CS_TERMINATE_REQ
, "LL_CTRL_OPCODE_LL_CS_TERMINATE_REQ" },
910 { LL_CTRL_OPCODE_LL_CS_FAE_REQ
, "LL_CTRL_OPCODE_LL_CS_FAE_REQ" },
911 { LL_CTRL_OPCODE_LL_CS_FAE_RSP
, "LL_CTRL_OPCODE_LL_CS_FAE_RSP" },
912 { LL_CTRL_OPCODE_LL_CS_CHANNEL_MAP_IND
, "LL_CTRL_OPCODE_LL_CS_CHANNEL_MAP_IND" },
913 { LL_CTRL_OPCODE_LL_CS_SEQ_REQ
, "LL_CTRL_OPCODE_LL_CS_SEQ_REQ" },
914 { LL_CTRL_OPCODE_LL_CS_TERMINATE_RSP
, "LL_CTRL_OPCODE_LL_CS_TERMINATE_RSP" },
915 { LL_CTRL_OPCODE_LL_FRAME_SPACE_REQ
, "LL_CTRL_OPCODE_LL_FRAME_SPACE_REQ" },
916 { LL_CTRL_OPCODE_LL_FRAME_SPACE_RSP
, "LL_CTRL_OPCODE_LL_FRAME_SPACE_RSP" },
919 static value_string_ext control_opcode_vals_ext
= VALUE_STRING_EXT_INIT(control_opcode_vals
);
921 static const value_string big_control_opcode_vals
[] = {
922 { 0x00, "BIG_CHANNEL_MAP_IND" },
923 { 0x01, "BIG_TERMINATE_IND" },
926 static value_string_ext big_control_opcode_vals_ext
= VALUE_STRING_EXT_INIT(big_control_opcode_vals
);
928 /* Taken from https://www.bluetooth.com/specifications/assigned-numbers/link-layer/ */
929 static const value_string ll_version_number_vals
[] = {
941 static value_string_ext ll_version_number_vals_ext
= VALUE_STRING_EXT_INIT(ll_version_number_vals
);
943 static const value_string advertising_mode_vals
[] = {
944 { 0x00, "Non-connectable Non-scannable" },
945 { 0x01, "Connectable Non-scannable" },
946 { 0x02, "Non-connectable Scannable"},
947 { 0x03, "Reserved for future use"},
950 static value_string_ext advertising_mode_vals_ext
= VALUE_STRING_EXT_INIT(advertising_mode_vals
);
952 static const value_string le_phys
[] =
965 static const value_string le_cte_type_vals
[] = {
966 { 0, "AoA Constant Tone Extension" },
967 { 1, "AoD Constant Tone Extension with 1 usec slots" },
968 { 2, "AoD Constant Tone Extension with 2 usec slots" },
969 { 3, "Reserved for future use" },
973 static const true_false_string tfs_ca
= {
978 static const true_false_string tfs_offset_units
= {
983 static const true_false_string tfs_offset_adjust
= {
984 "Adjusted 2.4576 seconds",
988 static const true_false_string tfs_ch_sel
= {
993 static const true_false_string tfs_random_public
= {
998 void proto_register_btle(void);
999 void proto_reg_handoff_btle(void);
1001 static bool btle_detect_retransmit
= true;
1010 * Implements Bluetooth Vol 6, Part B, Section 3.1.1 (ref Figure 3.2)
1012 * At entry: tvb is entire BTLE packet without preamble
1013 * payload_len is the Length field from the BTLE PDU header
1014 * crc_init as defined in the specifications
1016 * This implementation operates on nibbles and is therefore
1020 btle_crc(tvbuff_t
*tvb
, const uint8_t payload_len
, const uint32_t crc_init
)
1022 static const uint16_t btle_crc_next_state_flips
[256] = {
1023 0x0000, 0x32d8, 0x196c, 0x2bb4, 0x0cb6, 0x3e6e, 0x15da, 0x2702,
1024 0x065b, 0x3483, 0x1f37, 0x2def, 0x0aed, 0x3835, 0x1381, 0x2159,
1025 0x065b, 0x3483, 0x1f37, 0x2def, 0x0aed, 0x3835, 0x1381, 0x2159,
1026 0x0000, 0x32d8, 0x196c, 0x2bb4, 0x0cb6, 0x3e6e, 0x15da, 0x2702,
1027 0x0cb6, 0x3e6e, 0x15da, 0x2702, 0x0000, 0x32d8, 0x196c, 0x2bb4,
1028 0x0aed, 0x3835, 0x1381, 0x2159, 0x065b, 0x3483, 0x1f37, 0x2def,
1029 0x0aed, 0x3835, 0x1381, 0x2159, 0x065b, 0x3483, 0x1f37, 0x2def,
1030 0x0cb6, 0x3e6e, 0x15da, 0x2702, 0x0000, 0x32d8, 0x196c, 0x2bb4,
1031 0x196c, 0x2bb4, 0x0000, 0x32d8, 0x15da, 0x2702, 0x0cb6, 0x3e6e,
1032 0x1f37, 0x2def, 0x065b, 0x3483, 0x1381, 0x2159, 0x0aed, 0x3835,
1033 0x1f37, 0x2def, 0x065b, 0x3483, 0x1381, 0x2159, 0x0aed, 0x3835,
1034 0x196c, 0x2bb4, 0x0000, 0x32d8, 0x15da, 0x2702, 0x0cb6, 0x3e6e,
1035 0x15da, 0x2702, 0x0cb6, 0x3e6e, 0x196c, 0x2bb4, 0x0000, 0x32d8,
1036 0x1381, 0x2159, 0x0aed, 0x3835, 0x1f37, 0x2def, 0x065b, 0x3483,
1037 0x1381, 0x2159, 0x0aed, 0x3835, 0x1f37, 0x2def, 0x065b, 0x3483,
1038 0x15da, 0x2702, 0x0cb6, 0x3e6e, 0x196c, 0x2bb4, 0x0000, 0x32d8,
1039 0x32d8, 0x0000, 0x2bb4, 0x196c, 0x3e6e, 0x0cb6, 0x2702, 0x15da,
1040 0x3483, 0x065b, 0x2def, 0x1f37, 0x3835, 0x0aed, 0x2159, 0x1381,
1041 0x3483, 0x065b, 0x2def, 0x1f37, 0x3835, 0x0aed, 0x2159, 0x1381,
1042 0x32d8, 0x0000, 0x2bb4, 0x196c, 0x3e6e, 0x0cb6, 0x2702, 0x15da,
1043 0x3e6e, 0x0cb6, 0x2702, 0x15da, 0x32d8, 0x0000, 0x2bb4, 0x196c,
1044 0x3835, 0x0aed, 0x2159, 0x1381, 0x3483, 0x065b, 0x2def, 0x1f37,
1045 0x3835, 0x0aed, 0x2159, 0x1381, 0x3483, 0x065b, 0x2def, 0x1f37,
1046 0x3e6e, 0x0cb6, 0x2702, 0x15da, 0x32d8, 0x0000, 0x2bb4, 0x196c,
1047 0x2bb4, 0x196c, 0x32d8, 0x0000, 0x2702, 0x15da, 0x3e6e, 0x0cb6,
1048 0x2def, 0x1f37, 0x3483, 0x065b, 0x2159, 0x1381, 0x3835, 0x0aed,
1049 0x2def, 0x1f37, 0x3483, 0x065b, 0x2159, 0x1381, 0x3835, 0x0aed,
1050 0x2bb4, 0x196c, 0x32d8, 0x0000, 0x2702, 0x15da, 0x3e6e, 0x0cb6,
1051 0x2702, 0x15da, 0x3e6e, 0x0cb6, 0x2bb4, 0x196c, 0x32d8, 0x0000,
1052 0x2159, 0x1381, 0x3835, 0x0aed, 0x2def, 0x1f37, 0x3483, 0x065b,
1053 0x2159, 0x1381, 0x3835, 0x0aed, 0x2def, 0x1f37, 0x3483, 0x065b,
1054 0x2702, 0x15da, 0x3e6e, 0x0cb6, 0x2bb4, 0x196c, 0x32d8, 0x0000
1056 int offset
= 4; /* skip AA, CRC applies over PDU */
1057 uint32_t state
= crc_init
;
1058 uint8_t bytes_to_go
= 2+payload_len
; /* PDU includes header and payload */
1059 while( bytes_to_go
-- ) {
1060 uint8_t byte
= tvb_get_uint8(tvb
, offset
++);
1061 uint8_t nibble
= (byte
& 0xf);
1062 uint8_t byte_index
= ((state
>> 16) & 0xf0) | nibble
;
1063 state
= ((state
<< 4) ^ btle_crc_next_state_flips
[byte_index
]) & 0xffffff;
1064 nibble
= ((byte
>> 4) & 0xf);
1065 byte_index
= ((state
>> 16) & 0xf0) | nibble
;
1066 state
= ((state
<< 4) ^ btle_crc_next_state_flips
[byte_index
]) & 0xffffff;
1071 static const char * adv_pdu_type_str_get(const btle_context_t
*btle_context
, uint32_t pdu_type
, bool is_periodic_adv
)
1073 if (is_periodic_adv
) {
1074 return "AUX_SYNC_IND";
1075 } else if (!btle_context
|| !(btle_context
->channel
< 37)) {
1076 return val_to_str_ext_const(pdu_type
, &pdu_type_vals_ext
, "Unknown");
1077 } else if (pdu_type
== 0x07 && btle_context
->aux_pdu_type_valid
) {
1078 return val_to_str_ext_const(btle_context
->aux_pdu_type
, &aux_pdu_common_vals_ext
, "Unknown");
1080 return val_to_str_ext_const(pdu_type
, &aux_pdu_type_vals_ext
, "Unknown");
1085 * Reverses the bits in each byte of a 32-bit word.
1087 * Needed because CRCs are transmitted in bit-reversed order compared
1088 * to the rest of the BTLE packet. See BT spec, Vol 6, Part B,
1092 reverse_bits_per_byte(const uint32_t val
)
1094 static const uint8_t nibble_rev
[16] = {
1095 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
1096 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
1098 uint32_t retval
= 0;
1099 unsigned byte_index
;
1100 for (byte_index
=0; byte_index
<4; byte_index
++) {
1101 unsigned shiftA
= byte_index
*8;
1102 unsigned shiftB
= shiftA
+4;
1103 retval
|= (nibble_rev
[((val
>> shiftA
) & 0xf)] << shiftB
);
1104 retval
|= (nibble_rev
[((val
>> shiftB
) & 0xf)] << shiftA
);
1110 dissect_feature_set(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1112 proto_item
*sub_item
;
1113 proto_tree
*sub_tree
;
1115 sub_item
= proto_tree_add_item(btle_tree
, hf_control_feature_set
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1116 sub_tree
= proto_item_add_subtree(sub_item
, ett_features
);
1118 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_1
, ENC_NA
);
1121 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_2
, ENC_NA
);
1124 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_3
, ENC_NA
);
1127 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_4
, ENC_NA
);
1130 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_5
, ENC_NA
);
1133 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_6
, ENC_NA
);
1136 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_7
, ENC_NA
);
1139 proto_tree_add_bitmask_list(sub_tree
, tvb
, offset
, 1, hfx_control_feature_set_8
, ENC_NA
);
1146 dissect_conn_param_req_rsp(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1148 proto_tree_add_item(btle_tree
, hf_control_interval_min
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1151 proto_tree_add_item(btle_tree
, hf_control_interval_max
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1154 proto_tree_add_item(btle_tree
, hf_control_latency
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1157 proto_tree_add_item(btle_tree
, hf_control_timeout
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1160 proto_tree_add_item(btle_tree
, hf_control_preferred_periodicity
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1163 proto_tree_add_item(btle_tree
, hf_control_reference_connection_event_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1166 proto_tree_add_item(btle_tree
, hf_control_offset_0
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1169 proto_tree_add_item(btle_tree
, hf_control_offset_1
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1172 proto_tree_add_item(btle_tree
, hf_control_offset_2
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1175 proto_tree_add_item(btle_tree
, hf_control_offset_3
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1178 proto_tree_add_item(btle_tree
, hf_control_offset_4
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1181 proto_tree_add_item(btle_tree
, hf_control_offset_5
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1188 dissect_length_req_rsp(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1190 proto_tree_add_item(btle_tree
, hf_control_max_rx_octets
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1193 proto_tree_add_item(btle_tree
, hf_control_max_rx_time
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1196 proto_tree_add_item(btle_tree
, hf_control_max_tx_octets
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1199 proto_tree_add_item(btle_tree
, hf_control_max_tx_time
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1206 dissect_phy_req_rsp(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1208 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_tx_phys
, ett_tx_phys
, hfx_control_phys_sender
, ENC_NA
);
1211 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_rx_phys
, ett_rx_phys
, hfx_control_phys_sender
, ENC_NA
);
1218 dissect_periodic_sync_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
, packet_info
*pinfo
, uint32_t interface_id
, uint32_t adapter_id
)
1220 uint32_t sync_offset
, interval
;
1221 int reserved_offset
;
1225 proto_item
*sub_item
;
1226 proto_tree
*sub_tree
;
1229 proto_tree_add_item(btle_tree
, hf_control_sync_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1233 sf
= tvb_get_uint16(tvb
, offset
, ENC_LITTLE_ENDIAN
);
1235 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_sync_info_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &sync_offset
);
1236 proto_tree_add_item(btle_tree
, hf_control_sync_info_offset_units
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1237 proto_tree_add_item(btle_tree
, hf_control_sync_info_offset_adjust
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1238 proto_tree_add_item(btle_tree
, hf_control_sync_info_reserved
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1239 if (sync_offset
> 0) {
1240 proto_item_append_text(item
, " (%u usec)", sync_offset
* ((sf
& 0x2000) != 0 ? 300 : 30) + ((sf
& 0x4000) != 0 ? 2457600 : 0));
1242 proto_item_append_text(item
, " Cannot be represented");
1246 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_sync_info_interval
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &interval
);
1247 proto_item_append_text(item
, " (%g msec)", interval
* 1.25);
1250 sub_item
= proto_tree_add_item(btle_tree
, hf_control_sync_info_channel_map
, tvb
, offset
, 5, ENC_NA
);
1251 sub_tree
= proto_item_add_subtree(sub_item
, ett_channel_map
);
1253 call_dissector_with_data(btcommon_le_channel_map_handle
, tvb_new_subset_length(tvb
, offset
, 5), pinfo
, sub_tree
, &reserved_offset
);
1254 proto_tree_add_item(btle_tree
, hf_control_sync_info_sleep_clock_accuracy
, tvb
, reserved_offset
, 1, ENC_LITTLE_ENDIAN
);
1257 proto_tree_add_item(btle_tree
, hf_control_sync_info_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1260 proto_tree_add_item(btle_tree
, hf_control_sync_info_crc_init
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1263 proto_tree_add_item(btle_tree
, hf_control_sync_info_event_counter
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1267 proto_tree_add_item(btle_tree
, hf_control_sync_conn_event_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1270 proto_tree_add_item(btle_tree
, hf_control_sync_last_pa_event_counter
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1273 proto_tree_add_bitmask_list(btle_tree
, tvb
, offset
, 1, hfx_control_periodicsyncflags
, ENC_NA
);
1276 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_phys
, ett_phys
, hfx_control_phys
, ENC_NA
);
1279 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, bd_addr
);
1281 proto_tree_add_item(btle_tree
, hf_control_sync_sync_conn_event_counter
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1288 dissect_cis_req(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1293 proto_tree_add_item(btle_tree
, hf_control_cig_id
, tvb
, offset
, 1, ENC_NA
);
1296 proto_tree_add_item(btle_tree
, hf_control_cis_id
, tvb
, offset
, 1, ENC_NA
);
1299 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_c_to_p_phy
, ett_c_to_p_phy
, hfx_control_c_to_p_phy
, ENC_NA
);
1302 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_p_to_c_phy
, ett_p_to_c_phy
, hfx_control_p_to_c_phy
, ENC_NA
);
1305 proto_tree_add_item(btle_tree
, hf_control_max_sdu_c_to_p
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1306 proto_tree_add_item(btle_tree
, hf_control_rfu_1
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1307 proto_tree_add_item(btle_tree
, hf_control_framed
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1310 proto_tree_add_item(btle_tree
, hf_control_max_sdu_p_to_c
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1311 proto_tree_add_item(btle_tree
, hf_control_rfu_2
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1314 proto_tree_add_item(btle_tree
, hf_control_sdu_interval_c_to_p
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1315 proto_tree_add_item(btle_tree
, hf_control_rfu_3
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1318 proto_tree_add_item(btle_tree
, hf_control_sdu_interval_p_to_c
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1319 proto_tree_add_item(btle_tree
, hf_control_rfu_4
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1322 proto_tree_add_item(btle_tree
, hf_control_max_pdu_c_to_p
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1325 proto_tree_add_item(btle_tree
, hf_control_max_pdu_p_to_c
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1328 proto_tree_add_item(btle_tree
, hf_control_num_sub_events
, tvb
, offset
, 1, ENC_NA
);
1331 proto_tree_add_item(btle_tree
, hf_control_sub_interval
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1334 proto_tree_add_item(btle_tree
, hf_control_bn_c_to_p
, tvb
, offset
, 1, ENC_NA
);
1335 proto_tree_add_item(btle_tree
, hf_control_bn_p_to_c
, tvb
, offset
, 1, ENC_NA
);
1338 proto_tree_add_item(btle_tree
, hf_control_ft_c_to_p
, tvb
, offset
, 1, ENC_NA
);
1341 proto_tree_add_item(btle_tree
, hf_control_ft_p_to_c
, tvb
, offset
, 1, ENC_NA
);
1344 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_iso_interval
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &interval
);
1345 proto_item_append_text(item
, " (%g msec)", interval
* 1.25);
1348 proto_tree_add_item(btle_tree
, hf_control_cis_offset_min
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1351 proto_tree_add_item(btle_tree
, hf_control_cis_offset_max
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1354 proto_tree_add_item(btle_tree
, hf_control_conn_event_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1361 dissect_cis_rsp(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1363 proto_tree_add_item(btle_tree
, hf_control_cis_offset_min
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1366 proto_tree_add_item(btle_tree
, hf_control_cis_offset_max
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1369 proto_tree_add_item(btle_tree
, hf_control_conn_event_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1376 dissect_cis_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1378 proto_tree_add_item(btle_tree
, hf_control_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1381 proto_tree_add_item(btle_tree
, hf_control_cis_offset
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1384 proto_tree_add_item(btle_tree
, hf_control_cig_sync_delay
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1387 proto_tree_add_item(btle_tree
, hf_control_cis_sync_delay
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
1390 proto_tree_add_item(btle_tree
, hf_control_conn_event_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1397 dissect_cis_terminate_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1399 proto_tree_add_item(btle_tree
, hf_control_cig_id
, tvb
, offset
, 1, ENC_NA
);
1402 proto_tree_add_item(btle_tree
, hf_control_cis_id
, tvb
, offset
, 1, ENC_NA
);
1405 proto_tree_add_item(btle_tree
, hf_control_error_code
, tvb
, offset
, 1, ENC_NA
);
1412 dissect_power_control_req(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1414 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_pwr_phy
, ett_pwr_phy
, hfx_control_pwr_phy
, ENC_NA
);
1417 proto_tree_add_item(btle_tree
, hf_control_delta
, tvb
, offset
, 1, ENC_NA
);
1420 proto_tree_add_item(btle_tree
, hf_control_txpwr
, tvb
, offset
, 1, ENC_NA
);
1428 dissect_power_control_rsp(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1430 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_pwrflags
, ett_pwrflags
, hfx_control_pwrflags
, ENC_NA
);
1433 proto_tree_add_item(btle_tree
, hf_control_delta
, tvb
, offset
, 1, ENC_NA
);
1436 proto_tree_add_item(btle_tree
, hf_control_txpwr
, tvb
, offset
, 1, ENC_NA
);
1439 proto_tree_add_item(btle_tree
, hf_control_acceptable_power_reduction
, tvb
, offset
, 1, ENC_NA
);
1446 dissect_power_control_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1448 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_pwr_phy
, ett_pwr_phy
, hfx_control_pwr_phy
, ENC_NA
);
1451 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_pwrflags
, ett_pwrflags
, hfx_control_pwrflags
, ENC_NA
);
1454 proto_tree_add_item(btle_tree
, hf_control_delta
, tvb
, offset
, 1, ENC_NA
);
1457 proto_tree_add_item(btle_tree
, hf_control_txpwr
, tvb
, offset
, 1, ENC_NA
);
1464 dissect_subrate_req(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1466 proto_tree_add_item(btle_tree
, hf_control_subrate_factor_min
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1469 proto_tree_add_item(btle_tree
, hf_control_subrate_factor_max
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1472 proto_tree_add_item(btle_tree
, hf_control_max_latency
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1475 proto_tree_add_item(btle_tree
, hf_control_continuation_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1478 proto_tree_add_item(btle_tree
, hf_control_timeout
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1485 dissect_subrate_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1487 proto_tree_add_item(btle_tree
, hf_control_subrate_factor
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1490 proto_tree_add_item(btle_tree
, hf_control_subrate_base_event
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1493 proto_tree_add_item(btle_tree
, hf_control_latency
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1496 proto_tree_add_item(btle_tree
, hf_control_continuation_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1499 proto_tree_add_item(btle_tree
, hf_control_timeout
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1506 dissect_channel_reporting_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1508 proto_tree_add_item(btle_tree
, hf_control_channel_reporting_enable
, tvb
, offset
, 1, ENC_NA
);
1511 proto_tree_add_item(btle_tree
, hf_control_channel_reporting_min_spacing
, tvb
, offset
, 1, ENC_NA
);
1514 proto_tree_add_item(btle_tree
, hf_control_channel_reporting_max_delay
, tvb
, offset
, 1, ENC_NA
);
1521 dissect_channel_status_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
)
1523 proto_tree_add_item(btle_tree
, hf_control_channel_classification
, tvb
, offset
, 10, ENC_NA
);
1531 dissect_periodic_sync_wr_ind(tvbuff_t
*tvb
, proto_tree
*btle_tree
, int offset
, packet_info
*pinfo
, uint32_t interface_id
, uint32_t adapter_id
)
1533 /* The first part of LL_PERIODIC_SYNC_WR_IND is identical to LL_PERIODIC_SYNC_IND */
1534 offset
+= dissect_periodic_sync_ind(tvb
, btle_tree
, offset
, pinfo
, interface_id
, adapter_id
);
1536 proto_tree_add_item(btle_tree
, hf_control_sync_info_rsp_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1539 proto_tree_add_item(btle_tree
, hf_control_sync_info_num_subevents
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1542 proto_tree_add_item(btle_tree
, hf_control_sync_info_subevent_interval
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1545 proto_tree_add_item(btle_tree
, hf_control_sync_info_response_slot_delay
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1548 proto_tree_add_item(btle_tree
, hf_control_sync_info_response_slot_spacing
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1555 dissect_ctrl_pdu_without_data(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*btle_tree
, int offset
)
1557 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
1558 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
1559 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
1566 dissect_crc(tvbuff_t
*tvb
,
1567 proto_tree
*btle_tree
,
1571 const connection_info_t
*connection_info
,
1572 const btle_context_t
*btle_context
,
1573 uint32_t access_address
)
1575 /* BT spec Vol 6, Part B, Section 1.2: CRC is big endian and bits in byte are flipped */
1576 uint32_t packet_crc
= reverse_bits_per_byte(tvb_get_ntoh24(tvb
, offset
));
1577 proto_item
*sub_item
= proto_tree_add_uint(btle_tree
, hf_crc
, tvb
, offset
, 3, packet_crc
);
1579 if (btle_context
&& btle_context
->crc_checked_at_capture
) {
1580 if (!btle_context
->crc_valid_at_capture
) {
1581 expert_add_info(pinfo
, sub_item
, &ei_crc_incorrect
);
1583 } else if ((access_address
== ACCESS_ADDRESS_ADVERTISING
) || connection_info
) {
1584 /* CRC can be calculated */
1587 if (access_address
== ACCESS_ADDRESS_ADVERTISING
) {
1588 crc_init
= 0x555555;
1590 crc_init
= connection_info
->crc_init
;
1593 uint32_t crc
= btle_crc(tvb
, length
, crc_init
);
1594 if (packet_crc
!= crc
) {
1595 expert_add_info(pinfo
, sub_item
, &ei_crc_incorrect
);
1598 expert_add_info(pinfo
, sub_item
, &ei_crc_cannot_be_determined
);
1604 /* Checks if it is possible to add the frame at the given index
1605 * to the given control procedure context.
1607 * It does not care if the procedure is already marked as completed.
1608 * Therefore this function can be used to add an LL_UNKNOWN_RSP to
1609 * a completed connection parameter update procedure.
1612 control_proc_can_add_frame_even_if_complete(packet_info
*pinfo
,
1613 control_proc_info_t
*last_control_proc_info
,
1614 uint8_t proc_opcode
,
1618 return false; /* This function must be used to add a frame to an ongoing procedure */
1620 /* We need to check if the control procedure has been initiated. */
1621 if (!last_control_proc_info
)
1624 /* And that the new frame belongs to this control procedure */
1625 if (last_control_proc_info
->proc_opcode
!= proc_opcode
)
1628 /* Previous frame has not yet been added. */
1629 if (last_control_proc_info
->frames
[frame_num
- 1] == 0)
1632 /* We need to check if we can add this frame at this index
1633 * in the control procedure sequence. */
1635 /* The first time we visit the frame, we just need to check that the
1637 if (!pinfo
->fd
->visited
&& last_control_proc_info
->frames
[frame_num
])
1638 return false; /* Another opcode has already been added to the procedure at this index */
1640 /* At later visits, we need to check that we are not replacing the frame with
1642 if (pinfo
->fd
->visited
&& (last_control_proc_info
->frames
[frame_num
] != pinfo
->num
))
1649 control_proc_is_complete(uint32_t frame_num
, control_proc_info_t
const *last_control_proc_info
)
1651 if (last_control_proc_info
->last_frame
!= 0 &&
1652 frame_num
> last_control_proc_info
->last_frame
)
1659 control_proc_can_add_frame(packet_info
*pinfo
,
1660 control_proc_info_t
*last_control_proc_info
,
1661 uint8_t proc_opcode
,
1664 if (!control_proc_can_add_frame_even_if_complete(pinfo
,
1665 last_control_proc_info
,
1670 /* We check that we are not adding a frame to a completed procedure. */
1671 if (control_proc_is_complete(pinfo
->num
, last_control_proc_info
))
1678 control_proc_complete_if_instant_reached(unsigned frame_num
,
1679 uint16_t event_counter
,
1680 control_proc_info_t
*last_control_proc_info
)
1682 /* We need to check if the control procedure has been initiated. */
1683 if (!last_control_proc_info
)
1686 if (control_proc_is_complete(frame_num
, last_control_proc_info
))
1689 /* The instant can only be reached if the current frame is after
1690 * the one containing the instant value. */
1691 if ((last_control_proc_info
->frame_with_instant_value
== 0)||
1692 (frame_num
< last_control_proc_info
->frame_with_instant_value
))
1695 if (last_control_proc_info
->instant
== event_counter
) {
1696 /* Frame matches event counter, mark procedure as complete. */
1697 last_control_proc_info
->last_frame
= frame_num
;
1702 control_proc_contains_instant(uint8_t proc_opcode
)
1704 switch (proc_opcode
)
1706 case LL_CTRL_OPCODE_CONNECTION_UPDATE_IND
:
1707 case LL_CTRL_OPCODE_CHANNEL_MAP_IND
:
1708 case LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
:
1709 case LL_CTRL_OPCODE_PHY_REQ
:
1716 /* Returns true if this frame contains an collision violating the specification.
1718 * See Core_v5.2, Vol 6, Part B, Section 5.3 */
1720 control_proc_invalid_collision(packet_info
const *pinfo
,
1721 control_proc_info_t
const *control_proc_other
,
1722 uint8_t proc_opcode
)
1724 if (!control_proc_other
)
1727 if (control_proc_is_complete(pinfo
->num
, control_proc_other
))
1730 /* Both procedures must contain an instant to be marked as incompatible. */
1731 if (!control_proc_contains_instant(control_proc_other
->proc_opcode
) ||
1732 !control_proc_contains_instant(proc_opcode
))
1735 /* From the Core Spec:
1737 * If the peer has already sent at least one PDU as part of procedure A, the
1738 * device should immediately exit the Connection State and transition to the
1741 * That is, if there exists are response in the other procedure at this point in
1742 * time, there is a procedure violation.
1744 if (control_proc_other
->frames
[1] && (control_proc_other
->frames
[1] < pinfo
->num
))
1750 /* Mark the start of a new control procedure.
1751 * At first visit it will create a new control procedure context.
1752 * Otherwise it will update the existing context.
1754 * If there is already an ongoing control procedure context, control procedure
1755 * contexts will not be created or modified.
1757 * It returns the procedure context in case it exists, otherwise NULL.
1759 static control_proc_info_t
*
1760 control_proc_start(tvbuff_t
*tvb
,
1762 proto_tree
*btle_tree
,
1763 proto_item
*control_proc_item
,
1764 wmem_tree_t
*control_proc_tree
,
1765 control_proc_info_t
const *control_proc_other_direction
,
1768 if (control_proc_invalid_collision(pinfo
,
1769 control_proc_other_direction
,
1771 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_invalid_collision
);
1774 control_proc_info_t
*proc_info
;
1775 if (!pinfo
->fd
->visited
) {
1776 /* Check the if there is an existing ongoing procedure. */
1777 proc_info
= (control_proc_info_t
*)wmem_tree_lookup32_le(control_proc_tree
, pinfo
->num
);
1778 if (proc_info
&& proc_info
->last_frame
== 0) {
1779 /* Control procedure violation - initiating new procedure before previous was complete */
1782 /* Create a new control procedure context. */
1783 proc_info
= wmem_new0(wmem_file_scope(), control_proc_info_t
);
1784 memset(proc_info
, 0, sizeof(control_proc_info_t
));
1785 proc_info
->frames
[0] = pinfo
->num
;
1786 proc_info
->proc_opcode
= opcode
;
1787 wmem_tree_insert32(control_proc_tree
, pinfo
->num
, proc_info
);
1790 /* Match the responses with this request. */
1791 proc_info
= (control_proc_info_t
*)wmem_tree_lookup32(control_proc_tree
, pinfo
->num
);
1793 if (proc_info
&& proc_info
->proc_opcode
== opcode
) {
1794 proto_item
*sub_item
;
1795 for (unsigned i
= 1; i
< array_length(proc_info
->frames
); i
++) {
1796 if (proc_info
->frames
[i
]) {
1797 sub_item
= proto_tree_add_uint(btle_tree
, hf_response_in_frame
, tvb
, 0, 0, proc_info
->frames
[i
]);
1798 proto_item_set_generated(sub_item
);
1802 /* The found control procedure does not match the last one.
1803 * This indicates a protocol violation. */
1804 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_overlapping
);
1813 /* Adds a frame to a control procedure context */
1814 static void control_proc_add_frame(tvbuff_t
*tvb
,
1816 proto_tree
*btle_tree
,
1819 control_proc_info_t
*last_control_proc_info
,
1820 control_proc_info_t
const *control_proc_other_direction
,
1825 last_control_proc_info
->frames
[frame_num
] = pinfo
->num
;
1827 item
= proto_tree_add_uint(btle_tree
, hf_request_in_frame
, tvb
, 0, 0,
1828 last_control_proc_info
->frames
[0]);
1829 proto_item_set_generated(item
);
1831 if (control_proc_other_direction
&&
1832 !control_proc_is_complete(pinfo
->num
, control_proc_other_direction
) &&
1833 control_proc_contains_instant(last_control_proc_info
->proc_opcode
) &&
1834 control_proc_contains_instant(control_proc_other_direction
->proc_opcode
)) {
1835 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
&&
1836 opcode
!= LL_CTRL_OPCODE_REJECT_IND
&&
1837 opcode
!= LL_CTRL_OPCODE_REJECT_EXT_IND
) {
1838 /* Continuing a control procedure when the peer has initiated an incompatible control procedure.
1839 * The central should have aborted the peripheral initiated procedure.
1840 * See Core_V5.2, Vol 6, Part B, Section 5.3.
1842 expert_add_info(pinfo
, item
, &ei_control_proc_invalid_conflict_resolution
);
1847 /* Adds a frame to a control procedure context.
1848 * Marks this frame as the last control procedure packet. */
1849 static void control_proc_add_last_frame(tvbuff_t
*tvb
,
1851 proto_tree
*btle_tree
,
1854 control_proc_info_t
*last_control_proc_info
,
1855 control_proc_info_t
const *control_proc_other_direction
,
1858 control_proc_add_frame(tvb
,
1863 last_control_proc_info
,
1864 control_proc_other_direction
,
1866 last_control_proc_info
->last_frame
= pinfo
->num
;
1869 /* Adds a frame containing an instant to a control procedure context
1870 * Marks this frame as the last control procedure packet if the event counter is not available */
1871 static void control_proc_add_frame_with_instant(tvbuff_t
*tvb
,
1873 proto_tree
*btle_tree
,
1874 const btle_context_t
*btle_context
,
1877 control_proc_info_t
*last_control_proc_info
,
1878 control_proc_info_t
const *control_proc_other_direction
,
1882 if (btle_context
&& btle_context
->event_counter_valid
) {
1883 control_proc_add_frame(tvb
,
1888 last_control_proc_info
,
1889 control_proc_other_direction
,
1891 last_control_proc_info
->instant
= instant
;
1892 last_control_proc_info
->frame_with_instant_value
= pinfo
->num
;
1894 /* Event counter is not available, assume the procedure completes now. */
1895 control_proc_add_last_frame(tvb
,
1900 last_control_proc_info
,
1901 control_proc_other_direction
,
1907 dissect_ad_eir(tvbuff_t
*tvb
, uint32_t interface_id
, uint32_t adapter_id
, uint32_t frame_number
, uint8_t *src_bd_addr
, packet_info
*pinfo
, proto_tree
*tree
)
1909 bluetooth_eir_ad_data_t
*ad_data
= wmem_new0(pinfo
->pool
, bluetooth_eir_ad_data_t
);
1910 ad_data
->interface_id
= interface_id
;
1911 ad_data
->adapter_id
= adapter_id
;
1912 call_dissector_with_data(btcommon_ad_handle
, tvb
, pinfo
, tree
, ad_data
);
1913 if (pinfo
->fd
->visited
)
1915 for (int offset
= 0;; ) {
1916 unsigned remain
= tvb_reported_length_remaining(tvb
, offset
);
1921 length
= tvb_get_uint8(tvb
, offset
);
1926 if (remain
< length
)
1928 opcode
= tvb_get_uint8(tvb
, offset
);
1929 if (opcode
== 0x2c && length
>= 34) {
1930 unsigned seed_access_address
= tvb_get_uint32(tvb
, offset
+ 14, ENC_LITTLE_ENDIAN
);
1931 uint32_t trunc_seed_access_address
= seed_access_address
& 0x0041ffff;
1932 broadcastiso_connection_info_t
*nconnection_info
;
1933 wmem_tree_key_t key
[5];
1936 key
[0].key
= &interface_id
;
1938 key
[1].key
= &adapter_id
;
1940 key
[2].key
= &trunc_seed_access_address
;
1942 key
[3].key
= &frame_number
;
1946 nconnection_info
= wmem_new0(wmem_file_scope(), broadcastiso_connection_info_t
);
1949 memcpy(nconnection_info
->central_bd_addr
, src_bd_addr
, 6);
1951 wmem_tree_insert32_array(broadcastiso_connection_info_tree
, key
, nconnection_info
);
1958 guess_btle_pdu_type_from_access(uint32_t interface_id
,
1959 uint32_t adapter_id
,
1960 uint32_t access_address
)
1962 wmem_tree_key_t key
[5];
1963 wmem_tree_t
*wmem_tree
;
1964 uint32_t broadcast_iso_seed_access_address
= access_address
& 0x0041ffff;
1966 /* No context to provide us with physical channel pdu type, make an assumption from the access address */
1967 if (access_address
== ACCESS_ADDRESS_ADVERTISING
) {
1968 return BTLE_PDU_TYPE_ADVERTISING
;
1971 /* Check if it is a connection context. */
1973 key
[0].key
= &interface_id
;
1975 key
[1].key
= &adapter_id
;
1977 key
[2].key
= &access_address
;
1981 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(connection_info_tree
, key
);
1984 return BTLE_PDU_TYPE_DATA
;
1987 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(periodic_adv_info_tree
, key
);
1989 /* Periodic advertiser. */
1990 return BTLE_PDU_TYPE_ADVERTISING
;
1993 key
[2].key
= &broadcast_iso_seed_access_address
;
1994 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(broadcastiso_connection_info_tree
, key
);
1996 /* Broadcast ISO. */
1997 return BTLE_PDU_TYPE_BROADCASTISO
;
2000 /* Default to data. */
2001 return BTLE_PDU_TYPE_DATA
;
2004 static const btle_context_t
* get_btle_context(packet_info
*pinfo
,
2006 uint32_t *adapter_id_out
,
2007 uint32_t *interface_id_out
)
2009 const btle_context_t
* btle_context
= NULL
;
2010 bluetooth_data_t
*bluetooth_data
= NULL
;
2011 ubertooth_data_t
*ubertooth_data
= NULL
;
2013 wmem_list_frame_t
* list_data
= wmem_list_frame_prev(wmem_list_tail(pinfo
->layers
));
2015 int previous_proto
= GPOINTER_TO_INT(wmem_list_frame_data(list_data
));
2017 if ((previous_proto
== proto_btle_rf
)||(previous_proto
== proto_nordic_ble
)) {
2018 btle_context
= (const btle_context_t
*) data
;
2019 bluetooth_data
= btle_context
->previous_protocol_data
.bluetooth_data
;
2020 } else if (previous_proto
== proto_bluetooth
) {
2021 bluetooth_data
= (bluetooth_data_t
*) data
;
2024 if (bluetooth_data
&& bluetooth_data
->previous_protocol_data_type
== BT_PD_UBERTOOTH_DATA
) {
2025 ubertooth_data
= bluetooth_data
->previous_protocol_data
.ubertooth_data
;
2030 *interface_id_out
= bluetooth_data
->interface_id
;
2031 else if (pinfo
->rec
->presence_flags
& WTAP_HAS_INTERFACE_ID
)
2032 *interface_id_out
= pinfo
->rec
->rec_header
.packet_header
.interface_id
;
2034 *interface_id_out
= HCI_INTERFACE_DEFAULT
;
2037 *adapter_id_out
= ubertooth_data
->bus_id
<< 8 | ubertooth_data
->device_address
;
2038 else if (bluetooth_data
)
2039 *adapter_id_out
= bluetooth_data
->adapter_id
;
2041 *adapter_id_out
= HCI_ADAPTER_DEFAULT
;
2043 return btle_context
;
2047 dissect_btle_adv(tvbuff_t
*tvb
,
2049 proto_tree
*btle_tree
,
2050 const btle_context_t
*btle_context
,
2051 uint32_t adapter_id
,
2052 uint32_t interface_id
,
2053 uint32_t access_address
)
2055 proto_item
*sub_item
;
2056 proto_tree
*sub_tree
;
2060 uint8_t *dst_bd_addr
;
2061 uint8_t *src_bd_addr
;
2062 static const uint8_t broadcast_addr
[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2063 connection_info_t
*connection_info
= NULL
;
2064 wmem_tree_t
*wmem_tree
;
2065 wmem_tree_key_t key
[5], ae_had_key
[4];
2067 uint32_t connection_access_address
;
2070 unsigned item_value
;
2072 proto_item
*advertising_header_item
;
2073 proto_tree
*advertising_header_tree
;
2074 proto_item
*link_layer_data_item
;
2075 proto_tree
*link_layer_data_tree
;
2076 uint8_t header
, pdu_type
;
2077 bool ch_sel_valid
= false, tx_add_valid
= false, rx_add_valid
= false;
2078 bool is_periodic_adv
= false;
2080 src_bd_addr
= (uint8_t *) wmem_alloc(pinfo
->pool
, 6);
2081 dst_bd_addr
= (uint8_t *) wmem_alloc(pinfo
->pool
, 6);
2084 key
[0].key
= &interface_id
;
2086 key
[1].key
= &adapter_id
;
2088 key
[2].key
= &access_address
;
2092 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(connection_info_tree
, key
);
2094 /* Check periodic advertising tree */
2095 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(periodic_adv_info_tree
, key
);
2097 is_periodic_adv
= true;
2102 connection_info
= (connection_info_t
*) wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
2103 if (connection_info
) {
2104 set_address(&pinfo
->net_src
, AT_ETHER
, 6, connection_info
->central_bd_addr
);
2105 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2106 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2107 memcpy(src_bd_addr
, connection_info
->central_bd_addr
, 6);
2111 advertising_header_item
= proto_tree_add_item(btle_tree
, hf_advertising_header
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2112 advertising_header_tree
= proto_item_add_subtree(advertising_header_item
, ett_advertising_header
);
2114 header
= tvb_get_uint8(tvb
, offset
);
2115 pdu_type
= header
& 0x0F;
2118 case 0x00: /* ADV_IND */
2119 ch_sel_valid
= true;
2121 case 0x02: /* ADV_NONCONN_IND */
2122 case 0x06: /* ADV_SCAN_IND */
2123 case 0x04: /* SCAN_RSP */
2124 tx_add_valid
= true;
2126 case 0x07: /* ADV_EXT_IND / AUX_ADV_IND / AUX_SYNC_IND / AUX_CHAIN_IND / AUX_SCAN_RSP */
2127 case 0x08: /* AUX_CONNECT_RSP */
2128 case 0x09: /* ADV_DECISION_IND */
2130 /* 0 + header, 1 = len, 2 = ext_len/adv-mode, 3 = flags */
2131 uint8_t ext_header_flags
= tvb_get_uint8(tvb
, offset
+ 3);
2133 ch_sel_valid
= false;
2134 tx_add_valid
= (ext_header_flags
& 0x01) != 0;
2135 rx_add_valid
= (ext_header_flags
& 0x02) != 0;
2138 case 0x01: /* ADV_DIRECT_IND */
2139 case 0x05: /* CONNECT_IND or AUX_CONNECT_REQ */
2140 if (btle_context
&& btle_context
->channel
>= 37) {
2142 ch_sel_valid
= true;
2145 case 0x03: /* SCAN_REQ or AUX_SCAN_REQ */
2146 tx_add_valid
= true;
2147 rx_add_valid
= true;
2151 proto_item_append_text(advertising_header_item
, " (PDU Type: %s", adv_pdu_type_str_get(btle_context
, pdu_type
, is_periodic_adv
));
2152 item
= proto_tree_add_item(advertising_header_tree
, hf_advertising_header_pdu_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2153 proto_item_append_text(item
, " %s", adv_pdu_type_str_get(btle_context
, pdu_type
, is_periodic_adv
));
2154 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_rfu_1
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2157 proto_item_append_text(advertising_header_item
, ", ChSel: %s",
2158 tfs_get_string(header
& 0x20, &tfs_ch_sel
));
2159 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_ch_sel
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2161 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_rfu_2
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2165 proto_item_append_text(advertising_header_item
, ", TxAdd: %s",
2166 tfs_get_string(header
& 0x40, &tfs_random_public
));
2167 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_randomized_tx
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2169 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_rfu_3
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2173 proto_item_append_text(advertising_header_item
, ", RxAdd: %s",
2174 tfs_get_string(header
& 0x80, &tfs_random_public
));
2175 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_randomized_rx
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2177 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_rfu_4
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2180 proto_item_append_text(advertising_header_item
, ")");
2182 col_set_str(pinfo
->cinfo
, COL_INFO
, adv_pdu_type_str_get(btle_context
, pdu_type
, is_periodic_adv
));
2186 proto_tree_add_item(advertising_header_tree
, hf_advertising_header_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2187 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &length
);
2188 proto_item_set_hidden(item
);
2192 case 0x00: /* ADV_IND */
2193 case 0x02: /* ADV_NONCONN_IND */
2194 case 0x06: /* ADV_SCAN_IND */
2195 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, src_bd_addr
);
2197 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2198 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2199 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2201 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, broadcast_addr
);
2202 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2203 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2205 if (!pinfo
->fd
->visited
) {
2208 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2209 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2210 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2212 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2213 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2214 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2217 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
2218 next_tvb
= tvb_new_subset_length(tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
2219 dissect_ad_eir(next_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, btle_tree
);
2222 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
2225 case 0x01: /* ADV_DIRECT_IND */
2226 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, src_bd_addr
);
2227 offset
= dissect_bd_addr(hf_target_addresss
, pinfo
, btle_tree
, tvb
, offset
, false, interface_id
, adapter_id
, dst_bd_addr
);
2229 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2230 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2231 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2233 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, dst_bd_addr
);
2234 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2235 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2237 if (!pinfo
->fd
->visited
) {
2240 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2241 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2242 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2244 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2245 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2246 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2250 case 0x03: /* SCAN_REQ */
2251 offset
= dissect_bd_addr(hf_scanning_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, src_bd_addr
);
2252 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, false, interface_id
, adapter_id
, dst_bd_addr
);
2254 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2255 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2256 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2258 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, dst_bd_addr
);
2259 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2260 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2262 if (!pinfo
->fd
->visited
) {
2265 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2266 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2267 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2269 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2270 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2271 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2275 case 0x04: /* SCAN_RSP */
2276 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, src_bd_addr
);
2278 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2279 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2280 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2282 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, broadcast_addr
);
2283 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2284 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2286 if (!pinfo
->fd
->visited
) {
2289 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2290 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2291 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2293 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2294 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2295 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2298 sub_item
= proto_tree_add_item(btle_tree
, hf_scan_response_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3, ENC_NA
);
2299 sub_tree
= proto_item_add_subtree(sub_item
, ett_scan_response_data
);
2301 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
2302 next_tvb
= tvb_new_subset_length(tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
2303 dissect_ad_eir(next_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, sub_tree
);
2306 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
2309 case 0x05: /* CONNECT_IND */
2311 uint32_t connect_ind_crc_init
;
2313 offset
= dissect_bd_addr(hf_initiator_addresss
, pinfo
, btle_tree
, tvb
, offset
, false, interface_id
, adapter_id
, src_bd_addr
);
2314 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, btle_tree
, tvb
, offset
, true, interface_id
, adapter_id
, dst_bd_addr
);
2316 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2317 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2318 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2320 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, dst_bd_addr
);
2321 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2322 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2324 if (!pinfo
->fd
->visited
) {
2327 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2328 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2329 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2331 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2332 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2333 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2336 link_layer_data_item
= proto_tree_add_item(btle_tree
, hf_link_layer_data
, tvb
, offset
, 22, ENC_NA
);
2337 link_layer_data_tree
= proto_item_add_subtree(link_layer_data_item
, ett_link_layer_data
);
2339 proto_tree_add_item(link_layer_data_tree
, hf_link_layer_data_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2340 connection_access_address
= tvb_get_letohl(tvb
, offset
);
2343 proto_tree_add_item_ret_uint(link_layer_data_tree
, hf_link_layer_data_crc_init
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
, &connect_ind_crc_init
);
2346 item
= proto_tree_add_item_ret_uint(link_layer_data_tree
, hf_link_layer_data_window_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &item_value
);
2347 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
2350 item
= proto_tree_add_item_ret_uint(link_layer_data_tree
, hf_link_layer_data_window_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
2351 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
2354 item
= proto_tree_add_item_ret_uint(link_layer_data_tree
, hf_link_layer_data_interval
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
2355 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
2358 proto_tree_add_item(link_layer_data_tree
, hf_link_layer_data_latency
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2361 item
= proto_tree_add_item_ret_uint(link_layer_data_tree
, hf_link_layer_data_timeout
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
2362 proto_item_append_text(item
, " (%u msec)", item_value
*10);
2365 sub_item
= proto_tree_add_item(link_layer_data_tree
, hf_link_layer_data_channel_map
, tvb
, offset
, 5, ENC_NA
);
2366 sub_tree
= proto_item_add_subtree(sub_item
, ett_channel_map
);
2368 call_dissector(btcommon_le_channel_map_handle
, tvb_new_subset_length(tvb
, offset
, 5), pinfo
, sub_tree
);
2371 proto_tree_add_item(link_layer_data_tree
, hf_link_layer_data_hop
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2372 proto_tree_add_item(link_layer_data_tree
, hf_link_layer_data_sleep_clock_accuracy
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2375 if (!pinfo
->fd
->visited
) {
2376 connection_parameter_info_t
*connection_parameter_info
;
2379 key
[0].key
= &interface_id
;
2381 key
[1].key
= &adapter_id
;
2383 key
[2].key
= &connection_access_address
;
2385 key
[3].key
= &pinfo
->num
;
2389 connection_info
= wmem_new0(wmem_file_scope(), connection_info_t
);
2390 connection_info
->crc_init
= connect_ind_crc_init
;
2392 memcpy(connection_info
->central_bd_addr
, src_bd_addr
, 6);
2393 memcpy(connection_info
->peripheral_bd_addr
, dst_bd_addr
, 6);
2395 /* We don't create control procedure context trees for BTLE_DIR_UNKNOWN,
2396 * as the direction must be known for request/response matching. */
2397 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
=
2398 wmem_tree_new(wmem_file_scope());
2399 connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].control_procs
=
2400 wmem_tree_new(wmem_file_scope());
2402 wmem_tree_insert32_array(connection_info_tree
, key
, connection_info
);
2404 connection_parameter_info
= wmem_new0(wmem_file_scope(), connection_parameter_info_t
);
2405 connection_parameter_info
->parameters_frame
= pinfo
->num
;
2408 key
[3].key
= &pinfo
->num
;
2409 wmem_tree_insert32_array(connection_parameter_info_tree
, key
, connection_parameter_info
);
2414 case 0x07: /* ADV_EXT_IND / AUX_ADV_IND / AUX_SYNC_IND / AUX_CHAIN_IND / AUX_SCAN_RSP */
2415 case 0x08: /* AUX_CONNECT_RSP */
2416 case 0x09: /* ADV_DECISION_IND */
2418 uint8_t tmp
, ext_header_len
, flags
, acad_len
;
2419 proto_item
*ext_header_item
, *ext_flags_item
;
2420 proto_tree
*ext_header_tree
, *ext_flags_tree
;
2422 bool adi_present
= false;
2423 bool aux_pointer_present
= false;
2425 tmp
= tvb_get_uint8(tvb
, offset
);
2426 ext_header_len
= acad_len
= tmp
& 0x3F;
2428 ext_header_item
= proto_tree_add_item(btle_tree
, hf_extended_advertising_header
, tvb
, offset
, ext_header_len
+ 1, ENC_NA
);
2429 ext_header_tree
= proto_item_add_subtree(ext_header_item
, ett_extended_advertising_header
);
2431 proto_tree_add_item(ext_header_tree
, hf_extended_advertising_header_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2432 proto_tree_add_item(ext_header_tree
, hf_extended_advertising_mode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2435 if (ext_header_len
> 0) {
2436 ext_flags_item
= proto_tree_add_item(ext_header_tree
, hf_extended_advertising_flags
, tvb
, offset
, 1, ENC_NA
);
2437 ext_flags_tree
= proto_item_add_subtree(ext_flags_item
, ett_extended_advertising_flags
);
2439 proto_tree_add_bitmask_list(ext_flags_tree
, tvb
, offset
, 1, hfx_extended_advertising_flags
, ENC_NA
);
2440 flags
= tvb_get_uint8(tvb
, offset
);
2449 /* Advertiser Address */
2450 offset
= dissect_bd_addr(hf_advertising_address
, pinfo
, ext_header_tree
, tvb
, offset
, true, interface_id
, adapter_id
, src_bd_addr
);
2451 set_address(&pinfo
->net_src
, AT_ETHER
, 6, src_bd_addr
);
2452 copy_address_shallow(&pinfo
->dl_src
, &pinfo
->net_src
);
2453 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2456 } else if (!connection_info
) {
2457 const char * anon_str
= "Anonymous";
2458 clear_address(&pinfo
->dl_src
);
2459 set_address(&pinfo
->net_src
, AT_STRINGZ
, sizeof(*anon_str
), anon_str
);
2460 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2464 /* Target Address */
2465 offset
= dissect_bd_addr(hf_target_addresss
, pinfo
, ext_header_tree
, tvb
, offset
, false, interface_id
, adapter_id
, dst_bd_addr
);
2466 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, dst_bd_addr
);
2467 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2468 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2472 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, broadcast_addr
);
2473 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
2474 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2481 sub_item
= proto_tree_add_item(ext_header_tree
, hf_extended_advertising_cte_info
, tvb
, offset
, 1, ENC_NA
);
2482 sub_tree
= proto_item_add_subtree(sub_item
, ett_extended_advertising_cte_info
);
2484 item
= proto_tree_add_item_ret_uint(sub_tree
, hf_extended_advertising_cte_info_time
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &cte_time
);
2485 proto_item_append_text(item
, " (%u usec)", cte_time
* 8);
2486 proto_tree_add_item(sub_tree
, hf_extended_advertising_cte_info_rfu
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2487 proto_tree_add_item(sub_tree
, hf_extended_advertising_cte_info_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2495 sub_item
= proto_tree_add_item_ret_uint(ext_header_tree
, hf_extended_advertising_data_info
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &adi
);
2496 sub_tree
= proto_item_add_subtree(sub_item
, ett_extended_advertising_data_info
);
2498 proto_tree_add_item(sub_tree
, hf_extended_advertising_data_info_did
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2499 proto_tree_add_item(sub_tree
, hf_extended_advertising_data_info_sid
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2507 uint32_t aux_offset
;
2510 sub_item
= proto_tree_add_item(ext_header_tree
, hf_extended_advertising_aux_ptr
, tvb
, offset
, 3, ENC_NA
);
2511 sub_tree
= proto_item_add_subtree(sub_item
, ett_extended_advertising_aux_pointer
);
2513 proto_tree_add_item(sub_tree
, hf_extended_advertising_aux_ptr_channel
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2514 proto_tree_add_item(sub_tree
, hf_extended_advertising_aux_ptr_ca
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2515 proto_tree_add_item(sub_tree
, hf_extended_advertising_aux_ptr_offset_units
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2516 tmp
= tvb_get_uint8(tvb
, offset
);
2519 item
= proto_tree_add_item_ret_uint(sub_tree
, hf_extended_advertising_aux_ptr_aux_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &aux_offset
);
2520 proto_tree_add_item(sub_tree
, hf_extended_advertising_aux_ptr_aux_phy
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2521 proto_item_append_text(item
, " (%u usec)", aux_offset
* ((tmp
& 0x80) != 0 ? 300 : 30));
2523 aux_pointer_present
= true;
2529 uint32_t sync_offset
, interval
;
2530 proto_item
*sync_info_item
;
2531 proto_tree
*sync_info_tree
;
2532 int reserved_offset
;
2536 sync_info_item
= proto_tree_add_item(ext_header_tree
, hf_extended_advertising_sync_info
, tvb
, offset
, 18, ENC_NA
);
2537 sync_info_tree
= proto_item_add_subtree(sync_info_item
, ett_extended_advertising_sync_info
);
2539 if (!pinfo
->fd
->visited
) {
2540 connection_parameter_info_t
*connection_parameter_info
;
2542 connection_access_address
= tvb_get_uint32(tvb
, offset
+ 9, ENC_LITTLE_ENDIAN
);
2545 key
[0].key
= &interface_id
;
2547 key
[1].key
= &adapter_id
;
2549 key
[2].key
= &connection_access_address
;
2551 key
[3].key
= &pinfo
->num
;
2555 connection_info
= wmem_new0(wmem_file_scope(), connection_info_t
);
2558 memcpy(connection_info
->central_bd_addr
, src_bd_addr
, 6);
2560 /* We don't create control procedure context trees for BTLE_DIR_UNKNOWN,
2561 * as the direction must be known for request/response matching. */
2562 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
=
2563 wmem_tree_new(wmem_file_scope());
2564 connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].control_procs
=
2565 wmem_tree_new(wmem_file_scope());
2567 wmem_tree_insert32_array(periodic_adv_info_tree
, key
, connection_info
);
2569 connection_parameter_info
= wmem_new0(wmem_file_scope(), connection_parameter_info_t
);
2570 connection_parameter_info
->parameters_frame
= pinfo
->num
;
2573 key
[3].key
= &pinfo
->num
;
2574 wmem_tree_insert32_array(connection_parameter_info_tree
, key
, connection_parameter_info
);
2577 sf
= tvb_get_uint16(tvb
, offset
, ENC_LITTLE_ENDIAN
);
2579 item
= proto_tree_add_item_ret_uint(sync_info_tree
, hf_extended_advertising_sync_info_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &sync_offset
);
2580 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_offset_units
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2581 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_offset_adjust
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2582 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_reserved
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2583 if (sync_offset
> 0) {
2584 proto_item_append_text(item
, " (%u usec)", sync_offset
* ((sf
& 0x2000) != 0 ? 300 : 30) + ((sf
& 0x4000) != 0 ? 2457600 : 0));
2586 proto_item_append_text(item
, " Cannot be represented");
2590 item
= proto_tree_add_item_ret_uint(sync_info_tree
, hf_extended_advertising_sync_info_interval
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &interval
);
2591 proto_item_append_text(item
, " (%g msec)", interval
* 1.25);
2594 sub_item
= proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_channel_map
, tvb
, offset
, 5, ENC_NA
);
2595 sub_tree
= proto_item_add_subtree(sub_item
, ett_channel_map
);
2597 call_dissector_with_data(btcommon_le_channel_map_handle
, tvb_new_subset_length(tvb
, offset
, 5), pinfo
, sub_tree
, &reserved_offset
);
2598 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_sleep_clock_accuracy
, tvb
, offset
+ reserved_offset
, 1, ENC_LITTLE_ENDIAN
);
2601 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2604 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_crc_init
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
2607 proto_tree_add_item(sync_info_tree
, hf_extended_advertising_sync_info_event_counter
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2615 proto_tree_add_item(ext_header_tree
, hf_extended_advertising_tx_power
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2622 sub_item
= proto_tree_add_item(ext_header_tree
, hf_extended_advertising_header_acad
, tvb
, offset
, acad_len
, ENC_NA
);
2623 sub_tree
= proto_item_add_subtree(sub_item
, ett_extended_advertising_acad
);
2625 /* Additional Controller Advertising Data */
2626 next_tvb
= tvb_new_subset_length(tvb
, offset
, acad_len
);
2627 dissect_ad_eir(next_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, sub_tree
);
2631 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
2632 bool ad_processed
= false;
2634 (pdu_type
== 0x07 || pdu_type
== 0x09) &&
2635 btle_context
->aux_pdu_type_valid
) {
2636 bool ad_reassembled
= false;
2637 ae_had_info_t
*ae_had_info
= NULL
;
2639 switch (btle_context
->aux_pdu_type
) {
2640 case 0x00: /* AUX_ADV_IND */
2641 case 0x02: /* AUX_SYNC_IND */
2642 case 0x03: /* AUX_SCAN_RSP */
2643 if (aux_pointer_present
) {
2644 /* Beginning of new sequence of fragments */
2645 if (!pinfo
->fd
->visited
&& adi_present
) {
2646 ae_had_info
= wmem_new0(wmem_file_scope(), ae_had_info_t
);
2647 ae_had_info
->first_frame_num
=pinfo
->num
;
2650 /* Copy Advertiser Address to reassemble AUX_CHAIN_IND */
2651 copy_address_wmem(wmem_file_scope(), &ae_had_info
->adv_addr
, &pinfo
->src
);
2654 ae_had_key
[0].length
= 1;
2655 ae_had_key
[0].key
= &interface_id
;
2656 ae_had_key
[1].length
= 1;
2657 ae_had_key
[1].key
= &adapter_id
;
2658 ae_had_key
[2].length
= 1;
2659 ae_had_key
[2].key
= &adi
;
2660 ae_had_key
[3].length
= 0;
2661 ae_had_key
[3].key
= NULL
;
2663 wmem_tree_insert32_array(adi_to_first_frame_tree
, ae_had_key
, ae_had_info
);
2665 fragment_add_seq(&btle_ea_host_advertising_data_reassembly_table
,
2667 ae_had_info
->first_frame_num
, NULL
,
2668 ae_had_info
->fragment_counter
,
2669 tvb_captured_length_remaining(tvb
, offset
) - 3,
2670 !ad_reassembled
, 0);
2672 ae_had_info
->fragment_counter
++;
2674 ad_processed
= true;
2677 case 0x01: /* AUX_CHAIN_IND */
2678 if (!aux_pointer_present
) {
2679 /* Final fragment */
2680 ad_reassembled
= true;
2682 if (!pinfo
->fd
->visited
&& adi_present
) {
2684 ae_had_key
[0].length
= 1;
2685 ae_had_key
[0].key
= &interface_id
;
2686 ae_had_key
[1].length
= 1;
2687 ae_had_key
[1].key
= &adapter_id
;
2688 ae_had_key
[2].length
= 1;
2689 ae_had_key
[2].key
= &adi
;
2690 ae_had_key
[3].length
= 0;
2691 ae_had_key
[3].key
= NULL
;
2693 ae_had_info
= (ae_had_info_t
*) wmem_tree_lookup32_array(adi_to_first_frame_tree
, ae_had_key
);
2695 if (ae_had_info
!= NULL
) {
2696 if (!(flags
& 0x01) && (ae_had_info
->adv_addr
.len
> 0)) {
2697 /* Copy Advertiser Address from AUX_ADV_IND if not present. */
2698 copy_address_shallow(&pinfo
->src
, &ae_had_info
->adv_addr
);
2701 fragment_add_seq(&btle_ea_host_advertising_data_reassembly_table
,
2703 ae_had_info
->first_frame_num
, NULL
,
2704 ae_had_info
->fragment_counter
,
2705 tvb_captured_length_remaining(tvb
, offset
) - 3,
2706 !ad_reassembled
, 0);
2708 ae_had_info
->fragment_counter
++;
2709 if (ad_reassembled
== true) {
2710 p_add_proto_data(wmem_file_scope(), pinfo
, proto_btle
, (uint32_t)(pinfo
->curr_layer_num
) << 8, ae_had_info
);
2714 ad_processed
= true;
2717 /* This field is 2 bits long, no special action needed */
2721 if (pinfo
->fd
->visited
) {
2722 /* Host Advertising Data fragment */
2723 proto_tree_add_item(btle_tree
, hf_extended_advertising_had_fragment
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
) - 3, ENC_NA
);
2724 if (ad_reassembled
) {
2725 fragment_head
*fd_head
= NULL
;
2726 tvbuff_t
*assembled_tvb
= NULL
;
2728 ae_had_info
= (ae_had_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_btle
, (uint32_t)(pinfo
->curr_layer_num
) << 8);
2729 if (ae_had_info
!= NULL
) {
2730 col_append_str(pinfo
->cinfo
, COL_INFO
, " (EA HAD Reassembled)");
2732 if (!(flags
& 0x01) && (ae_had_info
->adv_addr
.len
> 0)) {
2733 /* Copy Advertiser Address from AUX_ADV_IND if not present. */
2734 copy_address_shallow(&pinfo
->src
, &ae_had_info
->adv_addr
);
2737 fd_head
= fragment_get(&btle_ea_host_advertising_data_reassembly_table
, pinfo
, ae_had_info
->first_frame_num
, NULL
);
2738 assembled_tvb
= process_reassembled_data(
2740 "Reassembled Host Advertising Data", fd_head
,
2741 &btle_ea_host_advertising_data_frag_items
,
2744 if (assembled_tvb
) {
2745 dissect_ad_eir(assembled_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, btle_tree
);
2750 col_append_str(pinfo
->cinfo
, COL_INFO
, " (EA HAD Fragment)");
2752 offset
+= tvb_captured_length_remaining(tvb
, offset
) - 3;
2757 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
2758 /* Host Advertising Data */
2759 next_tvb
= tvb_new_subset_length(tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
2761 if (btle_context
&& btle_context
->aux_pdu_type_valid
&& btle_context
->aux_pdu_type
== 3) {
2763 sub_item
= proto_tree_add_item(btle_tree
, hf_scan_response_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3, ENC_NA
);
2764 sub_tree
= proto_item_add_subtree(sub_item
, ett_scan_response_data
);
2766 dissect_ad_eir(next_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, sub_tree
);
2769 dissect_ad_eir(next_tvb
, interface_id
, adapter_id
, pinfo
->num
, src_bd_addr
, pinfo
, btle_tree
);
2772 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
2778 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
2779 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
2780 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
2788 dissect_btle_acl(tvbuff_t
*tvb
,
2791 proto_tree
*btle_tree
,
2792 const btle_context_t
*btle_context
,
2793 uint32_t adapter_id
,
2794 uint32_t interface_id
,
2795 uint32_t access_address
)
2797 proto_item
*sub_item
;
2798 proto_tree
*sub_tree
;
2802 connection_info_t
*connection_info
= NULL
;
2803 wmem_tree_t
*wmem_tree
;
2804 wmem_tree_key_t key
[5];
2806 uint32_t connection_access_address
;
2809 unsigned item_value
;
2811 proto_item
*data_header_item
, *seq_item
, *control_proc_item
;
2812 proto_tree
*data_header_tree
;
2815 uint8_t control_opcode
;
2816 uint32_t direction
= BTLE_DIR_UNKNOWN
;
2817 uint8_t other_direction
= BTLE_DIR_UNKNOWN
;
2819 bool add_l2cap_index
= false;
2820 bool retransmit
= false;
2821 bool cte_info_present
= false;
2823 /* Holds the last initiated control procedures for a given direction. */
2824 control_proc_info_t
*last_control_proc
[3] = {0};
2827 direction
= btle_context
->direction
;
2828 other_direction
= (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) ? BTLE_DIR_CENTRAL_PERIPHERAL
: BTLE_DIR_PERIPHERAL_CENTRAL
;
2831 btle_frame_info_t
*btle_frame_info
= NULL
;
2832 fragment_head
*frag_btl2cap_msg
= NULL
;
2833 btle_frame_info_t empty_btle_frame_info
= {0, 0, 0, 0, 0};
2836 key
[0].key
= &interface_id
;
2838 key
[1].key
= &adapter_id
;
2840 key
[2].key
= &access_address
;
2844 oct
= tvb_get_uint8(tvb
, offset
);
2845 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(connection_info_tree
, key
);
2847 connection_info
= (connection_info_t
*) wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
2848 if (connection_info
) {
2849 char *str_addr_src
, *str_addr_dst
;
2850 /* longest possible string */
2851 const size_t str_addr_len
= sizeof("Peripheral_0x12345678");
2853 str_addr_src
= (char *) wmem_alloc(pinfo
->pool
, str_addr_len
);
2854 str_addr_dst
= (char *) wmem_alloc(pinfo
->pool
, str_addr_len
);
2856 sub_item
= proto_tree_add_ether(btle_tree
, hf_central_bd_addr
, tvb
, 0, 0, connection_info
->central_bd_addr
);
2857 proto_item_set_generated(sub_item
);
2859 sub_item
= proto_tree_add_ether(btle_tree
, hf_peripheral_bd_addr
, tvb
, 0, 0, connection_info
->peripheral_bd_addr
);
2860 proto_item_set_generated(sub_item
);
2862 switch (direction
) {
2863 case BTLE_DIR_CENTRAL_PERIPHERAL
:
2864 snprintf(str_addr_src
, str_addr_len
, "Central_0x%08x", access_address
);
2865 snprintf(str_addr_dst
, str_addr_len
, "Peripheral_0x%08x", access_address
);
2866 set_address(&pinfo
->dl_src
, AT_ETHER
, sizeof(connection_info
->central_bd_addr
), connection_info
->central_bd_addr
);
2867 set_address(&pinfo
->dl_dst
, AT_ETHER
, sizeof(connection_info
->peripheral_bd_addr
), connection_info
->peripheral_bd_addr
);
2869 case BTLE_DIR_PERIPHERAL_CENTRAL
:
2870 snprintf(str_addr_src
, str_addr_len
, "Peripheral_0x%08x", access_address
);
2871 snprintf(str_addr_dst
, str_addr_len
, "Central_0x%08x", access_address
);
2872 set_address(&pinfo
->dl_src
, AT_ETHER
, sizeof(connection_info
->peripheral_bd_addr
), connection_info
->peripheral_bd_addr
);
2873 set_address(&pinfo
->dl_dst
, AT_ETHER
, sizeof(connection_info
->central_bd_addr
), connection_info
->central_bd_addr
);
2876 /* BTLE_DIR_UNKNOWN */
2877 snprintf(str_addr_src
, str_addr_len
, "Unknown_0x%08x", access_address
);
2878 snprintf(str_addr_dst
, str_addr_len
, "Unknown_0x%08x", access_address
);
2879 clear_address(&pinfo
->dl_src
);
2880 clear_address(&pinfo
->dl_dst
);
2884 set_address(&pinfo
->net_src
, AT_STRINGZ
, (int)strlen(str_addr_src
)+1, str_addr_src
);
2885 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
2887 set_address(&pinfo
->net_dst
, AT_STRINGZ
, (int)strlen(str_addr_dst
)+1, str_addr_dst
);
2888 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
2890 /* Retrieve the last initiated control procedures. */
2891 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
] =
2892 (control_proc_info_t
*)wmem_tree_lookup32_le(connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
, pinfo
->num
);
2893 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
] =
2894 (control_proc_info_t
*)wmem_tree_lookup32_le(connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].control_procs
, pinfo
->num
);
2896 if (!pinfo
->fd
->visited
&& btle_context
&& btle_context
->event_counter_valid
) {
2897 control_proc_complete_if_instant_reached(pinfo
->num
,
2898 btle_context
->event_counter
,
2899 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
]);
2900 control_proc_complete_if_instant_reached(pinfo
->num
,
2901 btle_context
->event_counter
,
2902 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
]);
2905 if (!pinfo
->fd
->visited
) {
2908 btle_frame_info
= wmem_new0(wmem_file_scope(), btle_frame_info_t
);
2909 btle_frame_info
->l2cap_index
= connection_info
->direction_info
[direction
].l2cap_index
;
2911 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
2912 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
2913 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
2915 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
2916 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
2917 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
2919 if (!connection_info
->first_data_frame_seen
) {
2920 connection_info
->first_data_frame_seen
= 1;
2921 btle_frame_info
->retransmit
= 0;
2922 btle_frame_info
->ack
= 1;
2923 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].prev_seq_num
= 0;
2924 connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].prev_seq_num
= 1;
2927 uint8_t seq_num
= !!(oct
& 0x8), next_expected_seq_num
= !!(oct
& 0x4);
2929 if (seq_num
!= connection_info
->direction_info
[direction
].prev_seq_num
) {
2930 /* SN is not equal to previous packet (in same direction) SN */
2931 btle_frame_info
->retransmit
= 0;
2933 btle_frame_info
->retransmit
= 1;
2935 connection_info
->direction_info
[direction
].prev_seq_num
= seq_num
;
2937 if (next_expected_seq_num
!= connection_info
->direction_info
[other_direction
].prev_seq_num
) {
2938 /* NESN is not equal to previous packet (in other direction) SN */
2939 btle_frame_info
->ack
= 1;
2941 btle_frame_info
->ack
= 0;
2944 p_add_proto_data(wmem_file_scope(), pinfo
, proto_btle
, pinfo
->curr_layer_num
, btle_frame_info
);
2947 /* Not the first pass */
2948 btle_frame_info
= (btle_frame_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_btle
, pinfo
->curr_layer_num
);
2953 if (btle_frame_info
== NULL
) {
2954 btle_frame_info
= &empty_btle_frame_info
;
2957 cte_info_present
= (oct
& 0x20) != 0;
2959 data_header_item
= proto_tree_add_item(btle_tree
, hf_data_header
, tvb
, offset
, (cte_info_present
) ? 3 : 2, ENC_NA
);
2960 data_header_tree
= proto_item_add_subtree(data_header_item
, ett_data_header
);
2962 proto_tree_add_item(data_header_tree
, hf_data_header_llid
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2963 seq_item
= proto_tree_add_item(data_header_tree
, hf_data_header_next_expected_sequence_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2965 if (direction
!= BTLE_DIR_UNKNOWN
) {
2966 /* Unable to check valid NESN without direction */
2967 if (btle_frame_info
->ack
== 1) {
2968 proto_item_append_text(seq_item
, " [ACK]");
2970 proto_item_append_text(seq_item
, " [Request retransmit]");
2971 expert_add_info(pinfo
, seq_item
, &ei_nack
);
2975 seq_item
= proto_tree_add_item(data_header_tree
, hf_data_header_sequence_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2977 if (direction
!= BTLE_DIR_UNKNOWN
) {
2978 /* Unable to check valid SN or retransmission without direction */
2979 if (btle_frame_info
->retransmit
== 0) {
2980 proto_item_append_text(seq_item
, " [OK]");
2983 proto_item_append_text(seq_item
, " [Retransmit]");
2984 if (btle_detect_retransmit
) {
2985 expert_add_info(pinfo
, seq_item
, &ei_retransmit
);
2993 proto_tree_add_item(data_header_tree
, hf_data_header_more_data
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2994 proto_tree_add_item(data_header_tree
, hf_data_header_cte_info_present
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2995 proto_tree_add_item(data_header_tree
, hf_data_header_rfu
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2999 proto_tree_add_item(data_header_tree
, hf_data_header_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3000 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &length
);
3001 proto_item_set_hidden(item
);
3004 if (cte_info_present
) {
3007 sub_item
= proto_tree_add_item(data_header_tree
, hf_data_header_cte_info
, tvb
, offset
, 1, ENC_NA
);
3008 sub_tree
= proto_item_add_subtree(sub_item
, ett_data_header_cte_info
);
3010 item
= proto_tree_add_item_ret_uint(sub_tree
, hf_data_header_cte_info_time
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &cte_time
);
3011 proto_item_append_text(item
, " (%u usec)", cte_time
* 8);
3012 proto_tree_add_item(sub_tree
, hf_data_header_cte_info_rfu
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3013 proto_tree_add_item(sub_tree
, hf_data_header_cte_info_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3018 case 0x01: /* Continuation fragment of an L2CAP message, or an Empty PDU */
3020 tvbuff_t
*new_tvb
= NULL
;
3022 pinfo
->fragmented
= true;
3023 if (connection_info
&& !retransmit
) {
3024 if (!pinfo
->fd
->visited
) {
3025 if (connection_info
->direction_info
[direction
].segmentation_started
== 1) {
3026 if (connection_info
->direction_info
[direction
].segment_len_rem
>= length
) {
3027 connection_info
->direction_info
[direction
].segment_len_rem
= connection_info
->direction_info
[direction
].segment_len_rem
- length
;
3030 * Missing fragment for previous L2CAP and fragment start for this.
3031 * Set more_fragments and increase l2cap_index to avoid reassembly.
3033 btle_frame_info
->more_fragments
= 1;
3034 btle_frame_info
->missing_start
= 1;
3035 btle_frame_info
->l2cap_index
= l2cap_index
;
3036 connection_info
->direction_info
[direction
].l2cap_index
= l2cap_index
;
3037 connection_info
->direction_info
[direction
].segmentation_started
= 0;
3040 if (connection_info
->direction_info
[direction
].segment_len_rem
> 0) {
3041 btle_frame_info
->more_fragments
= 1;
3044 btle_frame_info
->more_fragments
= 0;
3045 connection_info
->direction_info
[direction
].segmentation_started
= 0;
3046 connection_info
->direction_info
[direction
].segment_len_rem
= 0;
3050 * Missing fragment start.
3051 * Set more_fragments and increase l2cap_index to avoid reassembly.
3053 btle_frame_info
->more_fragments
= 1;
3054 btle_frame_info
->missing_start
= 1;
3055 btle_frame_info
->l2cap_index
= l2cap_index
;
3056 connection_info
->direction_info
[direction
].l2cap_index
= l2cap_index
;
3057 connection_info
->direction_info
[direction
].segmentation_started
= 0;
3062 add_l2cap_index
= true;
3064 frag_btl2cap_msg
= fragment_add_seq_next(&btle_l2cap_msg_reassembly_table
,
3067 btle_frame_info
->l2cap_index
, /* uint32_t ID for fragments belonging together */
3069 length
, /* Fragment length */
3070 btle_frame_info
->more_fragments
); /* More fragments */
3072 new_tvb
= process_reassembled_data(tvb
, offset
, pinfo
,
3073 "Reassembled L2CAP",
3075 &btle_l2cap_msg_frag_items
,
3081 bthci_acl_data_t
*acl_data
;
3083 col_set_str(pinfo
->cinfo
, COL_INFO
, "L2CAP Data");
3085 acl_data
= wmem_new(pinfo
->pool
, bthci_acl_data_t
);
3086 acl_data
->interface_id
= interface_id
;
3087 acl_data
->adapter_id
= adapter_id
;
3088 acl_data
->chandle
= 0; /* No connection handle at this layer */
3089 acl_data
->remote_bd_addr_oui
= 0;
3090 acl_data
->remote_bd_addr_id
= 0;
3091 acl_data
->is_btle
= true;
3092 acl_data
->is_btle_retransmit
= retransmit
;
3093 acl_data
->adapter_disconnect_in_frame
= &bluetooth_max_disconnect_in_frame
;
3094 acl_data
->disconnect_in_frame
= &bluetooth_max_disconnect_in_frame
;
3096 next_tvb
= tvb_new_subset_length(tvb
, offset
, length
);
3098 call_dissector_with_data(btl2cap_handle
, new_tvb
, pinfo
, tree
, acl_data
);
3103 col_set_str(pinfo
->cinfo
, COL_INFO
, "L2CAP Fragment");
3104 item
= proto_tree_add_item(btle_tree
, hf_l2cap_fragment
, tvb
, offset
, length
, ENC_NA
);
3105 if (btle_frame_info
->missing_start
) {
3106 expert_add_info(pinfo
, item
, &ei_missing_fragment_start
);
3111 col_set_str(pinfo
->cinfo
, COL_INFO
, "Empty PDU");
3115 case 0x02: /* Start of an L2CAP message or a complete L2CAP message with no fragmentation */
3117 unsigned l2cap_len
= tvb_get_letohs(tvb
, offset
);
3118 if (l2cap_len
+ 4 > length
) { /* L2CAP PDU Length excludes the 4 octets header */
3119 pinfo
->fragmented
= true;
3120 if (connection_info
&& !retransmit
) {
3121 if (!pinfo
->fd
->visited
) {
3122 connection_info
->direction_info
[direction
].segmentation_started
= 1;
3123 /* The first two octets in the L2CAP PDU contain the length of the entire
3124 * L2CAP PDU in octets, excluding the Length and CID fields(4 octets).
3126 connection_info
->direction_info
[direction
].segment_len_rem
= l2cap_len
+ 4 - length
;
3127 connection_info
->direction_info
[direction
].l2cap_index
= l2cap_index
;
3128 btle_frame_info
->more_fragments
= 1;
3129 btle_frame_info
->l2cap_index
= l2cap_index
;
3133 add_l2cap_index
= true;
3135 frag_btl2cap_msg
= fragment_add_seq_next(&btle_l2cap_msg_reassembly_table
,
3138 btle_frame_info
->l2cap_index
, /* uint32_t ID for fragments belonging together */
3140 length
, /* Fragment length */
3141 btle_frame_info
->more_fragments
); /* More fragments */
3143 process_reassembled_data(tvb
, offset
, pinfo
,
3144 "Reassembled L2CAP",
3146 &btle_l2cap_msg_frag_items
,
3151 col_set_str(pinfo
->cinfo
, COL_INFO
, "L2CAP Fragment Start");
3152 proto_tree_add_item(btle_tree
, hf_l2cap_fragment
, tvb
, offset
, length
, ENC_NA
);
3155 bthci_acl_data_t
*acl_data
;
3156 if (connection_info
) {
3157 /* Add a L2CAP index for completeness */
3158 if (!pinfo
->fd
->visited
) {
3159 btle_frame_info
->l2cap_index
= l2cap_index
;
3163 add_l2cap_index
= true;
3166 col_set_str(pinfo
->cinfo
, COL_INFO
, "L2CAP Data");
3168 acl_data
= wmem_new(pinfo
->pool
, bthci_acl_data_t
);
3169 acl_data
->interface_id
= interface_id
;
3170 acl_data
->adapter_id
= adapter_id
;
3171 acl_data
->chandle
= 0; /* No connection handle at this layer */
3172 acl_data
->remote_bd_addr_oui
= 0;
3173 acl_data
->remote_bd_addr_id
= 0;
3174 acl_data
->is_btle
= true;
3175 acl_data
->is_btle_retransmit
= retransmit
;
3176 acl_data
->adapter_disconnect_in_frame
= &bluetooth_max_disconnect_in_frame
;
3177 acl_data
->disconnect_in_frame
= &bluetooth_max_disconnect_in_frame
;
3179 next_tvb
= tvb_new_subset_length(tvb
, offset
, length
);
3180 call_dissector_with_data(btl2cap_handle
, next_tvb
, pinfo
, tree
, acl_data
);
3185 case 0x03: /* Control PDU */
3186 control_proc_item
= proto_tree_add_item(btle_tree
, hf_control_opcode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3187 control_opcode
= tvb_get_uint8(tvb
, offset
);
3190 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Control Opcode: %s",
3191 val_to_str_ext_const(control_opcode
, &control_opcode_vals_ext
, "Unknown"));
3193 switch (control_opcode
) {
3194 case LL_CTRL_OPCODE_CONNECTION_UPDATE_IND
:
3195 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_window_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &item_value
);
3196 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
3199 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_window_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3200 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
3203 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_interval
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3204 proto_item_append_text(item
, " (%g msec)", item_value
*1.25);
3207 proto_tree_add_item(btle_tree
, hf_control_latency
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3210 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_control_timeout
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3211 proto_item_append_text(item
, " (%u msec)", item_value
*10);
3214 proto_tree_add_item_ret_uint(btle_tree
, hf_control_instant
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3217 if (!pinfo
->fd
->visited
) {
3218 if (connection_info
) {
3219 connection_parameter_info_t
*connection_parameter_info
;
3221 connection_parameter_info
= wmem_new0(wmem_file_scope(), connection_parameter_info_t
);
3222 connection_parameter_info
->parameters_frame
= pinfo
->num
;
3224 if (btle_context
&& btle_context
->event_counter_valid
) {
3225 connection_info
->connection_parameter_update_instant
= item_value
;
3226 connection_info
->connection_parameter_update_info
= connection_parameter_info
;
3228 /* We don't have event counter information needed to determine the exact time the new
3229 * connection parameters will be applied.
3230 * Instead just set it as active immediately.
3233 key
[0].key
= &interface_id
;
3235 key
[1].key
= &adapter_id
;
3237 key
[2].key
= &access_address
;
3239 key
[3].key
= &pinfo
->num
;
3242 wmem_tree_insert32_array(connection_parameter_info_tree
, key
, connection_parameter_info
);
3247 if (connection_info
&& !btle_frame_info
->retransmit
) {
3248 /* The LL_CONNECTION_UPDATE_IND can only be sent from central to peripheral.
3249 * It can either be sent as the first packet of the connection update procedure,
3250 * or as the last packet in the connection parameter request procedure. */
3251 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3252 if (control_proc_can_add_frame(pinfo
,
3253 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3254 LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
, 2)) {
3255 control_proc_add_last_frame(tvb
,
3260 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3261 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3263 } else if (control_proc_can_add_frame(pinfo
,
3264 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3265 LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
, 1)) {
3266 control_proc_add_last_frame(tvb
,
3271 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3272 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3275 control_proc_info_t
*proc_info
;
3276 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3277 connection_info
->direction_info
[direction
].control_procs
,
3278 last_control_proc
[other_direction
],
3282 if (btle_context
&& btle_context
->event_counter_valid
) {
3283 proc_info
->instant
= item_value
;
3284 proc_info
->frame_with_instant_value
= pinfo
->num
;
3286 /* Event counter is not available, assume the procedure completes now. */
3287 proc_info
->last_frame
= pinfo
->num
;
3292 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3293 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3298 case LL_CTRL_OPCODE_CHANNEL_MAP_IND
:
3299 sub_item
= proto_tree_add_item(btle_tree
, hf_control_channel_map
, tvb
, offset
, 5, ENC_NA
);
3300 sub_tree
= proto_item_add_subtree(sub_item
, ett_channel_map
);
3302 call_dissector(btcommon_le_channel_map_handle
, tvb_new_subset_length(tvb
, offset
, 5), pinfo
, sub_tree
);
3305 proto_tree_add_item_ret_uint(btle_tree
, hf_control_instant
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3308 if (connection_info
&& !btle_frame_info
->retransmit
) {
3309 /* The LL_CHANNEL_MAP_REQ can only be sent from central to peripheral.
3310 * It can either be sent as the first packet of the channel map update procedure,
3311 * or as the last packet in the minimum number of used channels procedure. */
3312 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3313 if (control_proc_can_add_frame(pinfo
,
3314 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3315 LL_CTRL_OPCODE_MIN_USED_CHANNELS_IND
, 1)) {
3316 control_proc_add_frame_with_instant(tvb
,
3322 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3323 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3327 control_proc_info_t
*proc_info
;
3328 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3329 connection_info
->direction_info
[direction
].control_procs
,
3330 last_control_proc
[other_direction
],
3334 if (btle_context
&& btle_context
->event_counter_valid
) {
3335 proc_info
->instant
= item_value
;
3336 proc_info
->frame_with_instant_value
= pinfo
->num
;
3338 /* Event counter is not available, assume the procedure completes now. */
3339 proc_info
->last_frame
= pinfo
->num
;
3343 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3344 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3349 case LL_CTRL_OPCODE_TERMINATE_IND
:
3350 proto_tree_add_item(btle_tree
, hf_control_error_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3353 /* No need to mark procedure as started, as the procedure only consist
3354 * of one packet which may be sent at any time, */
3357 case LL_CTRL_OPCODE_ENC_REQ
:
3358 proto_tree_add_item(btle_tree
, hf_control_random_number
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
3361 proto_tree_add_item(btle_tree
, hf_control_encrypted_diversifier
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3364 proto_tree_add_item(btle_tree
, hf_control_central_session_key_diversifier
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
3367 proto_tree_add_item(btle_tree
, hf_control_central_session_initialization_vector
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
3370 if (connection_info
&& !btle_frame_info
->retransmit
) {
3371 /* The LL_ENC_REQ can only be sent from central to peripheral. */
3372 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3373 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3374 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
3375 last_control_proc
[other_direction
],
3377 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3378 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3383 case LL_CTRL_OPCODE_ENC_RSP
:
3384 proto_tree_add_item(btle_tree
, hf_control_peripheral_session_key_diversifier
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
3387 proto_tree_add_item(btle_tree
, hf_control_peripheral_session_initialization_vector
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
3390 if (connection_info
&& !btle_frame_info
->retransmit
) {
3391 /* The LL_ENC_REQ can only be sent from peripheral to central. */
3392 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3393 if (control_proc_can_add_frame(pinfo
,
3394 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3395 LL_CTRL_OPCODE_ENC_REQ
, 1)) {
3396 control_proc_add_frame(tvb
,
3401 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3402 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3405 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3407 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3408 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3413 case LL_CTRL_OPCODE_START_ENC_REQ
:
3414 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
3415 if (connection_info
&& !btle_frame_info
->retransmit
) {
3416 /* The LL_START_ENC_REQ can only be sent from peripheral to central. */
3417 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3418 if (control_proc_can_add_frame(pinfo
,
3419 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3420 LL_CTRL_OPCODE_ENC_REQ
, 2)) {
3421 control_proc_add_frame(tvb
,
3426 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3427 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3430 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3432 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3433 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3439 case LL_CTRL_OPCODE_START_ENC_RSP
:
3440 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
3441 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3442 /* This is either frame 4 or 5 of the procedure */
3443 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
&&
3444 control_proc_can_add_frame(pinfo
,
3445 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3446 LL_CTRL_OPCODE_ENC_REQ
, 3)) {
3447 control_proc_add_frame(tvb
,
3452 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3453 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3455 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
&&
3456 control_proc_can_add_frame(pinfo
,
3457 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3458 LL_CTRL_OPCODE_ENC_REQ
, 4)) {
3459 control_proc_add_last_frame(tvb
,
3464 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3465 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3468 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3474 case LL_CTRL_OPCODE_UNKNOWN_RSP
:
3475 proto_tree_add_item(btle_tree
, hf_control_unknown_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3478 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3479 /* LL_UNKNOWN_RSP can only be sent as the second frame of a procedure. */
3480 if (last_control_proc
[other_direction
] &&
3481 control_proc_can_add_frame_even_if_complete(pinfo
,
3482 last_control_proc
[other_direction
],
3483 last_control_proc
[other_direction
]->proc_opcode
,
3485 control_proc_add_last_frame(tvb
,
3490 last_control_proc
[other_direction
],
3491 last_control_proc
[direction
],
3494 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3499 case LL_CTRL_OPCODE_FEATURE_REQ
:
3500 offset
= dissect_feature_set(tvb
, btle_tree
, offset
);
3501 if (connection_info
&& !btle_frame_info
->retransmit
) {
3502 /* The LL_FEATURE_REQ can only be sent from central to peripheral. */
3503 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3504 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3505 connection_info
->direction_info
[direction
].control_procs
,
3506 last_control_proc
[other_direction
],
3508 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3509 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3514 case LL_CTRL_OPCODE_FEATURE_RSP
:
3515 offset
= dissect_feature_set(tvb
, btle_tree
, offset
);
3516 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3517 if (control_proc_can_add_frame(pinfo
,
3518 last_control_proc
[other_direction
],
3519 LL_CTRL_OPCODE_FEATURE_REQ
, 1) ||
3520 control_proc_can_add_frame(pinfo
,
3521 last_control_proc
[other_direction
],
3522 LL_CTRL_OPCODE_PERIPHERAL_FEATURE_REQ
, 1)) {
3523 control_proc_add_last_frame(tvb
,
3528 last_control_proc
[other_direction
],
3529 last_control_proc
[direction
],
3532 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3537 case LL_CTRL_OPCODE_PAUSE_ENC_REQ
:
3538 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
3539 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
3540 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
3543 if (connection_info
&& !btle_frame_info
->retransmit
) {
3544 /* The LL_PAUSE_ENC_REQ can only be sent from central to peripheral. */
3545 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3546 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3547 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
3548 last_control_proc
[other_direction
],
3550 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3551 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3556 case LL_CTRL_OPCODE_PAUSE_ENC_RSP
:
3557 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
3559 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3560 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
&&
3561 control_proc_can_add_frame(pinfo
,
3562 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3563 LL_CTRL_OPCODE_PAUSE_ENC_REQ
, 1)) {
3564 control_proc_add_frame(tvb
,
3569 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3570 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3572 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
&&
3573 control_proc_can_add_frame(pinfo
,
3574 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3575 LL_CTRL_OPCODE_PAUSE_ENC_REQ
, 2)) {
3576 control_proc_add_last_frame(tvb
,
3581 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3582 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3585 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3590 case LL_CTRL_OPCODE_VERSION_IND
:
3591 proto_tree_add_item(btle_tree
, hf_control_version_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3594 proto_tree_add_item(btle_tree
, hf_control_company_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3597 proto_tree_add_item(btle_tree
, hf_control_subversion_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3600 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3601 /* The LL_VERSION_IND can be sent as a request or response.
3602 * We first check if it is a response. */
3603 if (control_proc_can_add_frame(pinfo
,
3604 last_control_proc
[other_direction
],
3605 LL_CTRL_OPCODE_VERSION_IND
, 1)) {
3606 control_proc_add_last_frame(tvb
,
3611 last_control_proc
[other_direction
],
3612 last_control_proc
[direction
],
3615 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3616 connection_info
->direction_info
[direction
].control_procs
,
3617 last_control_proc
[other_direction
],
3623 case LL_CTRL_OPCODE_REJECT_IND
:
3624 proto_tree_add_item(btle_tree
, hf_control_error_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3627 /* LL_REJECT_IND my be sent as:
3628 * - A response to the LL_ENQ_REQ from the central
3629 * - After the LL_ENC_RSP from the peripheral */
3630 if (connection_info
&& !btle_frame_info
->retransmit
) {
3631 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3632 if (control_proc_can_add_frame(pinfo
,
3633 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3634 LL_CTRL_OPCODE_ENC_REQ
, 1)) {
3635 control_proc_add_last_frame(tvb
,
3640 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3641 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3643 } else if (control_proc_can_add_frame(pinfo
,
3644 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3645 LL_CTRL_OPCODE_ENC_REQ
, 2)) {
3646 control_proc_add_last_frame(tvb
,
3651 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3652 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3655 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3657 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3658 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3663 case LL_CTRL_OPCODE_PERIPHERAL_FEATURE_REQ
:
3664 offset
= dissect_feature_set(tvb
, btle_tree
, offset
);
3665 if (connection_info
&& !btle_frame_info
->retransmit
) {
3666 /* The LL_PERIPHERAL_FEATURE_REQ can only be sent from peripheral to central. */
3667 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3668 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3669 connection_info
->direction_info
[direction
].control_procs
,
3670 last_control_proc
[other_direction
],
3672 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3673 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3678 case LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
:
3679 offset
= dissect_conn_param_req_rsp(tvb
, btle_tree
, offset
);
3680 if (connection_info
&& !btle_frame_info
->retransmit
) {
3681 if (direction
!= BTLE_DIR_UNKNOWN
) {
3682 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3683 connection_info
->direction_info
[direction
].control_procs
,
3684 last_control_proc
[other_direction
],
3690 case LL_CTRL_OPCODE_CONNECTION_PARAM_RSP
:
3691 offset
= dissect_conn_param_req_rsp(tvb
, btle_tree
, offset
);
3693 if (connection_info
&& !btle_frame_info
->retransmit
) {
3694 /* The LL_CONNECTION_PARAM_RSP can only be sent from peripheral to central
3695 * as a response to a central initiated procedure */
3696 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3697 if (control_proc_can_add_frame(pinfo
,
3698 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3699 LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
, 1)) {
3700 control_proc_add_frame(tvb
,
3705 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3706 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3709 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3711 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3712 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3717 case LL_CTRL_OPCODE_REJECT_EXT_IND
:
3718 proto_tree_add_item(btle_tree
, hf_control_reject_opcode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3721 proto_tree_add_item(btle_tree
, hf_control_error_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3724 /* LL_REJECT_EXT_IND my be sent as:
3725 * - A response to the LL_ENQ_REQ from the central
3726 * - After the LL_ENC_RSP from the peripheral
3727 * - As a response to LL_CONNECTION_PARAM_REQ
3728 * - As a response to LL_CONNECTION_PARAM_RSP
3729 * - As a response during the phy update procedure.
3730 * - As a response during the CTE request procedure.
3731 * - As a response to LL_CIS_REQ
3732 * - As a response to LL_CIS_RSP
3733 * - As a response to LL_POWER_CONTROL_REQ
3734 * - As a response to a LL_SUBRATE_REQ
3736 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3737 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
&&
3738 control_proc_can_add_frame(pinfo
,
3739 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3740 LL_CTRL_OPCODE_ENC_REQ
, 1)) {
3741 control_proc_add_last_frame(tvb
,
3746 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3747 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3749 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
&&
3750 control_proc_can_add_frame(pinfo
,
3751 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3752 LL_CTRL_OPCODE_ENC_REQ
, 2)) {
3753 control_proc_add_last_frame(tvb
,
3758 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3759 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3761 } else if (control_proc_can_add_frame(pinfo
,
3762 last_control_proc
[other_direction
],
3763 LL_CTRL_OPCODE_CONNECTION_PARAM_REQ
, 1)) {
3764 control_proc_add_last_frame(tvb
,
3769 last_control_proc
[other_direction
],
3770 last_control_proc
[direction
],
3772 } else if (control_proc_can_add_frame(pinfo
,
3773 last_control_proc
[other_direction
],
3774 LL_CTRL_OPCODE_PHY_REQ
, 1)) {
3775 control_proc_add_last_frame(tvb
,
3780 last_control_proc
[other_direction
],
3781 last_control_proc
[direction
],
3783 } else if (control_proc_can_add_frame(pinfo
,
3784 last_control_proc
[other_direction
],
3785 LL_CTRL_OPCODE_CTE_REQ
, 1)) {
3786 control_proc_add_last_frame(tvb
,
3791 last_control_proc
[other_direction
],
3792 last_control_proc
[direction
],
3794 } else if (control_proc_can_add_frame(pinfo
,
3795 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3796 LL_CTRL_OPCODE_CIS_REQ
, 1)) {
3797 control_proc_add_last_frame(tvb
,
3802 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3803 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3805 } else if (control_proc_can_add_frame(pinfo
,
3806 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3807 LL_CTRL_OPCODE_CIS_REQ
, 2)) {
3808 control_proc_add_last_frame(tvb
,
3813 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3814 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3816 } else if (control_proc_can_add_frame(pinfo
,
3817 last_control_proc
[other_direction
],
3818 LL_CTRL_OPCODE_POWER_CONTROL_REQ
, 1)) {
3819 control_proc_add_last_frame(tvb
,
3824 last_control_proc
[other_direction
],
3825 last_control_proc
[direction
],
3827 } else if (control_proc_can_add_frame(pinfo
,
3828 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3829 LL_CTRL_OPCODE_SUBRATE_REQ
, 1)) {
3830 control_proc_add_last_frame(tvb
,
3835 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3836 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3839 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3844 case LL_CTRL_OPCODE_PING_REQ
:
3845 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
3846 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3847 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3848 connection_info
->direction_info
[direction
].control_procs
,
3849 last_control_proc
[other_direction
],
3853 case LL_CTRL_OPCODE_PING_RSP
:
3854 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
3855 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3856 if (control_proc_can_add_frame(pinfo
,
3857 last_control_proc
[other_direction
],
3858 LL_CTRL_OPCODE_PING_REQ
, 1)) {
3859 control_proc_add_last_frame(tvb
,
3864 last_control_proc
[other_direction
],
3865 last_control_proc
[direction
],
3868 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3873 case LL_CTRL_OPCODE_LENGTH_REQ
:
3874 dissect_length_req_rsp(tvb
, btle_tree
, offset
);
3875 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3876 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3877 connection_info
->direction_info
[direction
].control_procs
,
3878 last_control_proc
[other_direction
],
3883 case LL_CTRL_OPCODE_LENGTH_RSP
:
3884 dissect_length_req_rsp(tvb
, btle_tree
, offset
);
3885 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3886 if (control_proc_can_add_frame(pinfo
,
3887 last_control_proc
[other_direction
],
3888 LL_CTRL_OPCODE_LENGTH_REQ
, 1)) {
3889 control_proc_add_last_frame(tvb
,
3894 last_control_proc
[other_direction
],
3895 last_control_proc
[direction
],
3898 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3902 case LL_CTRL_OPCODE_PHY_REQ
:
3903 dissect_phy_req_rsp(tvb
, btle_tree
, offset
);
3904 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
3905 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
3906 connection_info
->direction_info
[direction
].control_procs
,
3907 last_control_proc
[other_direction
],
3912 case LL_CTRL_OPCODE_PHY_RSP
:
3913 dissect_phy_req_rsp(tvb
, btle_tree
, offset
);
3914 if (connection_info
&& !btle_frame_info
->retransmit
) {
3915 /* The LL_PHY_RSP can only be sent from peripheral to central. */
3916 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3917 if (control_proc_can_add_frame(pinfo
,
3918 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3919 LL_CTRL_OPCODE_PHY_REQ
, 1)) {
3920 control_proc_add_frame(tvb
,
3925 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3926 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3929 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3931 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3932 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3937 case LL_CTRL_OPCODE_PHY_UPDATE_IND
:
3939 uint64_t phy_c_to_p
, phy_p_to_c
;
3941 item
= proto_tree_add_bitmask_ret_uint64(btle_tree
, tvb
, offset
, hf_control_c_to_p_phy
, ett_c_to_p_phy
, hfx_control_phys_update
, ENC_NA
, &phy_c_to_p
);
3942 if (phy_c_to_p
== 0) {
3943 proto_item_append_text(item
, ", No change");
3947 item
= proto_tree_add_bitmask_ret_uint64(btle_tree
, tvb
, offset
, hf_control_p_to_c_phy
, ett_p_to_c_phy
, hfx_control_phys_update
, ENC_NA
, &phy_p_to_c
);
3948 if (phy_p_to_c
== 0) {
3949 proto_item_append_text(item
, ", No change");
3953 if (phy_c_to_p
!= 0 && phy_p_to_c
!= 0) {
3954 proto_tree_add_item_ret_uint(btle_tree
, hf_control_instant
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
3956 /* If both the PHY_C_TO_P and PHY_P_TO_C fields are zero then there is no
3957 * Instant and the Instant field is reserved for future use.
3959 proto_tree_add_item(btle_tree
, hf_control_rfu_5
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3963 if (connection_info
&& !btle_frame_info
->retransmit
) {
3964 /* The LL_PHY_UPDATE_IND can only be sent from central to peripheral. */
3965 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
3966 if (control_proc_can_add_frame(pinfo
,
3967 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3968 LL_CTRL_OPCODE_PHY_REQ
, 2)) {
3969 control_proc_add_frame_with_instant(tvb
,
3975 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3976 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3979 } else if (control_proc_can_add_frame(pinfo
,
3980 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3981 LL_CTRL_OPCODE_PHY_REQ
, 1)){
3982 control_proc_add_frame_with_instant(tvb
,
3988 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
3989 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
3993 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
3995 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
3996 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4002 case LL_CTRL_OPCODE_MIN_USED_CHANNELS_IND
:
4003 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_phys
, ett_phys
, hfx_control_phys
, ENC_NA
);
4006 proto_tree_add_item(btle_tree
, hf_control_min_used_channels
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4009 if (connection_info
&& !btle_frame_info
->retransmit
) {
4010 /* The LL_MIN_USED_CHANNELS_IND can only be sent from peripheral to central. */
4011 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4012 control_proc_info_t
*proc_info
;
4013 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4014 connection_info
->direction_info
[direction
].control_procs
,
4015 last_control_proc
[other_direction
],
4018 /* Procedure completes in the same frame. */
4020 proc_info
->last_frame
= pinfo
->num
;
4022 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4023 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4027 case LL_CTRL_OPCODE_CTE_REQ
:
4028 proto_tree_add_bitmask(btle_tree
, tvb
, offset
, hf_control_phys
, ett_cte
, hfx_control_cte
, ENC_NA
);
4030 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4031 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4032 connection_info
->direction_info
[direction
].control_procs
,
4033 last_control_proc
[other_direction
],
4037 case LL_CTRL_OPCODE_CTE_RSP
:
4038 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
4039 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4040 if (control_proc_can_add_frame(pinfo
,
4041 last_control_proc
[other_direction
],
4042 LL_CTRL_OPCODE_CTE_REQ
, 1)) {
4043 control_proc_add_last_frame(tvb
,
4048 last_control_proc
[other_direction
],
4049 last_control_proc
[direction
],
4052 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4056 case LL_CTRL_OPCODE_PERIODIC_SYNC_IND
:
4057 offset
= dissect_periodic_sync_ind(tvb
, btle_tree
, offset
, pinfo
, interface_id
, adapter_id
);
4058 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4059 control_proc_info_t
*proc_info
;
4060 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4061 connection_info
->direction_info
[direction
].control_procs
,
4062 last_control_proc
[other_direction
],
4065 /* Procedure completes in the same frame. */
4067 proc_info
->last_frame
= pinfo
->num
;
4071 case LL_CTRL_OPCODE_CLOCK_ACCURACY_REQ
:
4072 proto_tree_add_item(btle_tree
, hf_control_sleep_clock_accuracy
, tvb
, offset
, 1, ENC_NA
);
4074 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4075 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4076 connection_info
->direction_info
[direction
].control_procs
,
4077 last_control_proc
[other_direction
],
4081 case LL_CTRL_OPCODE_CLOCK_ACCURACY_RSP
:
4082 proto_tree_add_item(btle_tree
, hf_control_sleep_clock_accuracy
, tvb
, offset
, 1, ENC_NA
);
4084 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4085 if (control_proc_can_add_frame(pinfo
,
4086 last_control_proc
[other_direction
],
4087 LL_CTRL_OPCODE_CLOCK_ACCURACY_REQ
, 1)) {
4088 control_proc_add_last_frame(tvb
,
4093 last_control_proc
[other_direction
],
4094 last_control_proc
[direction
],
4097 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4101 case LL_CTRL_OPCODE_CIS_REQ
:
4102 offset
= dissect_cis_req(tvb
, btle_tree
, offset
);
4103 if (connection_info
&& !btle_frame_info
->retransmit
) {
4104 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4105 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4106 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
4107 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4109 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4110 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4114 case LL_CTRL_OPCODE_CIS_RSP
:
4115 offset
= dissect_cis_rsp(tvb
, btle_tree
, offset
);
4116 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4117 if (control_proc_can_add_frame(pinfo
,
4118 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4119 LL_CTRL_OPCODE_CIS_REQ
, 1)) {
4120 control_proc_add_frame(tvb
,
4125 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4126 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4129 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4133 case LL_CTRL_OPCODE_CIS_IND
:
4134 if (!pinfo
->fd
->visited
) {
4135 connectediso_connection_info_t
*nconnection_info
;
4137 connection_access_address
= tvb_get_uint32(tvb
, offset
, ENC_LITTLE_ENDIAN
);
4140 key
[0].key
= &interface_id
;
4142 key
[1].key
= &adapter_id
;
4144 key
[2].key
= &connection_access_address
;
4146 key
[3].key
= &pinfo
->num
;
4150 nconnection_info
= wmem_new0(wmem_file_scope(), connectediso_connection_info_t
);
4151 if (connection_info
) {
4152 memcpy(nconnection_info
->central_bd_addr
, connection_info
->central_bd_addr
, 6);
4153 memcpy(nconnection_info
->peripheral_bd_addr
, connection_info
->peripheral_bd_addr
, 6);
4156 wmem_tree_insert32_array(connectediso_connection_info_tree
, key
, nconnection_info
);
4158 offset
= dissect_cis_ind(tvb
, btle_tree
, offset
);
4159 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4160 if (control_proc_can_add_frame(pinfo
,
4161 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4162 LL_CTRL_OPCODE_CIS_REQ
, 2)) {
4163 control_proc_add_last_frame(tvb
,
4168 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4169 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4172 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4176 case LL_CTRL_OPCODE_CIS_TERMINATE_IND
:
4177 offset
= dissect_cis_terminate_ind(tvb
, btle_tree
, offset
);
4178 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4179 control_proc_info_t
*proc_info
;
4180 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4181 connection_info
->direction_info
[direction
].control_procs
,
4182 last_control_proc
[other_direction
],
4185 /* Procedure completes in the same frame. */
4187 proc_info
->last_frame
= pinfo
->num
;
4191 case LL_CTRL_OPCODE_POWER_CONTROL_REQ
:
4192 offset
= dissect_power_control_req(tvb
, btle_tree
, offset
);
4193 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4194 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4195 connection_info
->direction_info
[direction
].control_procs
,
4196 last_control_proc
[other_direction
],
4200 case LL_CTRL_OPCODE_POWER_CONTROL_RSP
:
4201 offset
= dissect_power_control_rsp(tvb
, btle_tree
, offset
);
4202 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4203 if (control_proc_can_add_frame(pinfo
,
4204 last_control_proc
[other_direction
],
4205 LL_CTRL_OPCODE_POWER_CONTROL_REQ
, 1)) {
4206 control_proc_add_last_frame(tvb
,
4211 last_control_proc
[other_direction
],
4212 last_control_proc
[direction
],
4215 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4219 case LL_CTRL_OPCODE_POWER_CHANGE_IND
:
4220 offset
= dissect_power_control_ind(tvb
, btle_tree
, offset
);
4221 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4222 control_proc_info_t
*proc_info
;
4223 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4224 connection_info
->direction_info
[direction
].control_procs
,
4225 last_control_proc
[other_direction
],
4228 /* Procedure completes in the same frame. */
4230 proc_info
->last_frame
= pinfo
->num
;
4234 case LL_CTRL_OPCODE_SUBRATE_REQ
:
4235 offset
= dissect_subrate_req(tvb
, btle_tree
, offset
);
4236 if (connection_info
&& !btle_frame_info
->retransmit
) {
4237 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4238 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4239 connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].control_procs
,
4240 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4242 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4243 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4247 case LL_CTRL_OPCODE_SUBRATE_IND
:
4248 offset
= dissect_subrate_ind(tvb
, btle_tree
, offset
);
4249 if (connection_info
&& !btle_frame_info
->retransmit
) {
4250 if (control_proc_can_add_frame(pinfo
,
4251 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4252 LL_CTRL_OPCODE_SUBRATE_REQ
, 1)) {
4253 control_proc_add_last_frame(tvb
,
4258 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4259 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4261 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4262 control_proc_info_t
*proc_info
;
4263 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4264 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
4265 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4268 /* Procedure completes in the same frame. */
4270 proc_info
->last_frame
= pinfo
->num
;
4273 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4277 case LL_CTRL_OPCODE_CHANNEL_REPORTING_IND
:
4278 offset
= dissect_channel_reporting_ind(tvb
, btle_tree
, offset
);
4279 if (connection_info
&& !btle_frame_info
->retransmit
) {
4280 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4281 control_proc_info_t
*proc_info
;
4282 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4283 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
4284 last_control_proc
[BTLE_DIR_PERIPHERAL_CENTRAL
],
4287 /* Procedure completes in the same frame. */
4289 proc_info
->last_frame
= pinfo
->num
;
4291 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4292 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4296 case LL_CTRL_OPCODE_CHANNEL_STATUS_IND
:
4297 offset
= dissect_channel_status_ind(tvb
, btle_tree
, offset
);
4298 if (connection_info
&& !btle_frame_info
->retransmit
) {
4299 if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4300 control_proc_info_t
*proc_info
;
4301 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4302 connection_info
->direction_info
[BTLE_DIR_PERIPHERAL_CENTRAL
].control_procs
,
4303 last_control_proc
[BTLE_DIR_CENTRAL_PERIPHERAL
],
4306 /* Procedure completes in the same frame. */
4308 proc_info
->last_frame
= pinfo
->num
;
4310 } else if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4311 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4315 case LL_CTRL_OPCODE_PERIODIC_SYNC_WR_IND
:
4316 offset
= dissect_periodic_sync_wr_ind(tvb
, btle_tree
, offset
, pinfo
, interface_id
, adapter_id
);
4317 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4318 control_proc_info_t
*proc_info
;
4319 proc_info
= control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4320 connection_info
->direction_info
[direction
].control_procs
,
4321 last_control_proc
[other_direction
],
4324 /* Procedure completes in the same frame. */
4326 proc_info
->last_frame
= pinfo
->num
;
4330 case LL_CTRL_OPCODE_LL_FEATURE_EXT_REQ
:
4331 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4332 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4333 connection_info
->direction_info
[direction
].control_procs
,
4334 last_control_proc
[other_direction
],
4338 case LL_CTRL_OPCODE_LL_FEATURE_EXT_RSP
:
4339 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4340 if (control_proc_can_add_frame(pinfo
,
4341 last_control_proc
[other_direction
],
4342 LL_CTRL_OPCODE_LL_FEATURE_EXT_REQ
, 1)) {
4343 control_proc_add_last_frame(tvb
,
4348 last_control_proc
[other_direction
],
4349 last_control_proc
[direction
],
4352 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4356 case LL_CTRL_OPCODE_LL_CS_SEQ_REQ
:
4357 if (connection_info
&& !btle_frame_info
->retransmit
) {
4358 /* The LL_CTRL_OPCODE_LL_CS_SEQ_REQ can only be sent from central to peripheral. */
4359 if (direction
== BTLE_DIR_CENTRAL_PERIPHERAL
) {
4360 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4361 connection_info
->direction_info
[BTLE_DIR_CENTRAL_PERIPHERAL
].control_procs
,
4362 last_control_proc
[other_direction
],
4364 } else if (direction
== BTLE_DIR_PERIPHERAL_CENTRAL
) {
4365 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4369 case LL_CTRL_OPCODE_LL_CS_SEC_RSP
:
4370 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4371 if (control_proc_can_add_frame(pinfo
,
4372 last_control_proc
[other_direction
],
4373 LL_CTRL_OPCODE_LL_CS_SEQ_REQ
, 1)) {
4374 control_proc_add_last_frame(tvb
,
4379 last_control_proc
[other_direction
],
4380 last_control_proc
[direction
],
4383 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4387 case LL_CTRL_OPCODE_LL_CS_CAPABILITIES_REQ
:
4388 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4389 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4390 connection_info
->direction_info
[direction
].control_procs
,
4391 last_control_proc
[other_direction
],
4395 case LL_CTRL_OPCODE_LL_CS_CAPABILITIES_RSP
:
4396 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4397 if (control_proc_can_add_frame(pinfo
,
4398 last_control_proc
[other_direction
],
4399 LL_CTRL_OPCODE_LL_CS_CAPABILITIES_REQ
, 1)) {
4400 control_proc_add_last_frame(tvb
,
4405 last_control_proc
[other_direction
],
4406 last_control_proc
[direction
],
4409 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4413 case LL_CTRL_OPCODE_LL_CS_CONFIG_REQ
:
4414 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4415 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4416 connection_info
->direction_info
[direction
].control_procs
,
4417 last_control_proc
[other_direction
],
4421 case LL_CTRL_OPCODE_LL_CS_CONFIG_RSP
:
4422 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4423 if (control_proc_can_add_frame(pinfo
,
4424 last_control_proc
[other_direction
],
4425 LL_CTRL_OPCODE_LL_CS_CONFIG_REQ
, 1)) {
4426 control_proc_add_last_frame(tvb
,
4431 last_control_proc
[other_direction
],
4432 last_control_proc
[direction
],
4435 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4439 case LL_CTRL_OPCODE_LL_CS_REQ
:
4440 case LL_CTRL_OPCODE_LL_CS_RSP
:
4441 case LL_CTRL_OPCODE_LL_CS_IND
:
4442 /* TODO: Parse channel sounding start procedure PDUs and
4443 * procedure termination. */
4445 case LL_CTRL_OPCODE_LL_CS_TERMINATE_REQ
:
4446 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4447 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4448 connection_info
->direction_info
[direction
].control_procs
,
4449 last_control_proc
[other_direction
],
4453 case LL_CTRL_OPCODE_LL_CS_TERMINATE_RSP
:
4454 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4455 if (control_proc_can_add_frame(pinfo
,
4456 last_control_proc
[other_direction
],
4457 LL_CTRL_OPCODE_LL_CS_TERMINATE_REQ
, 1)) {
4458 control_proc_add_last_frame(tvb
,
4463 last_control_proc
[other_direction
],
4464 last_control_proc
[direction
],
4467 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4471 case LL_CTRL_OPCODE_LL_CS_FAE_REQ
:
4472 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4473 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4474 connection_info
->direction_info
[direction
].control_procs
,
4475 last_control_proc
[other_direction
],
4479 case LL_CTRL_OPCODE_LL_CS_FAE_RSP
:
4480 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4481 if (control_proc_can_add_frame(pinfo
,
4482 last_control_proc
[other_direction
],
4483 LL_CTRL_OPCODE_LL_CS_FAE_REQ
, 1)) {
4484 control_proc_add_last_frame(tvb
,
4489 last_control_proc
[other_direction
],
4490 last_control_proc
[direction
],
4493 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4497 case LL_CTRL_OPCODE_LL_CS_CHANNEL_MAP_IND
:
4498 /* TODO: Parse Channel Sounding Channel Map Update procedu PDU
4499 * and procedure termination. */
4500 case LL_CTRL_OPCODE_LL_FRAME_SPACE_REQ
:
4501 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4502 control_proc_start(tvb
, pinfo
, btle_tree
, control_proc_item
,
4503 connection_info
->direction_info
[direction
].control_procs
,
4504 last_control_proc
[other_direction
],
4508 case LL_CTRL_OPCODE_LL_FRAME_SPACE_RSP
:
4509 if (connection_info
&& !btle_frame_info
->retransmit
&& direction
!= BTLE_DIR_UNKNOWN
) {
4510 if (control_proc_can_add_frame(pinfo
,
4511 last_control_proc
[other_direction
],
4512 LL_CTRL_OPCODE_LL_FRAME_SPACE_REQ
, 1)) {
4513 control_proc_add_last_frame(tvb
,
4518 last_control_proc
[other_direction
],
4519 last_control_proc
[direction
],
4522 expert_add_info(pinfo
, control_proc_item
, &ei_control_proc_wrong_seq
);
4527 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
4534 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
4535 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
4536 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
4540 if (add_l2cap_index
) {
4541 item
= proto_tree_add_uint(btle_tree
, hf_l2cap_index
, tvb
, 0, 0, btle_frame_info
->l2cap_index
);
4542 proto_item_set_generated(item
);
4546 key
[0].key
= &interface_id
;
4548 key
[1].key
= &adapter_id
;
4550 key
[2].key
= &access_address
;
4553 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(connection_parameter_info_tree
, key
);
4555 connection_parameter_info_t
*connection_parameter_info
;
4557 if (connection_info
&& connection_info
->connection_parameter_update_info
!= NULL
&&
4558 btle_context
&& btle_context
->event_counter_valid
) {
4559 if ( ((int16_t)btle_context
->event_counter
- connection_info
->connection_parameter_update_instant
) >= 0) {
4560 wmem_tree_insert32(wmem_tree
, pinfo
->num
, connection_info
->connection_parameter_update_info
);
4561 connection_info
->connection_parameter_update_info
= NULL
;
4565 connection_parameter_info
= (connection_parameter_info_t
*) wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
4566 if (connection_parameter_info
) {
4567 item
= proto_tree_add_uint(btle_tree
, hf_connection_parameters_in
, tvb
, 0, 0, connection_parameter_info
->parameters_frame
);
4568 proto_item_set_generated(item
);
4577 dissect_btle_connected_iso(tvbuff_t
*tvb
,
4579 proto_tree
*btle_tree
,
4580 const btle_context_t
*btle_context
,
4581 uint32_t adapter_id
,
4582 uint32_t interface_id
,
4583 uint32_t access_address
)
4585 proto_item
*sub_item
;
4588 connectediso_connection_info_t
*connection_info
= NULL
;
4589 wmem_tree_t
*wmem_tree
;
4590 wmem_tree_key_t key
[5];
4594 proto_item
*data_header_item
;
4595 proto_tree
*data_header_tree
;
4598 uint32_t direction
= BTLE_DIR_UNKNOWN
;
4601 direction
= btle_context
->direction
;
4604 btle_frame_info_t
*btle_frame_info
= NULL
;
4607 key
[0].key
= &interface_id
;
4609 key
[1].key
= &adapter_id
;
4611 key
[2].key
= &access_address
;
4615 oct
= tvb_get_uint8(tvb
, offset
);
4616 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(connection_info_tree
, key
);
4618 connection_info
= (connectediso_connection_info_t
*) wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
4619 if (connection_info
) {
4620 char *str_addr_src
, *str_addr_dst
;
4621 /* longest possible string */
4622 const size_t str_addr_len
= sizeof("Peripheral_0x12345678");
4624 str_addr_src
= (char *) wmem_alloc(pinfo
->pool
, str_addr_len
);
4625 str_addr_dst
= (char *) wmem_alloc(pinfo
->pool
, str_addr_len
);
4627 sub_item
= proto_tree_add_ether(btle_tree
, hf_central_bd_addr
, tvb
, 0, 0, connection_info
->central_bd_addr
);
4628 proto_item_set_generated(sub_item
);
4630 sub_item
= proto_tree_add_ether(btle_tree
, hf_peripheral_bd_addr
, tvb
, 0, 0, connection_info
->peripheral_bd_addr
);
4631 proto_item_set_generated(sub_item
);
4633 switch (direction
) {
4634 case BTLE_DIR_CENTRAL_PERIPHERAL
:
4635 snprintf(str_addr_src
, str_addr_len
, "Central_0x%08x", access_address
);
4636 snprintf(str_addr_dst
, str_addr_len
, "Peripheral_0x%08x", access_address
);
4637 set_address(&pinfo
->dl_src
, AT_ETHER
, sizeof(connection_info
->central_bd_addr
), connection_info
->central_bd_addr
);
4638 set_address(&pinfo
->dl_dst
, AT_ETHER
, sizeof(connection_info
->peripheral_bd_addr
), connection_info
->peripheral_bd_addr
);
4640 case BTLE_DIR_PERIPHERAL_CENTRAL
:
4641 snprintf(str_addr_src
, str_addr_len
, "Peripheral_0x%08x", access_address
);
4642 snprintf(str_addr_dst
, str_addr_len
, "Central_0x%08x", access_address
);
4643 set_address(&pinfo
->dl_src
, AT_ETHER
, sizeof(connection_info
->peripheral_bd_addr
), connection_info
->peripheral_bd_addr
);
4644 set_address(&pinfo
->dl_dst
, AT_ETHER
, sizeof(connection_info
->central_bd_addr
), connection_info
->central_bd_addr
);
4647 /* BTLE_DIR_UNKNOWN */
4648 snprintf(str_addr_src
, str_addr_len
, "Unknown_0x%08x", access_address
);
4649 snprintf(str_addr_dst
, str_addr_len
, "Unknown_0x%08x", access_address
);
4650 clear_address(&pinfo
->dl_src
);
4651 clear_address(&pinfo
->dl_dst
);
4655 set_address(&pinfo
->net_src
, AT_STRINGZ
, (int)strlen(str_addr_src
)+1, str_addr_src
);
4656 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
4658 set_address(&pinfo
->net_dst
, AT_STRINGZ
, (int)strlen(str_addr_dst
)+1, str_addr_dst
);
4659 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
4661 if (!pinfo
->fd
->visited
) {
4664 btle_frame_info
= wmem_new0(wmem_file_scope(), btle_frame_info_t
);
4666 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
4667 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
4668 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
4670 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_dst
, sizeof(address
));
4671 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_dst
.data
, pinfo
->dl_dst
.len
);
4672 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_DST
, addr
);
4673 p_add_proto_data(wmem_file_scope(), pinfo
, proto_btle
, pinfo
->curr_layer_num
, btle_frame_info
);
4678 data_header_item
= proto_tree_add_item(btle_tree
, hf_data_header
, tvb
, offset
, 2, ENC_NA
);
4679 data_header_tree
= proto_item_add_subtree(data_header_item
, ett_data_header
);
4681 proto_tree_add_item(data_header_tree
, hf_data_header_llid_connectediso
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4682 proto_tree_add_item(data_header_tree
, hf_data_header_next_expected_sequence_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4683 proto_tree_add_item(data_header_tree
, hf_data_header_sequence_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4686 proto_tree_add_item(data_header_tree
, hf_data_header_close_isochronous_event
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4687 proto_tree_add_item(data_header_tree
, hf_data_header_null_pdu_indicator
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4688 proto_tree_add_item(data_header_tree
, hf_data_header_rfu_57
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4692 proto_tree_add_item(data_header_tree
, hf_data_header_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4693 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &length
);
4694 proto_item_set_hidden(item
);
4698 case 0x00: /* Unframed CIS Data PDU; end fragment of an SDU or a complete SDU */
4699 case 0x01: /* Unframed CIS Data PDU; start or continuation fragment of an SDU */
4700 case 0x02: /* Framed CIS Data PDU; one or more segments of an SDU */
4701 proto_tree_add_item(btle_tree
, hf_isochronous_data
, tvb
, offset
, length
, ENC_NA
);
4706 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
4707 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
4708 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
4717 dissect_btle_broadcast_iso(tvbuff_t
*tvb
,
4719 proto_tree
*btle_tree
,
4720 uint32_t adapter_id
,
4721 uint32_t interface_id
,
4722 uint32_t access_address
)
4724 proto_item
*sub_item
;
4725 proto_tree
*sub_tree
;
4728 static const uint8_t broadcast_addr
[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
4729 wmem_tree_t
*wmem_tree
;
4730 wmem_tree_key_t key
[5];
4733 unsigned item_value
;
4735 broadcastiso_connection_info_t
*broadcastiso_connection_info
= NULL
;
4736 uint32_t seed_access_address
= access_address
& 0x0041ffff;
4737 proto_item
*data_header_item
;
4738 proto_tree
*data_header_tree
;
4740 uint8_t control_opcode
;
4743 key
[0].key
= &interface_id
;
4745 key
[1].key
= &adapter_id
;
4747 key
[2].key
= &seed_access_address
;
4751 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(broadcastiso_connection_info_tree
, key
);
4753 broadcastiso_connection_info
= (broadcastiso_connection_info_t
*) wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
4754 if (broadcastiso_connection_info
) {
4756 /* longest possible string */
4757 const size_t str_addr_len
= sizeof("Central_0x12345678");
4759 str_addr_src
= (char *) wmem_alloc(pinfo
->pool
, str_addr_len
);
4761 sub_item
= proto_tree_add_ether(btle_tree
, hf_central_bd_addr
, tvb
, 0, 0, broadcastiso_connection_info
->central_bd_addr
);
4762 proto_item_set_generated(sub_item
);
4764 snprintf(str_addr_src
, str_addr_len
, "Central_0x%08x", access_address
);
4765 set_address(&pinfo
->dl_src
, AT_ETHER
, sizeof(broadcastiso_connection_info
->central_bd_addr
), broadcastiso_connection_info
->central_bd_addr
);
4766 clear_address(&pinfo
->dl_dst
);
4768 set_address(&pinfo
->net_src
, AT_STRINGZ
, (int)strlen(str_addr_src
)+1, str_addr_src
);
4769 copy_address_shallow(&pinfo
->src
, &pinfo
->net_src
);
4771 if (!pinfo
->fd
->visited
) {
4774 addr
= (address
*) wmem_memdup(wmem_file_scope(), &pinfo
->dl_src
, sizeof(address
));
4775 addr
->data
= wmem_memdup(wmem_file_scope(), pinfo
->dl_src
.data
, pinfo
->dl_src
.len
);
4776 p_add_proto_data(wmem_file_scope(), pinfo
, proto_bluetooth
, BLUETOOTH_DATA_SRC
, addr
);
4781 set_address(&pinfo
->net_dst
, AT_ETHER
, 6, broadcast_addr
);
4782 copy_address_shallow(&pinfo
->dl_dst
, &pinfo
->net_dst
);
4783 copy_address_shallow(&pinfo
->dst
, &pinfo
->net_dst
);
4785 data_header_item
= proto_tree_add_item(btle_tree
, hf_data_header
, tvb
, offset
, 2, ENC_NA
);
4786 data_header_tree
= proto_item_add_subtree(data_header_item
, ett_data_header
);
4788 proto_tree_add_item(data_header_tree
, hf_data_header_llid_broadcastiso
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4789 llid
= tvb_get_uint8(tvb
, offset
) & 0x03;
4790 proto_tree_add_item(data_header_tree
, hf_data_header_control_subevent_sequence_number
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4791 proto_tree_add_item(data_header_tree
, hf_data_header_control_subevent_transmission_flag
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4792 proto_tree_add_item(data_header_tree
, hf_data_header_rfu_67
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4795 proto_tree_add_item(data_header_tree
, hf_data_header_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4796 item
= proto_tree_add_item_ret_uint(btle_tree
, hf_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &length
);
4797 proto_item_set_hidden(item
);
4801 case 0x00: /* Unframed BIS Data PDU; end fragment of an SDU or a complete SDU */
4802 case 0x01: /* Unframed BIS Data PDU; start or continuation fragment of an SDU */
4803 case 0x02: /* Framed BIS Data PDU; one or more segments of an SDU */
4804 proto_tree_add_item(btle_tree
, hf_isochronous_data
, tvb
, offset
, length
, ENC_NA
);
4808 case 0x03: /* BIG Control PDU */
4809 proto_tree_add_item(btle_tree
, hf_big_control_opcode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4810 control_opcode
= tvb_get_uint8(tvb
, offset
);
4813 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "BIG Control Opcode: %s",
4814 val_to_str_ext_const(control_opcode
, &big_control_opcode_vals_ext
, "Unknown"));
4816 switch (control_opcode
) {
4817 case 0x00: /* BIG_CHANNEL_MAP_IND */
4818 sub_item
= proto_tree_add_item(btle_tree
, hf_control_channel_map
, tvb
, offset
, 5, ENC_NA
);
4819 sub_tree
= proto_item_add_subtree(sub_item
, ett_channel_map
);
4821 call_dissector(btcommon_le_channel_map_handle
, tvb_new_subset_length(tvb
, offset
, 5), pinfo
, sub_tree
);
4824 proto_tree_add_item_ret_uint(btle_tree
, hf_control_instant
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
4828 case 0x01: /* BIG_TERMINATE_IND */
4829 proto_tree_add_item(btle_tree
, hf_control_error_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4831 proto_tree_add_item_ret_uint(btle_tree
, hf_control_instant
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_value
);
4836 offset
= dissect_ctrl_pdu_without_data(tvb
, pinfo
, btle_tree
, offset
);
4842 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
4843 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
4844 offset
+= tvb_reported_length_remaining(tvb
, offset
) - 3;
4852 dissect_btle(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4854 proto_item
*btle_item
;
4855 proto_tree
*btle_tree
;
4856 proto_item
*sub_item
;
4858 uint32_t access_address
, length
;
4860 connection_info_t
*connection_info
= NULL
;
4862 uint8_t btle_pdu_type
= BTLE_PDU_TYPE_UNKNOWN
;
4864 uint32_t interface_id
;
4865 uint32_t adapter_id
;
4866 const btle_context_t
*btle_context
= get_btle_context(pinfo
,
4871 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "LE LL");
4873 btle_item
= proto_tree_add_item(tree
, proto_btle
, tvb
, offset
, -1, ENC_NA
);
4874 btle_tree
= proto_item_add_subtree(btle_item
, ett_btle
);
4876 sub_item
= proto_tree_add_item(btle_tree
, hf_access_address
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4877 access_address
= tvb_get_letohl(tvb
, offset
);
4879 switch(btle_context
->aa_category
) {
4881 expert_add_info(pinfo
, sub_item
, &ei_access_address_matched
);
4884 expert_add_info(pinfo
, sub_item
, &ei_access_address_illegal
);
4886 case E_AA_BIT_ERRORS
:
4887 expert_add_info(pinfo
, sub_item
, &ei_access_address_bit_errors
);
4895 if (btle_context
&& btle_context
->phy
== LE_CODED_PHY
) {
4896 proto_tree_add_item(btle_tree
, hf_coding_indicator
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4901 btle_pdu_type
= btle_context
->pdu_type
;
4904 if (btle_pdu_type
== BTLE_PDU_TYPE_UNKNOWN
) {
4905 /* No context to provide us with physical channel pdu type, make an assumption from the access address */
4906 btle_pdu_type
= guess_btle_pdu_type_from_access(interface_id
,
4911 if (btle_pdu_type
== BTLE_PDU_TYPE_ADVERTISING
) {
4912 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
4913 length
= dissect_btle_adv(next_tvb
,
4919 access_address
) - 2;
4920 offset
+= length
+ 2;
4921 } else if (btle_pdu_type
== BTLE_PDU_TYPE_DATA
) {
4922 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
4923 length
= dissect_btle_acl(next_tvb
,
4930 access_address
) - 2;
4931 offset
+= length
+ 2;
4932 } else if (btle_pdu_type
== BTLE_PDU_TYPE_CONNECTEDISO
) {
4933 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
4934 length
= dissect_btle_connected_iso(next_tvb
,
4940 access_address
) - 2;
4941 offset
+= length
+ 2;
4942 } else if (btle_pdu_type
== BTLE_PDU_TYPE_BROADCASTISO
) {
4943 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
4944 length
= dissect_btle_broadcast_iso(next_tvb
,
4949 access_address
) - 2;
4950 offset
+= length
+ 2;
4952 /* Unknown physical channel PDU type. Assume CRC size is 3 bytes */
4953 if (tvb_reported_length_remaining(tvb
, offset
) > 3) {
4954 proto_tree_add_expert(btle_tree
, pinfo
, &ei_unknown_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
) - 3);
4955 length
= tvb_reported_length_remaining(tvb
, offset
) - 3;
4958 /* Length is unknown. */
4963 offset
+= dissect_crc(tvb
,
4976 proto_register_btle(void)
4979 expert_module_t
*expert_module
;
4981 static hf_register_info hf
[] = {
4982 { &hf_access_address
,
4983 { "Access Address", "btle.access_address",
4984 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
4987 { &hf_coding_indicator
,
4988 { "Coding Indicator", "btle.coding_indicator",
4989 FT_UINT8
, BASE_DEC
, VALS(le_coding_indicators
), 0x3,
4992 { &hf_central_bd_addr
,
4993 { "Central Address", "btle.central_bd_addr",
4994 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
4997 { &hf_peripheral_bd_addr
,
4998 { "Peripheral Address", "btle.peripheral_bd_addr",
4999 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
5003 { "Length", "btle.length",
5004 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5007 { &hf_advertising_header
,
5008 { "Packet Header", "btle.advertising_header",
5009 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5012 { &hf_advertising_header_pdu_type
,
5013 { "PDU Type", "btle.advertising_header.pdu_type",
5014 FT_UINT8
, BASE_HEX
, NULL
, 0x0F,
5017 { &hf_advertising_header_rfu_1
,
5018 { "Reserved", "btle.advertising_header.rfu.1",
5019 FT_UINT8
, BASE_DEC
, NULL
, 0x10,
5020 "Reserved for Future Use", HFILL
}
5022 { &hf_advertising_header_ch_sel
,
5023 { "Channel Selection Algorithm", "btle.advertising_header.ch_sel",
5024 FT_BOOLEAN
, 8, TFS(&tfs_ch_sel
), 0x20,
5027 { &hf_advertising_header_rfu_2
,
5028 { "Reserved", "btle.advertising_header.rfu.2",
5029 FT_UINT8
, BASE_DEC
, NULL
, 0x20,
5030 "Reserved for Future Use", HFILL
}
5032 { &hf_advertising_header_randomized_tx
,
5033 { "Tx Address", "btle.advertising_header.randomized_tx",
5034 FT_BOOLEAN
, 8, TFS(&tfs_random_public
), 0x40,
5037 { &hf_advertising_header_rfu_3
,
5038 { "Reserved", "btle.advertising_header.rfu.3",
5039 FT_UINT8
, BASE_DEC
, NULL
, 0x40,
5040 "Reserved for Future Use", HFILL
}
5042 { &hf_advertising_header_randomized_rx
,
5043 { "Rx Address", "btle.advertising_header.randomized_rx",
5044 FT_BOOLEAN
, 8, TFS(&tfs_random_public
), 0x80,
5047 { &hf_advertising_header_rfu_4
,
5048 { "Reserved", "btle.advertising_header.rfu.4",
5049 FT_UINT8
, BASE_DEC
, NULL
, 0x80,
5050 "Reserved for Future Use", HFILL
}
5052 { &hf_advertising_header_length
,
5053 { "Length", "btle.advertising_header.length",
5054 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5057 { &hf_advertising_address
,
5058 { "Advertising Address", "btle.advertising_address",
5059 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
5062 { &hf_initiator_addresss
,
5063 { "Initiator Address", "btle.initiator_address",
5064 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
5067 { &hf_target_addresss
,
5068 { "Target Address", "btle.target_address",
5069 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
5072 { &hf_scanning_address
,
5073 { "Scanning Address", "btle.scanning_address",
5074 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
5077 { &hf_scan_response_data
,
5078 { "Scan Response Data", "btle.scan_response_data",
5079 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5082 { &hf_link_layer_data
,
5083 { "Link Layer Data", "btle.link_layer_data",
5084 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5087 { &hf_link_layer_data_access_address
,
5088 { "Access Address", "btle.link_layer_data.access_address",
5089 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5092 { &hf_link_layer_data_crc_init
,
5093 { "CRC Init", "btle.link_layer_data.crc_init",
5094 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
5097 { &hf_link_layer_data_window_size
,
5098 { "Window Size", "btle.link_layer_data.window_size",
5099 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5102 { &hf_link_layer_data_window_offset
,
5103 { "Window Offset", "btle.link_layer_data.window_offset",
5104 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5107 { &hf_link_layer_data_interval
,
5108 { "Interval", "btle.link_layer_data.interval",
5109 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5112 { &hf_link_layer_data_latency
,
5113 { "Latency", "btle.link_layer_data.latency",
5114 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5117 { &hf_link_layer_data_timeout
,
5118 { "Timeout", "btle.link_layer_data.timeout",
5119 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5122 { &hf_link_layer_data_channel_map
,
5123 { "Channel Map", "btle.link_layer_data.channel_map",
5124 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5127 { &hf_link_layer_data_hop
,
5128 { "Hop", "btle.link_layer_data.hop",
5129 FT_UINT8
, BASE_DEC
, NULL
, 0x1f,
5132 { &hf_link_layer_data_sleep_clock_accuracy
,
5133 { "Sleep Clock Accuracy", "btle.link_layer_data.sleep_clock_accuracy",
5134 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &sleep_clock_accuracy_vals_ext
, 0xe0,
5137 { &hf_extended_advertising_header
,
5138 { "Extended Advertising Header", "btle.extended_advertising_header",
5139 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5142 { &hf_extended_advertising_header_length
,
5143 { "Extended Header Length", "btle.extended_advertising_header.length",
5144 FT_UINT8
, BASE_DEC
, NULL
, 0x3F,
5147 { &hf_extended_advertising_mode
,
5148 { "Advertising Mode", "btle.extended_advertising_header.mode",
5149 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &advertising_mode_vals_ext
, 0xC0,
5152 { &hf_extended_advertising_flags
,
5153 { "Extended Header Flags", "btle.extended_advertising_header.flags",
5154 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5157 { &hf_extended_advertising_flags_adva
,
5158 { "Advertiser Address", "btle.extended_advertising_header.flags.advertiser_address",
5159 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x01,
5162 { &hf_extended_advertising_flags_targeta
,
5163 { "Target Address", "btle.extended_advertising_header.flags.target_address",
5164 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x02,
5167 { &hf_extended_advertising_flags_cte_info
,
5168 { "CTE Info", "btle.extended_advertising_header.flags.cte_info",
5169 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x04,
5172 { &hf_extended_advertising_flags_advdatainfo
,
5173 { "Advertiser Data Info", "btle.extended_advertising_header.advertiser_data_info",
5174 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x08,
5177 { &hf_extended_advertising_flags_aux_ptr
,
5178 { "Aux pointer", "btle.extended_advertising_header.flags.aux_pointer",
5179 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x10,
5182 { &hf_extended_advertising_flags_sync_info
,
5183 { "Sync Info", "btle.extended_advertising_header.flags.sync_info",
5184 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x20,
5187 { &hf_extended_advertising_flags_tx_power
,
5188 { "TX Power", "btle.extended_advertising_header.flags.tx_power",
5189 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x40,
5192 { &hf_extended_advertising_flags_reserved
,
5193 { "Reserved", "btle.extended_advertising_header.flags.reserved",
5194 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x80,
5197 { &hf_extended_advertising_cte_info
,
5198 { "CTE Info", "btle.extended_advertising_header.cte_info",
5199 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5202 { &hf_extended_advertising_cte_info_time
,
5203 { "CTE Time", "btle.extended_advertising_header.cte_info.time",
5204 FT_UINT8
, BASE_HEX
, NULL
, 0x1F,
5207 { &hf_extended_advertising_cte_info_rfu
,
5208 { "RFU", "btle.extended_advertising_header.cte_info.rfu",
5209 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
5212 { &hf_extended_advertising_cte_info_type
,
5213 { "CTE Type", "btle.extended_advertising_header.cte_info.type",
5214 FT_UINT8
, BASE_HEX
, VALS(le_cte_type_vals
), 0xC0,
5217 { &hf_extended_advertising_data_info
,
5218 { "Advertiser Data Info", "btle.extended_advertising.advertising_data_info",
5219 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5222 { &hf_extended_advertising_data_info_did
,
5223 { "Advertiser Data Identifier", "btle.extended_advertising.advertising_data_info.did",
5224 FT_UINT16
, BASE_HEX
, NULL
, 0x0FFF,
5227 { &hf_extended_advertising_data_info_sid
,
5228 { "Advertiser Set Identifier", "btle.extended_advertising.advertising_data_info.sid",
5229 FT_UINT16
, BASE_HEX
, NULL
, 0xF000,
5232 { &hf_extended_advertising_aux_ptr
,
5233 { "Advertiser Aux Pointer", "btle.extended_advertising.aux_pointer",
5234 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5237 { &hf_extended_advertising_aux_ptr_channel
,
5238 { "Channel Index", "btle.extended_advertising_header.aux_pointer.channel",
5239 FT_UINT8
, BASE_DEC
, NULL
, 0x3F,
5242 { &hf_extended_advertising_aux_ptr_ca
,
5243 { "Clock Accuracy", "btle.extended_advertising_header.aux_pointer.ca",
5244 FT_BOOLEAN
, 8, TFS(&tfs_ca
), 0x40,
5247 { &hf_extended_advertising_aux_ptr_offset_units
,
5248 { "Offset units", "btle.extended_advertising_header.aux_pointer.offset_units",
5249 FT_BOOLEAN
, 8, TFS(&tfs_offset_units
), 0x80,
5252 { &hf_extended_advertising_aux_ptr_aux_offset
,
5253 { "Aux Offset", "btle.extended_advertising_header.aux_pointer.aux_offset",
5254 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF,
5257 { &hf_extended_advertising_aux_ptr_aux_phy
,
5258 { "Aux PHY", "btle.extended_advertising_header.aux_pointer.aux_phy",
5259 FT_UINT16
, BASE_DEC
, VALS(le_phys
), 0xE000,
5262 { &hf_extended_advertising_sync_info
,
5263 { "Advertiser Sync Info", "btle.extended_advertising.sync_info",
5264 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5267 { &hf_extended_advertising_had_fragment
,
5268 { "Host Advertising Data Fragment", "btle.extended_advertising.had_fragment",
5269 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5272 { &hf_extended_advertising_sync_info_offset
,
5273 { "Sync Offset", "btle.extended_advertising_header.sync_info.sync_offset",
5274 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF,
5277 { &hf_extended_advertising_sync_info_offset_units
,
5278 { "Offset Units", "btle.extended_advertising_header.sync_info.offset_units",
5279 FT_BOOLEAN
, 16, TFS(&tfs_offset_units
), 0x2000,
5282 { &hf_extended_advertising_sync_info_offset_adjust
,
5283 { "Offset Adjust", "btle.extended_advertising_header.sync_info.offset_adjust",
5284 FT_BOOLEAN
, 16, TFS(&tfs_offset_adjust
), 0x4000,
5287 { &hf_extended_advertising_sync_info_reserved
,
5288 { "Reserved", "btle.extended_advertising_header.sync_info.reserved",
5289 FT_BOOLEAN
, 16, NULL
, 0x8000,
5292 { &hf_extended_advertising_sync_info_interval
,
5293 { "Interval", "btle.extended_advertising_header.sync_info.interval",
5294 FT_UINT16
, BASE_HEX
, NULL
, 0,
5297 { &hf_extended_advertising_sync_info_channel_map
,
5298 { "Channel Map", "btle.extended_advertising_header.sync_info.channel_map",
5299 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5302 { &hf_extended_advertising_sync_info_sleep_clock_accuracy
,
5303 { "Sleep Clock Accuracy", "btle.extended_advertising_header.sync_info.sleep_clock_accuracy",
5304 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &sleep_clock_accuracy_vals_ext
, 0xe0,
5307 { &hf_extended_advertising_sync_info_access_address
,
5308 { "Access Address", "btle.extended_advertising_header.sync_info.access_address",
5309 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5312 { &hf_extended_advertising_sync_info_crc_init
,
5313 { "CRC Init", "btle.extended_advertising_header.sync_info.crc_init",
5314 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
5317 { &hf_extended_advertising_sync_info_event_counter
,
5318 { "Event counter", "btle.extended_advertising_header.sync_info.event_counter",
5319 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5322 { &hf_extended_advertising_tx_power
,
5323 { "TX Power", "btle.extended_advertising_header.tx_power",
5324 FT_INT8
, BASE_DEC
| BASE_UNIT_STRING
, UNS(&units_dbm
), 0x0,
5327 { &hf_extended_advertising_header_acad
,
5328 { "Additional Controller Advertising Data", "btle.extended_advertising_header.acad",
5329 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5333 { "Data Header", "btle.data_header",
5334 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5337 { &hf_data_header_llid
,
5338 { "LLID", "btle.data_header.llid",
5339 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &llid_codes_vals_ext
, 0x03,
5340 "Logical Link Identifier", HFILL
}
5342 { &hf_data_header_llid_connectediso
,
5343 { "LLID", "btle.data_header.llid",
5344 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &llid_connectediso_codes_vals_ext
, 0x03,
5345 "Logical Link Identifier", HFILL
}
5347 { &hf_data_header_llid_broadcastiso
,
5348 { "LLID", "btle.data_header.llid",
5349 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &llid_broadcastiso_codes_vals_ext
, 0x03,
5350 "Logical Link Identifier", HFILL
}
5352 { &hf_data_header_next_expected_sequence_number
,
5353 { "Next Expected Sequence Number", "btle.data_header.next_expected_sequence_number",
5354 FT_UINT8
, BASE_DEC
, NULL
, 0x04,
5357 { &hf_data_header_sequence_number
,
5358 { "Sequence Number", "btle.data_header.sequence_number",
5359 FT_UINT8
, BASE_DEC
, NULL
, 0x08,
5362 { &hf_data_header_more_data
,
5363 { "More Data", "btle.data_header.more_data",
5364 FT_BOOLEAN
, 8, NULL
, 0x10,
5367 { &hf_data_header_cte_info_present
,
5368 { "CTE Info", "btle.data_header.cte_info_present",
5369 FT_BOOLEAN
, 8, TFS(&tfs_present_not_present
), 0x20,
5372 { &hf_data_header_length
,
5373 { "Length", "btle.data_header.length",
5374 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5377 { &hf_data_header_cte_info
,
5378 { "CTE Info", "btle.data_header.cte_info",
5379 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5382 { &hf_data_header_cte_info_time
,
5383 { "CTE Time", "btle.data_header.cte_info.time",
5384 FT_UINT8
, BASE_HEX
, NULL
, 0x1F,
5387 { &hf_data_header_cte_info_rfu
,
5388 { "RFU", "btle.data_header.cte_info.rfu",
5389 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
5392 { &hf_data_header_cte_info_type
,
5393 { "CTE Type", "btle.data_header.cte_info.type",
5394 FT_UINT8
, BASE_HEX
, VALS(le_cte_type_vals
), 0xC0,
5397 { &hf_data_header_rfu
,
5398 { "RFU", "btle.data_header.rfu",
5399 FT_UINT8
, BASE_DEC
, NULL
, 0xC0,
5400 "Reserved for Future Use", HFILL
}
5402 { &hf_data_header_rfu_67
,
5403 { "RFU", "btle.data_header.rfu",
5404 FT_UINT8
, BASE_DEC
, NULL
, 0xC0,
5405 "Reserved for Future Use", HFILL
}
5407 { &hf_data_header_rfu_57
,
5408 { "RFU", "btle.data_header.rfu",
5409 FT_UINT8
, BASE_DEC
, NULL
, 0xA0,
5410 "Reserved for Future Use", HFILL
}
5412 { &hf_data_header_close_isochronous_event
,
5413 { "Close Isochronous Event", "btle.data_header.close_isochronous_event",
5414 FT_BOOLEAN
, 8, NULL
, 0x10,
5417 { &hf_data_header_null_pdu_indicator
,
5418 { "Null PDU Indicator", "btle.data_header.null_pdu_indicator",
5419 FT_BOOLEAN
, 8, NULL
, 0x40,
5422 { &hf_data_header_control_subevent_sequence_number
,
5423 { "Control Subevent Sequence Number", "btle.data_header.control_subevent_sequence_number",
5424 FT_UINT8
, BASE_DEC
, NULL
, 0x1C,
5427 { &hf_data_header_control_subevent_transmission_flag
,
5428 { "Control Subevent Transmission Flag", "btle.data_header.control_subevent_transmission_flag",
5429 FT_BOOLEAN
, 8, NULL
, 0x20,
5432 { &hf_control_opcode
,
5433 { "Control Opcode", "btle.control_opcode",
5434 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &control_opcode_vals_ext
, 0x0,
5437 { &hf_control_reject_opcode
,
5438 { "Reject Opcode", "btle.control.reject_opcode",
5439 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &control_opcode_vals_ext
, 0x0,
5442 { &hf_control_unknown_type
,
5443 { "Unknown Type", "btle.control.unknown_type",
5444 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &control_opcode_vals_ext
, 0x0,
5447 { &hf_control_error_code
,
5448 { "Error Code", "btle.control.error_code",
5449 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &bthci_cmd_status_vals_ext
, 0x0,
5452 { &hf_control_version_number
,
5453 { "Version Number", "btle.control.version_number",
5454 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &ll_version_number_vals_ext
, 0x0,
5457 { &hf_control_company_id
,
5458 { "Company Id", "btle.control.company_id",
5459 FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, &bluetooth_company_id_vals_ext
, 0x0,
5462 { &hf_control_subversion_number
,
5463 { "Subversion Number", "btle.control.subversion_number",
5464 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5467 { &hf_control_feature_set
,
5468 { "Feature Set", "btle.control.feature_set",
5469 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
5472 { &hf_control_feature_set_le_encryption
,
5473 { "LE Encryption", "btle.control.feature_set.le_encryption",
5474 FT_BOOLEAN
, 8, NULL
, 0x01,
5477 { &hf_control_feature_set_connection_parameters_request_procedure
,
5478 { "Connection Parameters Request Procedure", "btle.control.feature_set.connection_parameters_request_procedure",
5479 FT_BOOLEAN
, 8, NULL
, 0x02,
5482 { &hf_control_feature_set_extended_reject_indication
,
5483 { "Extended Reject Indication", "btle.control.feature_set.extended_reject_indication",
5484 FT_BOOLEAN
, 8, NULL
, 0x04,
5487 { &hf_control_feature_set_peripheral_initiated_features_exchange
,
5488 { "Peripheral Initiated Features Exchange", "btle.control.feature_set.peripheral_initiated_features_exchange",
5489 FT_BOOLEAN
, 8, NULL
, 0x08,
5492 { &hf_control_feature_set_le_ping
,
5493 { "LE Ping", "btle.control.feature_set.le_ping",
5494 FT_BOOLEAN
, 8, NULL
, 0x10,
5497 { &hf_control_feature_set_le_pkt_len_ext
,
5498 { "LE Data Packet Length Extension", "btle.control.feature_set.le_pkt_len_ext",
5499 FT_BOOLEAN
, 8, NULL
, 0x20,
5502 { &hf_control_feature_set_ll_privacy
,
5503 { "LL Privacy", "btle.control.feature_set.le_privacy",
5504 FT_BOOLEAN
, 8, NULL
, 0x40,
5507 { &hf_control_feature_set_ext_scan_flt_pol
,
5508 { "Extended Scanner Filter Policies", "btle.control.feature_set.ext_scan_flt_pol",
5509 FT_BOOLEAN
, 8, NULL
, 0x80,
5512 { &hf_control_feature_set_le_2m_phy
,
5513 { "LE 2M PHY", "btle.control.feature_set.le_2m_phy",
5514 FT_BOOLEAN
, 8, NULL
, 0x01,
5517 { &hf_control_feature_set_stable_modulation_index_transmitter
,
5518 { "Stable Modulation Index - Transmitter", "btle.control.feature_set.st_mod_idx_tx",
5519 FT_BOOLEAN
, 8, NULL
, 0x02,
5522 { &hf_control_feature_set_stable_modulation_index_receiver
,
5523 { "Stable Modulation Index - Receiver", "btle.control.feature_set.st_mod_idx_rx",
5524 FT_BOOLEAN
, 8, NULL
, 0x04,
5527 { &hf_control_feature_set_le_coded_phy
,
5528 { "LE Coded PHY", "btle.control.feature_set.le_coded_phy",
5529 FT_BOOLEAN
, 8, NULL
, 0x08,
5532 { &hf_control_feature_set_le_extended_advertising
,
5533 { "LE Extended Advertising", "btle.control.feature_set.le_extended_adv",
5534 FT_BOOLEAN
, 8, NULL
, 0x10,
5537 { &hf_control_feature_set_le_periodic_advertising
,
5538 { "LE Periodic Advertising", "btle.control.feature_set.periodic_adv",
5539 FT_BOOLEAN
, 8, NULL
, 0x20,
5542 { &hf_control_feature_set_channel_selection_algorithm_2
,
5543 { "Channel Selection Algorithm #2", "btle.control.feature_set.ch_sel_2",
5544 FT_BOOLEAN
, 8, NULL
, 0x40,
5547 { &hf_control_feature_set_le_power_class_1
,
5548 { "LE Power Class 1", "btle.control.feature_set.le_power_class_1",
5549 FT_BOOLEAN
, 8, NULL
, 0x80,
5552 { &hf_control_feature_set_minimum_number_of_used_channels_procedure
,
5553 { "Minimum Number of Used Channels Procedure", "btle.control.feature_set.min_num_used_ch_proc",
5554 FT_BOOLEAN
, 8, NULL
, 0x01,
5557 { &hf_control_feature_set_connection_cte_request
,
5558 { "Connection CTE Request", "btle.control.feature_set.connection_cte_request",
5559 FT_BOOLEAN
, 8, NULL
, 0x02,
5562 { &hf_control_feature_set_connection_cte_response
,
5563 { "Connection CTE Response", "btle.control.feature_set.connection_cte_response",
5564 FT_BOOLEAN
, 8, NULL
, 0x04,
5567 { &hf_control_feature_set_connectionless_cte_tx
,
5568 { "Connectionless CTE Transmitter", "btle.control.feature_set.connectionless_cte_transmitter",
5569 FT_BOOLEAN
, 8, NULL
, 0x08,
5572 { &hf_control_feature_set_connectionless_cte_rx
,
5573 { "Connectionless CTE Receiver", "btle.control.feature_set.connectionless_cte_receiver",
5574 FT_BOOLEAN
, 8, NULL
, 0x10,
5577 { &hf_control_feature_set_antenna_switching_tx_aod
,
5578 { "Antenna Switching During CTE Transmission (AoD)", "btle.control.feature_set.antenna_switching_tx_aod",
5579 FT_BOOLEAN
, 8, NULL
, 0x20,
5582 { &hf_control_feature_set_antenna_switching_rx_aoa
,
5583 { "Antenna Switching During CTE Reception (AoA)", "btle.control.feature_set.antenna_switching_rx_aoa",
5584 FT_BOOLEAN
, 8, NULL
, 0x40,
5587 { &hf_control_feature_set_cte_rx
,
5588 { "Receiving Constant Tone Extensions", "btle.control.feature_set.cte_rx",
5589 FT_BOOLEAN
, 8, NULL
, 0x80,
5592 { &hf_control_feature_set_past_sender
,
5593 { "Periodic Advertising Sync Transfer - Sender", "btle.control.feature_set.past_sender",
5594 FT_BOOLEAN
, 8, NULL
, 0x01,
5597 { &hf_control_feature_set_past_receiver
,
5598 { "Periodic Advertising Sync Transfer - Receiver", "btle.control.feature_set.past_receiver",
5599 FT_BOOLEAN
, 8, NULL
, 0x02,
5602 { &hf_control_feature_set_sca_updates
,
5603 { "Sleep Clock Accuracy Updates", "btle.control.feature_set.sca_updates",
5604 FT_BOOLEAN
, 8, NULL
, 0x04,
5607 { &hf_control_feature_set_remote_public_key_validation
,
5608 { "Remote Public Key Validation", "btle.control.feature_set.remote_public_key_validation",
5609 FT_BOOLEAN
, 8, NULL
, 0x08,
5612 { &hf_control_feature_set_cis_central
,
5613 { "Connected Isochronous Stream - Central", "btle.control.feature_set.cis_central",
5614 FT_BOOLEAN
, 8, NULL
, 0x10,
5617 { &hf_control_feature_set_cis_peripheral
,
5618 { "Connected Isochronous Stream - Peripheral", "btle.control.feature_set.cis_peripheral",
5619 FT_BOOLEAN
, 8, NULL
, 0x20,
5622 { &hf_control_feature_set_iso_broadcast
,
5623 { "Isochronous Broadcaster", "btle.control.feature_set.iso_broadcast",
5624 FT_BOOLEAN
, 8, NULL
, 0x40,
5627 { &hf_control_feature_set_synchronized_receiver
,
5628 { "Synchronized Receiver", "btle.control.feature_set.synchronized_receiver",
5629 FT_BOOLEAN
, 8, NULL
, 0x80,
5632 { &hf_control_feature_set_connected_iso_host_support
,
5633 { "Connected Isochronous Stream (Host Support)", "btle.control.feature_set.connected_iso_host_support",
5634 FT_BOOLEAN
, 8, NULL
, 0x01,
5637 { &hf_control_feature_set_le_power_control_request1
,
5638 { "LE Power Control Request", "btle.control.feature_set.le_power_control_request",
5639 FT_BOOLEAN
, 8, NULL
, 0x02,
5642 { &hf_control_feature_set_le_power_control_request2
,
5643 { "LE Power Control Request", "btle.control.feature_set.le_power_control_request_bit_2",
5644 FT_BOOLEAN
, 8, NULL
, 0x04,
5647 { &hf_control_feature_set_le_path_loss_monitoring
,
5648 { "LE Path Loss Monitoring", "btle.control.feature_set.le_path_loss_monitoring",
5649 FT_BOOLEAN
, 8, NULL
, 0x08,
5652 { &hf_control_feature_set_le_periodic_adv_adi_support
,
5653 { "Periodic Advertising ADI support", "btle.control.feature_set.le_periodic_adv_adi_support",
5654 FT_BOOLEAN
, 8, NULL
, 0x10,
5657 { &hf_control_feature_set_connection_subrating
,
5658 { "Connection Subrating", "btle.control.feature_set.connection_subrating",
5659 FT_BOOLEAN
, 8, NULL
, 0x20,
5662 { &hf_control_feature_set_connection_subrating_host_support
,
5663 { "Connection Subrating (Host Support)", "btle.control.feature_set.connection_subrating_host_support",
5664 FT_BOOLEAN
, 8, NULL
, 0x40,
5667 { &hf_control_feature_set_channel_classification
,
5668 { "Channel Classification", "btle.control.feature_set.channel_classification",
5669 FT_BOOLEAN
, 8, NULL
, 0x80,
5672 { &hf_control_feature_set_adv_coding_selection
,
5673 { "Advertising Coding Selection", "btle.control.feature_set.adv_coding_selection",
5674 FT_BOOLEAN
, 8, NULL
, 0x01,
5677 { &hf_control_feature_set_decision_based_advertising_filtering
,
5678 { "Decision-Based Advertising Filtering", "btle.control.feature_set.hf_control_feature_set_decision_based_advertising_filtering",
5679 FT_BOOLEAN
, 8, NULL
, 0x02,
5682 { &hf_control_feature_set_adv_coding_selection_host_support
,
5683 { "Advertising Coding Selection (Host Support)", "btle.control.feature_set.adv_coding_selection_host_support",
5684 FT_BOOLEAN
, 8, NULL
, 0x04,
5687 { &hf_control_feature_set_periodic_adv_with_responses_advertiser
,
5688 { "Periodic Advertising with Responses - Advertiser", "btle.control.feature_set.periodic_adv_with_responses_advertiser",
5689 FT_BOOLEAN
, 8, NULL
, 0x08,
5692 { &hf_control_feature_set_periodic_adv_with_responses_scanner
,
5693 { "Periodic Advertising with Responses - Scanner", "btle.control.feature_set.adv_with_responses_scanner",
5694 FT_BOOLEAN
, 8, NULL
, 0x10,
5697 { &hf_control_feature_set_unsegmented_frame_mode
,
5698 { "Unsegmented Framed Mode", "btle.control.feature_set.hf_control_feature_set_unsegmented_frame_mode",
5699 FT_BOOLEAN
, 8, NULL
, 0x20,
5702 { &hf_control_feature_set_channel_sounding
,
5703 { "Channel Sounding", "btle.control.feature_set.hf_control_feature_set_channel_sounding",
5704 FT_BOOLEAN
, 8, NULL
, 0x40,
5707 { &hf_control_feature_set_channel_sounding_host_support
,
5708 { "Channel Sounding (Host Support)", "btle.control.feature_set.hf_control_feature_set_channel_sounding_host_support",
5709 FT_BOOLEAN
, 8, NULL
, 0x80,
5712 { &hf_control_feature_set_channel_sounding_tone_quality_indication
,
5713 { "Channel Sounding Tone Quality Indication", "btle.control.feature_set.hf_control_feature_set_channel_sounding_tone_quality_indication",
5714 FT_BOOLEAN
, 8, NULL
, 0x01,
5717 { &hf_control_feature_set_reserved_bits_page_7
,
5718 { "Reserved bits", "btle.control.feature_set.hf_control_feature_set_reserved_bits_page_7",
5719 FT_UINT8
, BASE_DEC
, NULL
, 0xFE,
5722 { &hf_control_feature_set_reserved_bits_page_8
,
5723 { "Reserved bits", "btle.control.feature_set.hf_control_feature_set_reserved_bits_page_8",
5724 FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
5727 { &hf_control_feature_set_ll_extended_feature_set
,
5728 { "LL Extended Feature Set", "btle.control.feature_set.hf_control_feature_set_ll_extended_feature_set",
5729 FT_UINT8
, BASE_DEC
, NULL
, 0x80,
5732 { &hf_control_feature_set_monitoring_advertisers
,
5733 { "Monitoring Advertisers", "btle.control.feature_set.hf_control_feature_set_monitoring_advertisers",
5734 FT_UINT8
, BASE_DEC
, NULL
, 0x01,
5737 { &hf_control_feature_set_frame_space_update
,
5738 { "Frame Space Update", "btle.control.feature_set.hf_control_feature_set_frame_space_update",
5739 FT_UINT8
, BASE_DEC
, NULL
, 0x02,
5742 { &hf_control_feature_set_reserved_bits_page_9
,
5743 { "Reserved bits", "btle.control.feature_set.hf_control_feature_set_reserved_bits_page_9",
5744 FT_UINT8
, BASE_DEC
, NULL
, 0xFC,
5747 { &hf_control_window_size
,
5748 { "Window Size", "btle.control.window_size",
5749 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5752 { &hf_control_window_offset
,
5753 { "Window Offset", "btle.control.window_offset",
5754 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5757 { &hf_control_interval
,
5758 { "Interval", "btle.control.interval",
5759 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5762 { &hf_control_latency
,
5763 { "Latency", "btle.control.latency",
5764 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5767 { &hf_control_timeout
,
5768 { "Timeout", "btle.control.timeout",
5769 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5772 { &hf_control_instant
,
5773 { "Instant", "btle.control.instant",
5774 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5777 { &hf_control_rfu_5
,
5778 { "Reserved for future use", "btle.control.reserved",
5779 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5782 { &hf_control_interval_min
,
5783 { "Interval Min", "btle.control.interval.min",
5784 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5787 { &hf_control_interval_max
,
5788 { "Interval Max", "btle.control.interval.max",
5789 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5792 { &hf_control_preferred_periodicity
,
5793 { "Preferred Periodicity", "btle.control.preferred_periodicity",
5794 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5797 { &hf_control_reference_connection_event_count
,
5798 { "Reference Connection Event Count","btle.control.reference_connection_event_count",
5799 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5802 { &hf_control_offset_0
,
5803 { "Offset 0", "btle.control.offset.0",
5804 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5807 { &hf_control_offset_1
,
5808 { "Offset 1", "btle.control.offset.1",
5809 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5812 { &hf_control_offset_2
,
5813 { "Offset 2", "btle.control.offset.2",
5814 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5817 { &hf_control_offset_3
,
5818 { "Offset 3", "btle.control.offset.3",
5819 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5822 { &hf_control_offset_4
,
5823 { "Offset 4", "btle.control.offset.4",
5824 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5827 { &hf_control_offset_5
,
5828 { "Offset 5", "btle.control.offset.5",
5829 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5832 { &hf_control_channel_map
,
5833 { "Channel Map", "btle.control.channel_map",
5834 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5837 { &hf_control_random_number
,
5838 { "Random Number", "btle.control.random_number",
5839 FT_UINT64
, BASE_DEC_HEX
, NULL
, 0x0,
5842 { &hf_control_encrypted_diversifier
,
5843 { "Encrypted Diversifier", "btle.control.encrypted_diversifier",
5844 FT_UINT16
, BASE_DEC_HEX
, NULL
, 0x0,
5847 { &hf_control_central_session_key_diversifier
,
5848 { "Central Session Key Diversifier", "btle.control.central_session_key_diversifier",
5849 FT_UINT64
, BASE_DEC_HEX
, NULL
, 0x0,
5852 { &hf_control_peripheral_session_key_diversifier
,
5853 { "Peripheral Session Key Diversifier", "btle.control.peripheral_session_key_diversifier",
5854 FT_UINT64
, BASE_DEC_HEX
, NULL
, 0x0,
5857 { &hf_control_central_session_initialization_vector
,
5858 { "Central Session Initialization Vector", "btle.control.central_session_initialization_vector",
5859 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
5862 { &hf_control_peripheral_session_initialization_vector
,
5863 { "Peripheral Session Initialization Vector", "btle.control.peripheral_session_initialization_vector",
5864 FT_UINT64
, BASE_DEC_HEX
, NULL
, 0x0,
5867 { &hf_control_max_rx_octets
,
5868 { "Max RX octets", "btle.control.max_rx_octets",
5869 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5872 { &hf_control_max_rx_time
,
5873 { "Max RX time", "btle.control.max_rx_time",
5874 FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microsecond_microseconds
), 0x0,
5877 { &hf_control_max_tx_octets
,
5878 { "Max TX octets", "btle.control.max_tx_octets",
5879 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5882 { &hf_control_max_tx_time
,
5883 { "Max TX time", "btle.control.max_tx_time",
5884 FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microsecond_microseconds
), 0x0,
5887 { &hf_control_phys_sender_le_1m_phy
,
5888 { "Sender prefers to use the LE 1M PHY", "btle.control.phys.le_1m_phy",
5889 FT_BOOLEAN
, 8, NULL
, 0x01,
5892 { &hf_control_phys_sender_le_2m_phy
,
5893 { "Sender prefers to use the LE 2M PHY", "btle.control.phys.le_2m_phy",
5894 FT_BOOLEAN
, 8, NULL
, 0x02,
5897 { &hf_control_phys_sender_le_coded_phy
,
5898 { "Sender prefers to use the LE Coded PHY", "btle.control.phys.le_coded_phy",
5899 FT_BOOLEAN
, 8, NULL
, 0x04,
5902 { &hf_control_phys_update_le_1m_phy
,
5903 { "The LE 1M PHY shall be used", "btle.control.phys.le_1m_phy",
5904 FT_BOOLEAN
, 8, NULL
, 0x01,
5907 { &hf_control_phys_update_le_2m_phy
,
5908 { "The LE 2M PHY shall be used", "btle.control.phys.le_2m_phy",
5909 FT_BOOLEAN
, 8, NULL
, 0x02,
5912 { &hf_control_phys_update_le_coded_phy
,
5913 { "The LE Coded PHY shall be used", "btle.control.phys.le_coded_phy",
5914 FT_BOOLEAN
, 8, NULL
, 0x04,
5917 { &hf_control_phys_reserved_bits
,
5918 { "Reserved for future use", "btle.control.phys.reserved",
5919 FT_UINT8
, BASE_DEC
, NULL
, 0xF8,
5922 { &hf_control_tx_phys
,
5923 { "TX PHYs", "btle.control.tx_phys",
5924 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5927 { &hf_control_rx_phys
,
5928 { "RX PHYs", "btle.control.rx_phys",
5929 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5932 { &hf_control_c_to_p_phy
,
5933 { "Central to Peripheral PHY", "btle.control.m_to_s_phy",
5934 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5937 { &hf_control_c_to_p_phy_le_1m_phy
,
5938 { "LE 1M PHY", "btle.control.m_to_s_phy.le_1m_phy",
5939 FT_BOOLEAN
, 8, NULL
, 0x01,
5942 { &hf_control_c_to_p_phy_le_2m_phy
,
5943 { "LE 2M PHY", "btle.control.m_to_s_phy.le_2m_phy",
5944 FT_BOOLEAN
, 8, NULL
, 0x02,
5947 { &hf_control_c_to_p_phy_le_coded_phy
,
5948 { "LE Coded PHY", "btle.control.m_to_s_phy.le_coded_phy",
5949 FT_BOOLEAN
, 8, NULL
, 0x04,
5952 { &hf_control_c_to_p_phy_reserved_bits
,
5953 { "Reserved for future use", "btle.control.m_to_s_phy.reserved",
5954 FT_UINT8
, BASE_DEC
, NULL
, 0xF8,
5957 { &hf_control_p_to_c_phy
,
5958 { "Peripheral to Central PHY", "btle.control.s_to_m_phy",
5959 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5962 { &hf_control_p_to_c_phy_le_1m_phy
,
5963 { "LE 1M PHY", "btle.control.s_to_m_phy.le_1m_phy",
5964 FT_BOOLEAN
, 8, NULL
, 0x01,
5967 { &hf_control_p_to_c_phy_le_2m_phy
,
5968 { "LE 2M PHY", "btle.control.s_to_m_phy.le_2m_phy",
5969 FT_BOOLEAN
, 8, NULL
, 0x02,
5972 { &hf_control_p_to_c_phy_le_coded_phy
,
5973 { "LE Coded PHY", "btle.control.s_to_m_phy.le_coded_phy",
5974 FT_BOOLEAN
, 8, NULL
, 0x04,
5977 { &hf_control_p_to_c_phy_reserved_bits
,
5978 { "Reserved for future use", "btle.control.s_to_m_phy.reserved",
5979 FT_UINT8
, BASE_DEC
, NULL
, 0xF8,
5983 { "PHYs", "btle.control.phys",
5984 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5987 { &hf_control_phys_le_1m_phy
,
5988 { "LE 1M PHY", "btle.control.phys.le_1m_phy",
5989 FT_BOOLEAN
, 8, NULL
, 0x01,
5992 { &hf_control_phys_le_2m_phy
,
5993 { "LE 2M PHY", "btle.control.phys.le_2m_phy",
5994 FT_BOOLEAN
, 8, NULL
, 0x02,
5997 { &hf_control_phys_le_coded_phy
,
5998 { "LE Coded PHY", "btle.control.phys.le_coded_phy",
5999 FT_BOOLEAN
, 8, NULL
, 0x04,
6002 { &hf_control_min_used_channels
,
6003 { "Minimum Used Channels", "btle.control.min_used_channels",
6004 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6007 { &hf_control_cte_min_len_req
,
6008 { "MinCTELenReq", "btle.control.cte.min_len_req",
6009 FT_UINT8
, BASE_DEC
, NULL
, 0x1F,
6012 { &hf_control_cte_rfu
,
6013 { "Reserved", "btle.control.cte.rfu",
6014 FT_UINT8
, BASE_DEC
, NULL
, 0x20,
6017 { &hf_control_cte_type_req
,
6018 { "CTETypeReq", "btle.control.cte.type_req",
6019 FT_UINT8
, BASE_DEC
, VALS(le_cte_type_vals
), 0xC0,
6022 { &hf_control_sync_id
,
6023 { "ID", "btle.control.sync.id",
6024 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
6027 { &hf_control_sync_info_offset
,
6028 { "Sync Offset", "btle.control.sync_info.sync_offset",
6029 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF,
6032 { &hf_control_sync_info_offset_units
,
6033 { "Offset Units", "btle.control.sync_info.offset_units",
6034 FT_BOOLEAN
, 16, TFS(&tfs_offset_units
), 0x2000,
6037 { &hf_control_sync_info_offset_adjust
,
6038 { "Offset Adjust", "btle.control.sync_info.offset_adjust",
6039 FT_BOOLEAN
, 16, TFS(&tfs_offset_adjust
), 0x4000,
6042 { &hf_control_sync_info_reserved
,
6043 { "Reserved", "btle.control.sync_info.reserved",
6044 FT_BOOLEAN
, 16, NULL
, 0x8000,
6047 { &hf_control_sync_info_interval
,
6048 { "Interval", "btle.control.sync_info.interval",
6049 FT_UINT16
, BASE_HEX
, NULL
, 0,
6052 { &hf_control_sync_info_channel_map
,
6053 { "Channel Map", "btle.control.sync_info.channel_map",
6054 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6057 { &hf_control_sync_info_sleep_clock_accuracy
,
6058 { "Sleep Clock Accuracy", "btle.control.sync_info.sleep_clock_accuracy",
6059 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &sleep_clock_accuracy_vals_ext
, 0xe0,
6062 { &hf_control_sync_info_access_address
,
6063 { "Access Address", "btle.control.sync_info.access_address",
6064 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
6067 { &hf_control_sync_info_crc_init
,
6068 { "CRC Init", "btle.control.sync_info.crc_init",
6069 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
6072 { &hf_control_sync_info_event_counter
,
6073 { "Event counter", "btle.control.sync_info.event_counter",
6074 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6077 { &hf_control_sync_conn_event_count
,
6078 { "connEventCount", "btle.control.sync.conn_event_count",
6079 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6082 { &hf_control_sync_last_pa_event_counter
,
6083 { "lastPaEventCounter", "btle.control.sync.last_pa_event_counter",
6084 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6087 { &hf_control_sync_sid
,
6088 { "SID", "btle.control.sync.sid",
6089 FT_UINT8
, BASE_HEX
, NULL
, 0x0F,
6092 { &hf_control_sync_atype
,
6093 { "AType", "btle.control.sync.atype",
6094 FT_UINT8
, BASE_DEC
, NULL
, 0x10,
6097 { &hf_control_sync_sleep_clock_accuracy
,
6098 { "Sleep Clock Accuracy", "btle.control.sync.sleep_clock_accuracy",
6099 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &sleep_clock_accuracy_vals_ext
, 0xE0,
6102 { &hf_control_sync_sync_conn_event_counter
,
6103 { "syncConnEventCount", "btle.control.sync.sync_conn_event_count",
6104 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6107 { &hf_control_sleep_clock_accuracy
,
6108 { "Sleep Clock Accuracy", "btle.control.sleep_clock_accuracy",
6109 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &sleep_clock_accuracy_vals_ext
, 0xe0,
6112 { &hf_control_cig_id
,
6113 { "CIG_ID", "btle.control.cig_id",
6114 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6117 { &hf_control_cis_id
,
6118 { "CIS_ID", "btle.control.cis_id",
6119 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6122 { &hf_control_max_sdu_c_to_p
,
6123 { "Max_SDU_C_To_P", "btle.control.max_sdu_c_to_p",
6124 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
6127 { &hf_control_rfu_1
,
6128 { "Reserved", "btle.control.rfu.1",
6129 FT_UINT16
, BASE_DEC
, NULL
, 0x7000,
6130 "Reserved for Future Use", HFILL
}
6132 { &hf_control_framed
,
6133 { "Framed", "btle.control.framed",
6134 FT_BOOLEAN
, 16, NULL
, 0x8000,
6137 { &hf_control_max_sdu_p_to_c
,
6138 { "Max_SDU_P_To_C", "btle.control.max_sdu_p_to_c",
6139 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
6142 { &hf_control_rfu_2
,
6143 { "Reserved", "btle.control.rfu.2",
6144 FT_UINT16
, BASE_DEC
, NULL
, 0xf000,
6145 "Reserved for Future Use", HFILL
}
6147 { &hf_control_sdu_interval_c_to_p
,
6148 { "SDU_Interval_C_To_P", "btle.control.sdu_interval_c_to_p",
6149 FT_UINT24
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microsecond_microseconds
), 0x0fffff,
6152 { &hf_control_rfu_3
,
6153 { "Reserved", "btle.control.rfu.3",
6154 FT_UINT24
, BASE_DEC
, NULL
, 0xf00000,
6155 "Reserved for Future Use", HFILL
}
6157 { &hf_control_sdu_interval_p_to_c
,
6158 { "SDU_Interval_P_To_C", "btle.control.sdu_interval_p_to_c",
6159 FT_UINT24
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microsecond_microseconds
), 0x0fffff,
6162 { &hf_control_rfu_4
,
6163 { "Reserved", "btle.control.rfu.4",
6164 FT_UINT24
, BASE_DEC
, NULL
, 0xf00000,
6165 "Reserved for Future Use", HFILL
}
6167 { &hf_control_max_pdu_c_to_p
,
6168 { "Max_PDU_C_To_P", "btle.control.max_pdu_c_to_p",
6169 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6172 { &hf_control_max_pdu_p_to_c
,
6173 { "Max_PDU_P_To_C", "btle.control.max_pdu_p_to_c",
6174 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6177 { &hf_control_num_sub_events
,
6178 { "Num_Sub_Events", "btle.control.num_sub_events",
6179 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6182 { &hf_control_sub_interval
,
6183 { "Sub_Interval", "btle.control.sub_interval",
6184 FT_UINT24
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microsecond_microseconds
), 0x0,
6187 { &hf_control_bn_c_to_p
,
6188 { "BN_C_To_P", "btle.control.bn_c_to_p",
6189 FT_UINT8
, BASE_DEC
, NULL
, 0x0f,
6192 { &hf_control_bn_p_to_c
,
6193 { "BN_P_To_C", "btle.control.bn_p_to_c",
6194 FT_UINT8
, BASE_DEC
, NULL
, 0xf0,
6197 { &hf_control_ft_c_to_p
,
6198 { "FT_C_To_P", "btle.control.ft_c_to_p",
6199 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6202 { &hf_control_ft_p_to_c
,
6203 { "FT_P_To_C", "btle.control.ft_p_to_c",
6204 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6207 { &hf_control_iso_interval
,
6208 { "ISO_Interval", "btle.control.iso_interval",
6209 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6212 { &hf_control_cis_offset_min
,
6213 { "CIS_Offset_Min", "btle.control.cis_offset_min",
6214 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6217 { &hf_control_cis_offset_max
,
6218 { "CIS_Offset_Max", "btle.control.cis_offset_max",
6219 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6222 { &hf_control_conn_event_count
,
6223 { "connEventCount", "btle.control.conn_event_count",
6224 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6227 { &hf_control_access_address
,
6228 { "Access Address", "btle.control.access_address",
6229 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
6232 { &hf_control_cis_offset
,
6233 { "CIS_Offset", "btle.control.cis_offset",
6234 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6237 { &hf_control_cig_sync_delay
,
6238 { "CIG_Sync_Delay", "btle.control.cig_sync_delay",
6239 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6242 { &hf_control_cis_sync_delay
,
6243 { "CIS_Sync_Delay", "btle.control.cis_sync_delay",
6244 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6247 { &hf_control_pwr_phy
,
6248 { "Power PHY", "btle.control.pwr_phy",
6249 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
6252 { &hf_control_pwr_phy_le_1m_phy
,
6253 { "LE 1M PHY", "btle.control.pwr_phy.le_1m_phy",
6254 FT_BOOLEAN
, 8, NULL
, 0x01,
6257 { &hf_control_pwr_phy_le_2m_phy
,
6258 { "LE 2M PHY", "btle.control.pwr_phy.le_2m_phy",
6259 FT_BOOLEAN
, 8, NULL
, 0x02,
6262 { &hf_control_pwr_phy_le_coded_s8_phy
,
6263 { "LE Coded S=8 PHY", "btle.control.pwr_phy.le_coded_s8_phy",
6264 FT_BOOLEAN
, 8, NULL
, 0x04,
6267 { &hf_control_pwr_phy_le_coded_s2_phy
,
6268 { "LE Coded S=2 PHY", "btle.control.pwr_phy.le_coded_s2_phy",
6269 FT_BOOLEAN
, 8, NULL
, 0x08,
6272 { &hf_control_pwr_phy_reserved_bits
,
6273 { "Reserved for future use", "btle.control.pwr_phy.reserved",
6274 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
6277 { &hf_control_delta
,
6278 { "Delta", "btle.control.delta",
6279 FT_INT8
, BASE_DEC
, NULL
, 0x0,
6282 { &hf_control_txpwr
,
6283 { "TxPower", "btle.control.txpower",
6284 FT_INT8
, BASE_DEC
, NULL
, 0x0,
6287 { &hf_control_pwrflags
,
6288 { "Power Flags", "btle.control.pwrflags",
6289 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
6292 { &hf_control_pwrflags_min
,
6293 { "Min", "btle.control.min",
6294 FT_BOOLEAN
, 8, NULL
, 0x01,
6297 { &hf_control_pwrflags_max
,
6298 { "Max", "btle.control.max",
6299 FT_BOOLEAN
, 8, NULL
, 0x02,
6302 { &hf_control_pwrflags_reserved_bits
,
6303 { "Reserved for future use", "btle.control.pwrctrl.reserved",
6304 FT_UINT8
, BASE_DEC
, NULL
, 0xFC,
6307 { &hf_control_acceptable_power_reduction
,
6308 { "Acceptable Power Reduction", "btle.control.acceptable_power_reduction",
6309 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6312 { &hf_control_subrate_factor_min
,
6313 {"Minimum subrating factor", "btle.control.subrate_factor_min",
6314 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6317 { &hf_control_subrate_factor_max
,
6318 {"Minimum subrating factor", "btle.control.subrate_factor_max",
6319 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6322 { &hf_control_max_latency
,
6323 {"Maximum peripheral latency in subrated events", "btle.control.max_latency",
6324 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6327 { &hf_control_continuation_number
,
6328 {"The minimum requested continuation number", "btle.control.continuation_number",
6329 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6332 { &hf_control_subrate_factor
,
6333 {"Subrate factor", "btle.control.subrate_factor",
6334 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6337 { &hf_control_subrate_base_event
,
6338 {"Subrate base event", "btle.control.subrate_base_event",
6339 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6342 { &hf_control_channel_reporting_enable
,
6343 {"Enable channel reporting", "btle.control.channel_reporting_enable",
6344 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6347 { &hf_control_channel_reporting_min_spacing
,
6348 {"Channel reporting min spacing (200 ms units)", "btle.control.channel_reporting_min_spacing",
6349 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6352 { &hf_control_channel_reporting_max_delay
,
6353 {"Channel reporting max delay (200 ms units)", "btle.control.channel_reporting_max_delay",
6354 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6357 { &hf_control_channel_classification
,
6358 {"Channel classification", "btle.control.hf_control_channel_classification",
6359 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6362 { &hf_control_sync_info_rsp_access_address
,
6363 {"Response Access Address", "btle.control.sync_info.rsp_aa",
6364 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
6367 { &hf_control_sync_info_num_subevents
,
6368 {"Num subevents", "btle.control.sync_info.num_subevents",
6369 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6372 { &hf_control_sync_info_subevent_interval
,
6373 {"Subevent interval", "btle.control.sync_info.subevent_interval",
6374 FT_UINT8
, BASE_HEX
, NULL
, 0,
6377 { &hf_control_sync_info_response_slot_delay
,
6378 {"Response slot delay", "btle.control.sync_info.response_slot_delay",
6379 FT_UINT8
, BASE_HEX
, NULL
, 0,
6382 { &hf_control_sync_info_response_slot_spacing
,
6383 {"Response slot spacing", "btle.control.sync_info.response_slot_spacing",
6384 FT_UINT8
, BASE_HEX
, NULL
, 0,
6387 { &hf_big_control_opcode
,
6388 { "BIG Control Opcode", "btle.big_control_opcode",
6389 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &big_control_opcode_vals_ext
, 0x0,
6393 { "L2CAP Index", "btle.l2cap_index",
6394 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
6397 { &hf_l2cap_fragment
,
6398 { "L2CAP Fragment", "btle.l2cap_data",
6399 FT_NONE
, BASE_NONE
, NULL
, 0x0,
6402 { &hf_connection_parameters_in
,
6403 { "Connection Parameters in", "btle.connection_parameters_in",
6404 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
6408 { "CRC", "btle.crc",
6409 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
6412 { &hf_isochronous_data
,
6413 { "Isochronous Data", "btle.isochronous_data",
6414 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6417 { &hf_btle_l2cap_msg_fragments
,
6418 { "L2CAP fragments", "btle.l2cap.fragments",
6419 FT_NONE
, BASE_NONE
, NULL
, 0x00,
6422 { &hf_btle_l2cap_msg_fragment
,
6423 { "L2CAP fragment", "btle.l2cap.fragment",
6424 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6427 { &hf_btle_l2cap_msg_fragment_overlap
,
6428 { "L2CAP fragment overlap", "btle.l2cap.fragment.overlap",
6429 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6432 { &hf_btle_l2cap_msg_fragment_overlap_conflicts
,
6433 { "L2CAP fragment overlapping with conflicting data", "btle.l2cap.fragment.overlap.conflicts",
6434 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6437 { &hf_btle_l2cap_msg_fragment_multiple_tails
,
6438 { "L2CAP has multiple tail fragments", "btle.l2cap.fragment.multiple_tails",
6439 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6442 { &hf_btle_l2cap_msg_fragment_too_long_fragment
,
6443 { "L2CAP fragment too long", "btle.l2cap.fragment.too_long_fragment",
6444 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6447 { &hf_btle_l2cap_msg_fragment_error
,
6448 { "L2CAP defragmentation error", "btle.l2cap.fragment.error",
6449 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6452 { &hf_btle_l2cap_msg_fragment_count
,
6453 { "L2CAP fragment count", "btle.l2cap.fragment.count",
6454 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
6457 { &hf_btle_l2cap_msg_reassembled_in
,
6458 { "Reassembled in", "btle.l2cap.reassembled.in",
6459 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6462 { &hf_btle_l2cap_msg_reassembled_length
,
6463 { "Reassembled L2CAP length", "btle.l2cap.reassembled.length",
6464 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
6467 { &hf_btle_ea_host_advertising_data_fragments
,
6468 { "EA HAD fragments", "btle.ea.host_advertising_data.fragments",
6469 FT_NONE
, BASE_NONE
, NULL
, 0x00,
6472 { &hf_btle_ea_host_advertising_data_fragment
,
6473 { "EA HAD fragment", "btle.ea.host_advertising_data.fragment",
6474 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6477 { &hf_btle_ea_host_advertising_data_fragment_overlap
,
6478 { "EA HAD fragment overlap", "btle.ea.host_advertising_data.fragment.overlap",
6479 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6482 { &hf_btle_ea_host_advertising_data_fragment_overlap_conflicts
,
6483 { "EA HAD fragment overlapping with conflicting data", "btle.ea.host_advertising_data.fragment.overlap.conflicts",
6484 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6487 { &hf_btle_ea_host_advertising_data_fragment_multiple_tails
,
6488 { "EA HAD has multiple tail fragments", "btle.ea.host_advertising_data.fragment.multiple_tails",
6489 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6492 { &hf_btle_ea_host_advertising_data_fragment_too_long_fragment
,
6493 { "EA HAD fragment too long", "btle.ea.host_advertising_data.fragment.too_long_fragment",
6494 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6497 { &hf_btle_ea_host_advertising_data_fragment_error
,
6498 { "EA HAD defragmentation error", "btle.ea.host_advertising_data.fragment.error",
6499 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6502 { &hf_btle_ea_host_advertising_data_fragment_count
,
6503 { "EA HAD fragment count", "btle.ea.host_advertising_data.fragment.count",
6504 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
6507 { &hf_btle_ea_host_advertising_data_reassembled_in
,
6508 { "Reassembled in", "btle.ea.host_advertising_data.reassembled.in",
6509 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
6512 { &hf_btle_ea_host_advertising_data_reassembled_length
,
6513 { "Reassembled EA HAD length", "btle.ea.host_advertising_data.reassembled.length",
6514 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
6517 { &hf_request_in_frame
,
6518 {"Request in Frame", "btle.request_in_frame",
6519 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
6522 { &hf_response_in_frame
,
6523 {"Response in Frame", "btle.response_in_frame",
6524 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
6529 static ei_register_info ei
[] = {
6531 { "btle.unknown_data", PI_PROTOCOL
, PI_NOTE
, "Unknown data", EXPFILL
}},
6532 { &ei_access_address_matched
,
6533 { "btle.access_address.matched", PI_PROTOCOL
, PI_NOTE
, "AccessAddress matched at capture", EXPFILL
}},
6534 { &ei_access_address_bit_errors
,
6535 { "btle.access_address.bit_errors", PI_PROTOCOL
, PI_WARN
, "AccessAddress has errors present at capture", EXPFILL
}},
6536 { &ei_access_address_illegal
,
6537 { "btle.access_address.illegal", PI_PROTOCOL
, PI_ERROR
, "AccessAddress has illegal value", EXPFILL
}},
6538 { &ei_control_proc_overlapping
,
6539 { "btle.control_proc_overlapping", PI_PROTOCOL
, PI_ERROR
, "Initiating a new control procedure before the previous was complete", EXPFILL
}},
6540 { &ei_control_proc_invalid_collision
,
6541 { "btle.control_proc_incompatible", PI_PROTOCOL
, PI_ERROR
, "Initiating a new incompatible control procedure after having sent a response to an incompatible control procedure", EXPFILL
}},
6542 { &ei_control_proc_wrong_seq
,
6543 { "btle.control_proc_unknown_seq", PI_PROTOCOL
, PI_ERROR
, "Incorrect control procedure packet sequencing or direction", EXPFILL
}},
6544 { &ei_control_proc_invalid_conflict_resolution
,
6545 { "btle.ei_control_proc_invalid_conflict_resolution",
6546 PI_PROTOCOL
, PI_ERROR
, "Incorrect control procedure packet collision resolution. See Core_v5.2, Vol 6, Part B, Section 5.3", EXPFILL
}},
6547 { &ei_crc_cannot_be_determined
,
6548 { "btle.crc.indeterminate", PI_CHECKSUM
, PI_NOTE
, "CRC unchecked, not all data available", EXPFILL
}},
6549 { &ei_crc_incorrect
,
6550 { "btle.crc.incorrect", PI_CHECKSUM
, PI_WARN
, "Incorrect CRC", EXPFILL
}},
6551 { &ei_missing_fragment_start
,
6552 { "btle.missing_fragment_start", PI_SEQUENCE
, PI_WARN
, "Missing Fragment Start", EXPFILL
}},
6554 { "btle.retransmit", PI_SEQUENCE
, PI_NOTE
, "Retransmission", EXPFILL
}},
6556 { "btle.nack", PI_SEQUENCE
, PI_NOTE
, "Not acknowledged", EXPFILL
}},
6559 static int *ett
[] = {
6561 &ett_advertising_header
,
6562 &ett_link_layer_data
,
6563 &ett_extended_advertising_header
,
6564 &ett_extended_advertising_flags
,
6565 &ett_extended_advertising_cte_info
,
6566 &ett_extended_advertising_data_info
,
6567 &ett_extended_advertising_aux_pointer
,
6568 &ett_extended_advertising_sync_info
,
6569 &ett_extended_advertising_acad
,
6571 &ett_data_header_cte_info
,
6581 &ett_scan_response_data
,
6583 &ett_btle_l2cap_msg_fragment
,
6584 &ett_btle_l2cap_msg_fragments
,
6585 &ett_btle_ea_host_advertising_data_fragment
,
6586 &ett_btle_ea_host_advertising_data_fragments
6589 connection_info_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6590 periodic_adv_info_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6591 connectediso_connection_info_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6592 broadcastiso_connection_info_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6593 connection_parameter_info_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6594 adi_to_first_frame_tree
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6596 proto_btle
= proto_register_protocol("Bluetooth Low Energy Link Layer",
6597 "BT LE LL", "btle");
6598 btle_handle
= register_dissector("btle", dissect_btle
, proto_btle
);
6600 proto_register_field_array(proto_btle
, hf
, array_length(hf
));
6601 proto_register_subtree_array(ett
, array_length(ett
));
6603 expert_module
= expert_register_protocol(proto_btle
);
6604 expert_register_field_array(expert_module
, ei
, array_length(ei
));
6606 module
= prefs_register_protocol_subtree("Bluetooth", proto_btle
, NULL
);
6607 prefs_register_static_text_preference(module
, "version",
6608 "Bluetooth LE LL version: 5.4 (Core)",
6609 "Version of protocol supported by this dissector.");
6611 prefs_register_bool_preference(module
, "detect_retransmit",
6612 "Detect retransmission",
6613 "Detect retransmission based on SN (Sequence Number)",
6614 &btle_detect_retransmit
);
6616 reassembly_table_register(&btle_l2cap_msg_reassembly_table
,
6617 &addresses_reassembly_table_functions
);
6619 reassembly_table_register(&btle_ea_host_advertising_data_reassembly_table
,
6620 &addresses_reassembly_table_functions
);
6622 register_init_routine(btle_init
);
6626 proto_reg_handoff_btle(void)
6628 btcommon_ad_handle
= find_dissector_add_dependency("btcommon.eir_ad.ad", proto_btle
);
6629 btcommon_le_channel_map_handle
= find_dissector_add_dependency("btcommon.le_channel_map", proto_btle
);
6630 btl2cap_handle
= find_dissector_add_dependency("btl2cap", proto_btle
);
6632 proto_btle_rf
= proto_get_id_by_filter_name("btle_rf");
6633 proto_nordic_ble
= proto_get_id_by_filter_name("nordic_ble");
6635 dissector_add_uint("bluetooth.encap", WTAP_ENCAP_BLUETOOTH_LE_LL
, btle_handle
);
6639 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6644 * indent-tabs-mode: nil
6647 * vi: set shiftwidth=4 tabstop=8 expandtab:
6648 * :indentSize=4:tabSize=8:noTabs=true: