Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-btle.c
blob22cfc7a3a514e3b7cf9807d4021e001df69e57b6
1 /* packet-btle.c
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
18 #include "config.h"
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>
25 #include <epan/tfs.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;
40 static int hf_crc;
41 static int hf_central_bd_addr;
42 static int hf_peripheral_bd_addr;
43 static int hf_length;
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;
349 static int ett_btle;
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;
359 static int ett_phys;
360 static int ett_pwr_phy;
361 static int ett_cte;
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,
386 NULL
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,
398 NULL
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,
410 NULL
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,
422 NULL
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,
434 NULL
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,
446 NULL
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,
458 NULL
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,
464 NULL
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,
470 NULL
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,
478 NULL
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,
486 NULL
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,
494 NULL
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,
502 NULL
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,
510 NULL
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,
519 NULL
522 static int * const hfx_control_cte[] = {
523 &hf_control_cte_min_len_req,
524 &hf_control_cte_rfu,
525 &hf_control_cte_type_req,
526 NULL
529 static int * const hfx_control_periodicsyncflags[] = {
530 &hf_control_sync_sid,
531 &hf_control_sync_atype,
532 &hf_control_sync_sleep_clock_accuracy,
533 NULL
536 static int * const hfx_control_pwrflags[] = {
537 &hf_control_pwrflags_min,
538 &hf_control_pwrflags_max,
539 &hf_control_pwrflags_reserved_bits,
540 NULL
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;
570 /* Reassembly */
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 */
591 NULL,
592 /* Tag */
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 */
617 NULL,
618 /* Tag */
619 "BTLE EA HAD fragments"
622 typedef struct _ae_had_info_t {
623 unsigned fragment_counter;
624 uint32_t first_frame_num;
625 address adv_addr;
626 } ae_had_info_t;
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. */
633 unsigned frames[5];
635 /* Opcode of the first control procedure packet. */
636 uint8_t proc_opcode;
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. */
645 unsigned last_frame;
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. */
655 uint16_t instant;
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. */
666 } direction_info_t;
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 {
674 uint32_t crc_init;
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 */
686 } connection_info_t;
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;
701 /* */
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 */
708 } btle_frame_info_t;
710 static const value_string pdu_type_vals[] = {
711 { 0x00, "ADV_IND" },
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" },
721 { 0, NULL }
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" },
730 { 0, NULL}
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" },
739 { 0, NULL}
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" },
747 { 2, "Reserved" },
748 { 3, "Reserved" },
749 { 0, NULL }
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" },
761 { 0, NULL }
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" },
769 { 0, NULL }
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" },
777 { 0, NULL }
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" },
786 { 0, NULL }
788 static value_string_ext llid_broadcastiso_codes_vals_ext = VALUE_STRING_EXT_INIT(llid_broadcastiso_codes_vals);
790 typedef enum
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" },
917 { 0, NULL }
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" },
924 { 0, NULL }
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[] = {
930 { 0x06, "4.0"},
931 { 0x07, "4.1" },
932 { 0x08, "4.2" },
933 { 0x09, "5.0" },
934 { 0x0A, "5.1" },
935 { 0x0B, "5.2" },
936 { 0x0C, "5.3" },
937 { 0x0D, "5.4" },
938 { 0x0E, "6.0" },
939 { 0, NULL }
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"},
948 { 0, NULL},
950 static value_string_ext advertising_mode_vals_ext = VALUE_STRING_EXT_INIT(advertising_mode_vals);
952 static const value_string le_phys[] =
954 { 0, "LE 1M" },
955 { 1, "LE 2M" },
956 { 2, "LE Coded" },
957 { 3, "Reserved" },
958 { 4, "Reserved" },
959 { 5, "Reserved" },
960 { 6, "Reserved" },
961 { 7, "Reserved" },
962 { 0, NULL }
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" },
970 { 0, NULL }
973 static const true_false_string tfs_ca = {
974 "0 ppm to 50 ppm",
975 "51 ppm to 500 ppm"
978 static const true_false_string tfs_offset_units = {
979 "300 usec",
980 "30 usec"
983 static const true_false_string tfs_offset_adjust = {
984 "Adjusted 2.4576 seconds",
985 "No adjust"
988 static const true_false_string tfs_ch_sel = {
989 "#2",
990 "#1"
993 static const true_false_string tfs_random_public = {
994 "Random",
995 "Public"
998 void proto_register_btle(void);
999 void proto_reg_handoff_btle(void);
1001 static bool btle_detect_retransmit = true;
1003 static void
1004 btle_init(void)
1006 l2cap_index = 0;
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
1017 * endian-neutral.
1019 static uint32_t
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;
1068 return state;
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");
1079 } else {
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,
1089 * Section 1.2.
1091 static uint32_t
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);
1106 return retval;
1109 static int
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);
1119 offset += 1;
1121 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_2, ENC_NA);
1122 offset += 1;
1124 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_3, ENC_NA);
1125 offset += 1;
1127 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_4, ENC_NA);
1128 offset += 1;
1130 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_5, ENC_NA);
1131 offset += 1;
1133 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_6, ENC_NA);
1134 offset += 1;
1136 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_7, ENC_NA);
1137 offset += 1;
1139 proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, hfx_control_feature_set_8, ENC_NA);
1140 offset += 1;
1142 return offset;
1145 static int
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);
1149 offset += 2;
1151 proto_tree_add_item(btle_tree, hf_control_interval_max, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1152 offset += 2;
1154 proto_tree_add_item(btle_tree, hf_control_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1155 offset += 2;
1157 proto_tree_add_item(btle_tree, hf_control_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1158 offset += 2;
1160 proto_tree_add_item(btle_tree, hf_control_preferred_periodicity, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1161 offset += 1;
1163 proto_tree_add_item(btle_tree, hf_control_reference_connection_event_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1164 offset += 2;
1166 proto_tree_add_item(btle_tree, hf_control_offset_0, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1167 offset += 2;
1169 proto_tree_add_item(btle_tree, hf_control_offset_1, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1170 offset += 2;
1172 proto_tree_add_item(btle_tree, hf_control_offset_2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1173 offset += 2;
1175 proto_tree_add_item(btle_tree, hf_control_offset_3, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1176 offset += 2;
1178 proto_tree_add_item(btle_tree, hf_control_offset_4, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1179 offset += 2;
1181 proto_tree_add_item(btle_tree, hf_control_offset_5, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1182 offset += 2;
1184 return offset;
1187 static int
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);
1191 offset += 2;
1193 proto_tree_add_item(btle_tree, hf_control_max_rx_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1194 offset += 2;
1196 proto_tree_add_item(btle_tree, hf_control_max_tx_octets, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1197 offset += 2;
1199 proto_tree_add_item(btle_tree, hf_control_max_tx_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1200 offset += 2;
1202 return offset;
1205 static int
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);
1209 offset += 1;
1211 proto_tree_add_bitmask(btle_tree, tvb, offset, hf_control_rx_phys, ett_rx_phys, hfx_control_phys_sender, ENC_NA);
1212 offset += 1;
1214 return offset;
1217 static int
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;
1222 uint16_t sf;
1223 uint8_t bd_addr[6];
1224 proto_item *item;
1225 proto_item *sub_item;
1226 proto_tree *sub_tree;
1228 /* ID */
1229 proto_tree_add_item(btle_tree, hf_control_sync_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1230 offset += 2;
1232 /* Sync Info */
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));
1241 } else {
1242 proto_item_append_text(item, " Cannot be represented");
1244 offset += 2;
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);
1248 offset += 2;
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);
1255 offset += 5;
1257 proto_tree_add_item(btle_tree, hf_control_sync_info_access_address, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1258 offset += 4;
1260 proto_tree_add_item(btle_tree, hf_control_sync_info_crc_init, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1261 offset += 3;
1263 proto_tree_add_item(btle_tree, hf_control_sync_info_event_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1264 offset += 2;
1266 /* connEv */
1267 proto_tree_add_item(btle_tree, hf_control_sync_conn_event_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1268 offset += 2;
1270 proto_tree_add_item(btle_tree, hf_control_sync_last_pa_event_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1271 offset += 2;
1273 proto_tree_add_bitmask_list(btle_tree, tvb, offset, 1, hfx_control_periodicsyncflags, ENC_NA);
1274 offset += 1;
1276 proto_tree_add_bitmask(btle_tree, tvb, offset, hf_control_phys, ett_phys, hfx_control_phys, ENC_NA);
1277 offset += 1;
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);
1282 offset += 2;
1284 return offset;
1287 static int
1288 dissect_cis_req(tvbuff_t *tvb, proto_tree *btle_tree, int offset)
1290 uint32_t interval;
1291 proto_item *item;
1293 proto_tree_add_item(btle_tree, hf_control_cig_id, tvb, offset, 1, ENC_NA);
1294 offset += 1;
1296 proto_tree_add_item(btle_tree, hf_control_cis_id, tvb, offset, 1, ENC_NA);
1297 offset += 1;
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);
1300 offset += 1;
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);
1303 offset += 1;
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);
1308 offset += 2;
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);
1312 offset += 2;
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);
1316 offset += 3;
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);
1320 offset += 3;
1322 proto_tree_add_item(btle_tree, hf_control_max_pdu_c_to_p, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1323 offset += 2;
1325 proto_tree_add_item(btle_tree, hf_control_max_pdu_p_to_c, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1326 offset += 2;
1328 proto_tree_add_item(btle_tree, hf_control_num_sub_events, tvb, offset, 1, ENC_NA);
1329 offset += 1;
1331 proto_tree_add_item(btle_tree, hf_control_sub_interval, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1332 offset += 3;
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);
1336 offset += 1;
1338 proto_tree_add_item(btle_tree, hf_control_ft_c_to_p, tvb, offset, 1, ENC_NA);
1339 offset += 1;
1341 proto_tree_add_item(btle_tree, hf_control_ft_p_to_c, tvb, offset, 1, ENC_NA);
1342 offset += 1;
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);
1346 offset += 2;
1348 proto_tree_add_item(btle_tree, hf_control_cis_offset_min, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1349 offset += 3;
1351 proto_tree_add_item(btle_tree, hf_control_cis_offset_max, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1352 offset += 3;
1354 proto_tree_add_item(btle_tree, hf_control_conn_event_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1355 offset += 2;
1357 return offset;
1360 static int
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);
1364 offset += 3;
1366 proto_tree_add_item(btle_tree, hf_control_cis_offset_max, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1367 offset += 3;
1369 proto_tree_add_item(btle_tree, hf_control_conn_event_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1370 offset += 2;
1372 return offset;
1375 static int
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);
1379 offset += 4;
1381 proto_tree_add_item(btle_tree, hf_control_cis_offset, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1382 offset += 3;
1384 proto_tree_add_item(btle_tree, hf_control_cig_sync_delay, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1385 offset += 3;
1387 proto_tree_add_item(btle_tree, hf_control_cis_sync_delay, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1388 offset += 3;
1390 proto_tree_add_item(btle_tree, hf_control_conn_event_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1391 offset += 2;
1393 return offset;
1396 static int
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);
1400 offset += 1;
1402 proto_tree_add_item(btle_tree, hf_control_cis_id, tvb, offset, 1, ENC_NA);
1403 offset += 1;
1405 proto_tree_add_item(btle_tree, hf_control_error_code, tvb, offset, 1, ENC_NA);
1406 offset += 1;
1408 return offset;
1411 static int
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);
1415 offset += 1;
1417 proto_tree_add_item(btle_tree, hf_control_delta, tvb, offset, 1, ENC_NA);
1418 offset += 1;
1420 proto_tree_add_item(btle_tree, hf_control_txpwr, tvb, offset, 1, ENC_NA);
1421 offset += 1;
1423 return offset;
1427 static int
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);
1431 offset += 1;
1433 proto_tree_add_item(btle_tree, hf_control_delta, tvb, offset, 1, ENC_NA);
1434 offset += 1;
1436 proto_tree_add_item(btle_tree, hf_control_txpwr, tvb, offset, 1, ENC_NA);
1437 offset += 1;
1439 proto_tree_add_item(btle_tree, hf_control_acceptable_power_reduction, tvb, offset, 1, ENC_NA);
1440 offset += 1;
1442 return offset;
1445 static int
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);
1449 offset += 1;
1451 proto_tree_add_bitmask(btle_tree, tvb, offset, hf_control_pwrflags, ett_pwrflags, hfx_control_pwrflags, ENC_NA);
1452 offset += 1;
1454 proto_tree_add_item(btle_tree, hf_control_delta, tvb, offset, 1, ENC_NA);
1455 offset += 1;
1457 proto_tree_add_item(btle_tree, hf_control_txpwr, tvb, offset, 1, ENC_NA);
1458 offset += 1;
1460 return offset;
1463 static int
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);
1467 offset += 2;
1469 proto_tree_add_item(btle_tree, hf_control_subrate_factor_max, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1470 offset += 2;
1472 proto_tree_add_item(btle_tree, hf_control_max_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1473 offset += 2;
1475 proto_tree_add_item(btle_tree, hf_control_continuation_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1476 offset += 2;
1478 proto_tree_add_item(btle_tree, hf_control_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1479 offset += 2;
1481 return offset;
1484 static int
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);
1488 offset += 2;
1490 proto_tree_add_item(btle_tree, hf_control_subrate_base_event, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1491 offset += 2;
1493 proto_tree_add_item(btle_tree, hf_control_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1494 offset += 2;
1496 proto_tree_add_item(btle_tree, hf_control_continuation_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1497 offset += 2;
1499 proto_tree_add_item(btle_tree, hf_control_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1500 offset += 2;
1502 return offset;
1505 static int
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);
1509 offset += 1;
1511 proto_tree_add_item(btle_tree, hf_control_channel_reporting_min_spacing, tvb, offset, 1, ENC_NA);
1512 offset += 1;
1514 proto_tree_add_item(btle_tree, hf_control_channel_reporting_max_delay, tvb, offset, 1, ENC_NA);
1515 offset += 1;
1517 return offset;
1520 static int
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);
1524 offset += 10;
1526 return offset;
1530 static int
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);
1537 offset += 4;
1539 proto_tree_add_item(btle_tree, hf_control_sync_info_num_subevents, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1540 offset += 1;
1542 proto_tree_add_item(btle_tree, hf_control_sync_info_subevent_interval, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1543 offset += 1;
1545 proto_tree_add_item(btle_tree, hf_control_sync_info_response_slot_delay, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1546 offset += 1;
1548 proto_tree_add_item(btle_tree, hf_control_sync_info_response_slot_spacing, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1549 offset += 1;
1551 return offset;
1554 static int
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;
1562 return offset;
1565 static int
1566 dissect_crc(tvbuff_t *tvb,
1567 proto_tree *btle_tree,
1568 int offset,
1569 packet_info *pinfo,
1570 uint32_t length,
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 */
1585 uint32_t crc_init;
1587 if (access_address == ACCESS_ADDRESS_ADVERTISING) {
1588 crc_init = 0x555555;
1589 } else {
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);
1597 } else {
1598 expert_add_info(pinfo, sub_item, &ei_crc_cannot_be_determined);
1601 return 3;
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.
1611 static bool
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,
1615 unsigned frame_num)
1617 if (frame_num == 0)
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)
1622 return false;
1624 /* And that the new frame belongs to this control procedure */
1625 if (last_control_proc_info->proc_opcode != proc_opcode)
1626 return false;
1628 /* Previous frame has not yet been added. */
1629 if (last_control_proc_info->frames[frame_num - 1] == 0)
1630 return false;
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
1636 * spot is empty. */
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
1641 * another frame. */
1642 if (pinfo->fd->visited && (last_control_proc_info->frames[frame_num] != pinfo->num))
1643 return false;
1645 return true;
1648 static bool
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)
1653 return true;
1655 return false;
1658 static bool
1659 control_proc_can_add_frame(packet_info *pinfo,
1660 control_proc_info_t *last_control_proc_info,
1661 uint8_t proc_opcode,
1662 unsigned frame_num)
1664 if (!control_proc_can_add_frame_even_if_complete(pinfo,
1665 last_control_proc_info,
1666 proc_opcode,
1667 frame_num))
1668 return false;
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))
1672 return false;
1674 return true;
1677 static void
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)
1684 return;
1686 if (control_proc_is_complete(frame_num, last_control_proc_info))
1687 return;
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))
1693 return;
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;
1701 static bool
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:
1710 return true;
1711 default:
1712 return false;
1716 /* Returns true if this frame contains an collision violating the specification.
1718 * See Core_v5.2, Vol 6, Part B, Section 5.3 */
1719 static bool
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)
1725 return false;
1727 if (control_proc_is_complete(pinfo->num, control_proc_other))
1728 return false;
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))
1733 return false;
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
1739 * Standby State.
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))
1745 return true;
1746 else
1747 return false;
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,
1761 packet_info *pinfo,
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,
1766 uint8_t opcode)
1768 if (control_proc_invalid_collision(pinfo,
1769 control_proc_other_direction,
1770 opcode)) {
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 */
1780 return NULL;
1781 } else {
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);
1789 } else {
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);
1801 } else {
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);
1806 return NULL;
1810 return proc_info;
1813 /* Adds a frame to a control procedure context */
1814 static void control_proc_add_frame(tvbuff_t *tvb,
1815 packet_info *pinfo,
1816 proto_tree *btle_tree,
1817 uint8_t opcode,
1818 uint32_t direction,
1819 control_proc_info_t *last_control_proc_info,
1820 control_proc_info_t const *control_proc_other_direction,
1821 unsigned frame_num)
1823 proto_item *item;
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,
1850 packet_info *pinfo,
1851 proto_tree *btle_tree,
1852 uint8_t opcode,
1853 uint32_t direction,
1854 control_proc_info_t *last_control_proc_info,
1855 control_proc_info_t const *control_proc_other_direction,
1856 unsigned frame_num)
1858 control_proc_add_frame(tvb,
1859 pinfo,
1860 btle_tree,
1861 opcode,
1862 direction,
1863 last_control_proc_info,
1864 control_proc_other_direction,
1865 frame_num);
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,
1872 packet_info *pinfo,
1873 proto_tree *btle_tree,
1874 const btle_context_t *btle_context,
1875 uint8_t opcode,
1876 uint32_t direction,
1877 control_proc_info_t *last_control_proc_info,
1878 control_proc_info_t const *control_proc_other_direction,
1879 unsigned frame_num,
1880 uint16_t instant)
1882 if (btle_context && btle_context->event_counter_valid) {
1883 control_proc_add_frame(tvb,
1884 pinfo,
1885 btle_tree,
1886 opcode,
1887 direction,
1888 last_control_proc_info,
1889 control_proc_other_direction,
1890 frame_num);
1891 last_control_proc_info->instant = instant;
1892 last_control_proc_info->frame_with_instant_value = pinfo->num;
1893 } else {
1894 /* Event counter is not available, assume the procedure completes now. */
1895 control_proc_add_last_frame(tvb,
1896 pinfo,
1897 btle_tree,
1898 opcode,
1899 direction,
1900 last_control_proc_info,
1901 control_proc_other_direction,
1902 frame_num);
1906 static void
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)
1914 return;
1915 for (int offset = 0;; ) {
1916 unsigned remain = tvb_reported_length_remaining(tvb, offset);
1917 unsigned length;
1918 uint8_t opcode;
1919 if (remain < 1)
1920 break;
1921 length = tvb_get_uint8(tvb, offset);
1922 ++offset;
1923 if (length <= 0)
1924 continue;
1925 --remain;
1926 if (remain < length)
1927 break;
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];
1935 key[0].length = 1;
1936 key[0].key = &interface_id;
1937 key[1].length = 1;
1938 key[1].key = &adapter_id;
1939 key[2].length = 1;
1940 key[2].key = &trunc_seed_access_address;
1941 key[3].length = 1;
1942 key[3].key = &frame_number;
1943 key[4].length = 0;
1944 key[4].key = NULL;
1946 nconnection_info = wmem_new0(wmem_file_scope(), broadcastiso_connection_info_t);
1948 if (src_bd_addr)
1949 memcpy(nconnection_info->central_bd_addr, src_bd_addr, 6);
1951 wmem_tree_insert32_array(broadcastiso_connection_info_tree, key, nconnection_info);
1953 offset += length;
1957 static uint8_t
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. */
1972 key[0].length = 1;
1973 key[0].key = &interface_id;
1974 key[1].length = 1;
1975 key[1].key = &adapter_id;
1976 key[2].length = 1;
1977 key[2].key = &access_address;
1978 key[3].length = 0;
1979 key[3].key = NULL;
1981 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(connection_info_tree, key);
1982 if (wmem_tree) {
1983 /* Connection. */
1984 return BTLE_PDU_TYPE_DATA;
1987 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(periodic_adv_info_tree, key);
1988 if (wmem_tree) {
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);
1995 if (wmem_tree) {
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,
2005 void *data,
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));
2014 if (list_data) {
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;
2029 if (bluetooth_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;
2033 else
2034 *interface_id_out = HCI_INTERFACE_DEFAULT;
2036 if (ubertooth_data)
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;
2040 else
2041 *adapter_id_out = HCI_ADAPTER_DEFAULT;
2043 return btle_context;
2046 static int
2047 dissect_btle_adv(tvbuff_t *tvb,
2048 packet_info *pinfo,
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;
2057 int offset = 0;
2058 uint32_t length;
2059 tvbuff_t *next_tvb;
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;
2069 proto_item *item;
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);
2083 key[0].length = 1;
2084 key[0].key = &interface_id;
2085 key[1].length = 1;
2086 key[1].key = &adapter_id;
2087 key[2].length = 1;
2088 key[2].key = &access_address;
2089 key[3].length = 0;
2090 key[3].key = NULL;
2092 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(connection_info_tree, key);
2093 if (!wmem_tree) {
2094 /* Check periodic advertising tree */
2095 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(periodic_adv_info_tree, key);
2096 if (wmem_tree) {
2097 is_periodic_adv = true;
2101 if (wmem_tree) {
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;
2117 switch (pdu_type) {
2118 case 0x00: /* ADV_IND */
2119 ch_sel_valid = true;
2120 /* Fallthrough */
2121 case 0x02: /* ADV_NONCONN_IND */
2122 case 0x06: /* ADV_SCAN_IND */
2123 case 0x04: /* SCAN_RSP */
2124 tx_add_valid = true;
2125 break;
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;
2136 break;
2138 case 0x01: /* ADV_DIRECT_IND */
2139 case 0x05: /* CONNECT_IND or AUX_CONNECT_REQ */
2140 if (btle_context && btle_context->channel >= 37) {
2141 /* CONNECT_IND */
2142 ch_sel_valid = true;
2144 /* Fallthrough */
2145 case 0x03: /* SCAN_REQ or AUX_SCAN_REQ */
2146 tx_add_valid = true;
2147 rx_add_valid = true;
2148 break;
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);
2156 if (ch_sel_valid) {
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);
2160 } else {
2161 proto_tree_add_item(advertising_header_tree, hf_advertising_header_rfu_2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2164 if (tx_add_valid) {
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);
2168 } else {
2169 proto_tree_add_item(advertising_header_tree, hf_advertising_header_rfu_3, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2172 if (rx_add_valid) {
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);
2176 } else {
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));
2184 offset += 1;
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);
2189 offset += 1;
2191 switch (pdu_type) {
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) {
2206 address *addr;
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;
2224 break;
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) {
2238 address *addr;
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);
2249 break;
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) {
2263 address *addr;
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);
2274 break;
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) {
2287 address *addr;
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;
2308 break;
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) {
2325 address *addr;
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);
2341 offset += 4;
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);
2344 offset += 3;
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);
2348 offset += 1;
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);
2352 offset += 2;
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);
2356 offset += 2;
2358 proto_tree_add_item(link_layer_data_tree, hf_link_layer_data_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2359 offset += 2;
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);
2363 offset += 2;
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);
2369 offset += 5;
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);
2373 offset += 1;
2375 if (!pinfo->fd->visited) {
2376 connection_parameter_info_t *connection_parameter_info;
2378 key[0].length = 1;
2379 key[0].key = &interface_id;
2380 key[1].length = 1;
2381 key[1].key = &adapter_id;
2382 key[2].length = 1;
2383 key[2].key = &connection_access_address;
2384 key[3].length = 1;
2385 key[3].key = &pinfo->num;
2386 key[4].length = 0;
2387 key[4].key = NULL;
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;
2407 key[3].length = 1;
2408 key[3].key = &pinfo->num;
2409 wmem_tree_insert32_array(connection_parameter_info_tree, key, connection_parameter_info);
2412 break;
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;
2421 uint32_t adi;
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);
2433 offset += 1;
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);
2441 offset += 1;
2443 acad_len -= 1;
2444 } else {
2445 flags = 0;
2448 if (flags & 0x01) {
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);
2455 acad_len -= 6;
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);
2463 if (flags & 0x02) {
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);
2470 acad_len -= 6;
2471 } else {
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);
2477 if (flags & 0x04) {
2478 uint32_t cte_time;
2480 /* CTE Info */
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);
2488 offset += 1;
2490 acad_len -= 1;
2493 if (flags & 0x08) {
2494 /* AdvDataInfo */
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);
2500 offset += 2;
2501 adi_present = true;
2503 acad_len -= 2;
2506 if (flags & 0x10) {
2507 uint32_t aux_offset;
2509 /* Aux Pointer */
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);
2517 offset += 1;
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));
2522 offset += 2;
2523 aux_pointer_present = true;
2525 acad_len -= 3;
2528 if (flags & 0x20) {
2529 uint32_t sync_offset, interval;
2530 proto_item *sync_info_item;
2531 proto_tree *sync_info_tree;
2532 int reserved_offset;
2533 uint16_t sf;
2535 /* Sync Info */
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);
2544 key[0].length = 1;
2545 key[0].key = &interface_id;
2546 key[1].length = 1;
2547 key[1].key = &adapter_id;
2548 key[2].length = 1;
2549 key[2].key = &connection_access_address;
2550 key[3].length = 1;
2551 key[3].key = &pinfo->num;
2552 key[4].length = 0;
2553 key[4].key = NULL;
2555 connection_info = wmem_new0(wmem_file_scope(), connection_info_t);
2557 if (flags & 0x01)
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;
2572 key[3].length = 1;
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));
2585 } else {
2586 proto_item_append_text(item, " Cannot be represented");
2588 offset += 2;
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);
2592 offset += 2;
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);
2599 offset += 5;
2601 proto_tree_add_item(sync_info_tree, hf_extended_advertising_sync_info_access_address, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2602 offset += 4;
2604 proto_tree_add_item(sync_info_tree, hf_extended_advertising_sync_info_crc_init, tvb, offset, 3, ENC_LITTLE_ENDIAN);
2605 offset += 3;
2607 proto_tree_add_item(sync_info_tree, hf_extended_advertising_sync_info_event_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2608 offset += 2;
2610 acad_len -= 18;
2613 if (flags & 0x40) {
2614 /* Tx Power */
2615 proto_tree_add_item(ext_header_tree, hf_extended_advertising_tx_power, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2616 offset += 1;
2618 acad_len -= 1;
2621 if (acad_len > 0) {
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);
2629 offset += acad_len;
2631 if (tvb_reported_length_remaining(tvb, offset) > 3) {
2632 bool ad_processed = false;
2633 if (btle_context &&
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;
2649 if (flags & 0x01) {
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,
2666 tvb, offset, pinfo,
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;
2676 break;
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,
2702 tvb, offset, pinfo,
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;
2715 break;
2716 default:
2717 /* This field is 2 bits long, no special action needed */
2718 break;
2720 if (ad_processed) {
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(
2739 tvb, offset, pinfo,
2740 "Reassembled Host Advertising Data", fd_head,
2741 &btle_ea_host_advertising_data_frag_items,
2742 NULL, btle_tree);
2744 if (assembled_tvb) {
2745 dissect_ad_eir(assembled_tvb, interface_id, adapter_id, pinfo->num, src_bd_addr, pinfo, btle_tree);
2749 else {
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) {
2762 /* AUX_SCAN_RSP */
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);
2768 else {
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;
2775 break;
2777 default:
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;
2784 return offset;
2787 static int
2788 dissect_btle_acl(tvbuff_t *tvb,
2789 packet_info *pinfo,
2790 proto_tree *tree,
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;
2799 int offset = 0;
2800 uint32_t length;
2801 tvbuff_t *next_tvb;
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;
2808 proto_item *item;
2809 unsigned item_value;
2811 proto_item *data_header_item, *seq_item, *control_proc_item;
2812 proto_tree *data_header_tree;
2813 uint8_t oct;
2814 uint8_t llid;
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};
2826 if (btle_context) {
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};
2835 key[0].length = 1;
2836 key[0].key = &interface_id;
2837 key[1].length = 1;
2838 key[1].key = &adapter_id;
2839 key[2].length = 1;
2840 key[2].key = &access_address;
2841 key[3].length = 0;
2842 key[3].key = NULL;
2844 oct = tvb_get_uint8(tvb, offset);
2845 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(connection_info_tree, key);
2846 if (wmem_tree) {
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);
2868 break;
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);
2874 break;
2875 default:
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);
2881 break;
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) {
2906 address *addr;
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;
2926 else {
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;
2932 } else {
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;
2940 } else {
2941 btle_frame_info->ack = 0;
2944 p_add_proto_data(wmem_file_scope(), pinfo, proto_btle, pinfo->curr_layer_num, btle_frame_info);
2946 else {
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]");
2969 } else {
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]");
2982 else {
2983 proto_item_append_text(seq_item, " [Retransmit]");
2984 if (btle_detect_retransmit) {
2985 expert_add_info(pinfo, seq_item, &ei_retransmit);
2986 retransmit = true;
2991 llid = oct & 0x03;
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);
2997 offset += 1;
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);
3002 offset += 1;
3004 if (cte_info_present) {
3005 uint32_t cte_time;
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);
3014 offset += 1;
3017 switch (llid) {
3018 case 0x01: /* Continuation fragment of an L2CAP message, or an Empty PDU */
3019 if (length > 0) {
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;
3028 } else {
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;
3038 l2cap_index++;
3040 if (connection_info->direction_info[direction].segment_len_rem > 0) {
3041 btle_frame_info->more_fragments = 1;
3043 else {
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;
3048 } else {
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;
3058 l2cap_index++;
3062 add_l2cap_index = true;
3064 frag_btl2cap_msg = fragment_add_seq_next(&btle_l2cap_msg_reassembly_table,
3065 tvb, offset,
3066 pinfo,
3067 btle_frame_info->l2cap_index, /* uint32_t ID for fragments belonging together */
3068 NULL, /* data* */
3069 length, /* Fragment length */
3070 btle_frame_info->more_fragments); /* More fragments */
3072 new_tvb = process_reassembled_data(tvb, offset, pinfo,
3073 "Reassembled L2CAP",
3074 frag_btl2cap_msg,
3075 &btle_l2cap_msg_frag_items,
3076 NULL,
3077 btle_tree);
3080 if (new_tvb) {
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);
3097 if (next_tvb) {
3098 call_dissector_with_data(btl2cap_handle, new_tvb, pinfo, tree, acl_data);
3100 offset += length;
3102 else {
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);
3108 offset += length;
3110 } else {
3111 col_set_str(pinfo->cinfo, COL_INFO, "Empty PDU");
3114 break;
3115 case 0x02: /* Start of an L2CAP message or a complete L2CAP message with no fragmentation */
3116 if (length > 0) {
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;
3130 l2cap_index++;
3133 add_l2cap_index = true;
3135 frag_btl2cap_msg = fragment_add_seq_next(&btle_l2cap_msg_reassembly_table,
3136 tvb, offset,
3137 pinfo,
3138 btle_frame_info->l2cap_index, /* uint32_t ID for fragments belonging together */
3139 NULL, /* data* */
3140 length, /* Fragment length */
3141 btle_frame_info->more_fragments); /* More fragments */
3143 process_reassembled_data(tvb, offset, pinfo,
3144 "Reassembled L2CAP",
3145 frag_btl2cap_msg,
3146 &btle_l2cap_msg_frag_items,
3147 NULL,
3148 btle_tree);
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);
3153 offset += length;
3154 } else {
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;
3160 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);
3181 offset += length;
3184 break;
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);
3188 offset += 1;
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);
3197 offset += 1;
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);
3201 offset += 2;
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);
3205 offset += 2;
3207 proto_tree_add_item(btle_tree, hf_control_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3208 offset += 2;
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);
3212 offset += 2;
3214 proto_tree_add_item_ret_uint(btle_tree, hf_control_instant, tvb, offset, 2, ENC_LITTLE_ENDIAN, &item_value);
3215 offset += 2;
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;
3227 } else {
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.
3232 key[0].length = 1;
3233 key[0].key = &interface_id;
3234 key[1].length = 1;
3235 key[1].key = &adapter_id;
3236 key[2].length = 1;
3237 key[2].key = &access_address;
3238 key[3].length = 1;
3239 key[3].key = &pinfo->num;
3240 key[4].length = 0;
3241 key[4].key = NULL;
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,
3256 pinfo,
3257 btle_tree,
3258 control_opcode,
3259 direction,
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,
3267 pinfo,
3268 btle_tree,
3269 control_opcode,
3270 direction,
3271 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3272 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3274 } else {
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],
3279 control_opcode);
3281 if (proc_info) {
3282 if (btle_context && btle_context->event_counter_valid) {
3283 proc_info->instant = item_value;
3284 proc_info->frame_with_instant_value = pinfo->num;
3285 } else {
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);
3297 break;
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);
3303 offset += 5;
3305 proto_tree_add_item_ret_uint(btle_tree, hf_control_instant, tvb, offset, 2, ENC_LITTLE_ENDIAN, &item_value);
3306 offset += 2;
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,
3317 pinfo,
3318 btle_tree,
3319 btle_context,
3320 control_opcode,
3321 direction,
3322 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3323 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3325 item_value);
3326 } else {
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],
3331 control_opcode);
3333 if (proc_info) {
3334 if (btle_context && btle_context->event_counter_valid) {
3335 proc_info->instant = item_value;
3336 proc_info->frame_with_instant_value = pinfo->num;
3337 } else {
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);
3348 break;
3349 case LL_CTRL_OPCODE_TERMINATE_IND:
3350 proto_tree_add_item(btle_tree, hf_control_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3351 offset += 1;
3353 /* No need to mark procedure as started, as the procedure only consist
3354 * of one packet which may be sent at any time, */
3356 break;
3357 case LL_CTRL_OPCODE_ENC_REQ:
3358 proto_tree_add_item(btle_tree, hf_control_random_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3359 offset += 8;
3361 proto_tree_add_item(btle_tree, hf_control_encrypted_diversifier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3362 offset += 2;
3364 proto_tree_add_item(btle_tree, hf_control_central_session_key_diversifier, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3365 offset += 8;
3367 proto_tree_add_item(btle_tree, hf_control_central_session_initialization_vector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3368 offset += 4;
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],
3376 control_opcode);
3377 } else if (direction == BTLE_DIR_PERIPHERAL_CENTRAL) {
3378 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3382 break;
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);
3385 offset += 8;
3387 proto_tree_add_item(btle_tree, hf_control_peripheral_session_initialization_vector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3388 offset += 4;
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,
3397 pinfo,
3398 btle_tree,
3399 control_opcode,
3400 direction,
3401 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3402 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3404 } else {
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);
3412 break;
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,
3422 pinfo,
3423 btle_tree,
3424 control_opcode,
3425 direction,
3426 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3427 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3429 } else {
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);
3437 break;
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,
3448 pinfo,
3449 btle_tree,
3450 control_opcode,
3451 direction,
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,
3460 pinfo,
3461 btle_tree,
3462 control_opcode,
3463 direction,
3464 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3465 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3467 } else {
3468 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3472 break;
3474 case LL_CTRL_OPCODE_UNKNOWN_RSP:
3475 proto_tree_add_item(btle_tree, hf_control_unknown_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3476 offset += 1;
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,
3484 1)) {
3485 control_proc_add_last_frame(tvb,
3486 pinfo,
3487 btle_tree,
3488 control_opcode,
3489 direction,
3490 last_control_proc[other_direction],
3491 last_control_proc[direction],
3493 } else {
3494 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3498 break;
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],
3507 control_opcode);
3508 } else if (direction == BTLE_DIR_PERIPHERAL_CENTRAL) {
3509 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3513 break;
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,
3524 pinfo,
3525 btle_tree,
3526 control_opcode,
3527 direction,
3528 last_control_proc[other_direction],
3529 last_control_proc[direction],
3531 } else {
3532 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3536 break;
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],
3549 control_opcode);
3550 } else if (direction == BTLE_DIR_PERIPHERAL_CENTRAL) {
3551 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3555 break;
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,
3565 pinfo,
3566 btle_tree,
3567 control_opcode,
3568 direction,
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,
3577 pinfo,
3578 btle_tree,
3579 control_opcode,
3580 direction,
3581 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3582 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3584 } else {
3585 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3589 break;
3590 case LL_CTRL_OPCODE_VERSION_IND:
3591 proto_tree_add_item(btle_tree, hf_control_version_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3592 offset += 1;
3594 proto_tree_add_item(btle_tree, hf_control_company_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3595 offset += 2;
3597 proto_tree_add_item(btle_tree, hf_control_subversion_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3598 offset += 2;
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,
3607 pinfo,
3608 btle_tree,
3609 control_opcode,
3610 direction,
3611 last_control_proc[other_direction],
3612 last_control_proc[direction],
3614 } else {
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],
3618 control_opcode);
3622 break;
3623 case LL_CTRL_OPCODE_REJECT_IND:
3624 proto_tree_add_item(btle_tree, hf_control_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3625 offset += 1;
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,
3636 pinfo,
3637 btle_tree,
3638 control_opcode,
3639 direction,
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,
3647 pinfo,
3648 btle_tree,
3649 control_opcode,
3650 direction,
3651 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3652 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3654 } else {
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);
3662 break;
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],
3671 control_opcode);
3672 } else if (direction == BTLE_DIR_CENTRAL_PERIPHERAL) {
3673 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3676 break;
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],
3685 control_opcode);
3689 break;
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,
3701 pinfo,
3702 btle_tree,
3703 control_opcode,
3704 direction,
3705 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3706 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3708 } else {
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);
3716 break;
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);
3719 offset += 1;
3721 proto_tree_add_item(btle_tree, hf_control_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3722 offset += 1;
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,
3742 pinfo,
3743 btle_tree,
3744 control_opcode,
3745 direction,
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,
3754 pinfo,
3755 btle_tree,
3756 control_opcode,
3757 direction,
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,
3765 pinfo,
3766 btle_tree,
3767 control_opcode,
3768 direction,
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,
3776 pinfo,
3777 btle_tree,
3778 control_opcode,
3779 direction,
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,
3787 pinfo,
3788 btle_tree,
3789 control_opcode,
3790 direction,
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,
3798 pinfo,
3799 btle_tree,
3800 control_opcode,
3801 direction,
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,
3809 pinfo,
3810 btle_tree,
3811 control_opcode,
3812 direction,
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,
3820 pinfo,
3821 btle_tree,
3822 control_opcode,
3823 direction,
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,
3831 pinfo,
3832 btle_tree,
3833 control_opcode,
3834 direction,
3835 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3836 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3838 } else {
3839 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3843 break;
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],
3850 control_opcode);
3852 break;
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,
3860 pinfo,
3861 btle_tree,
3862 control_opcode,
3863 direction,
3864 last_control_proc[other_direction],
3865 last_control_proc[direction],
3867 } else {
3868 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3871 break;
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],
3879 control_opcode);
3882 break;
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,
3890 pinfo,
3891 btle_tree,
3892 control_opcode,
3893 direction,
3894 last_control_proc[other_direction],
3895 last_control_proc[direction],
3897 } else {
3898 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
3901 break;
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],
3908 control_opcode);
3911 break;
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,
3921 pinfo,
3922 btle_tree,
3923 control_opcode,
3924 direction,
3925 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3926 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3928 } else {
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);
3936 break;
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");
3945 offset += 1;
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");
3951 offset += 1;
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);
3955 } else {
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);
3961 offset += 2;
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,
3970 pinfo,
3971 btle_tree,
3972 btle_context,
3973 control_opcode,
3974 direction,
3975 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3976 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3978 item_value);
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,
3983 pinfo,
3984 btle_tree,
3985 btle_context,
3986 control_opcode,
3987 direction,
3988 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
3989 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
3991 item_value);
3992 } else {
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);
4000 break;
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);
4004 offset += 1;
4006 proto_tree_add_item(btle_tree, hf_control_min_used_channels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4007 offset += 1;
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],
4016 control_opcode);
4018 /* Procedure completes in the same frame. */
4019 if (proc_info) {
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);
4026 break;
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);
4029 offset += 1;
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],
4034 control_opcode);
4036 break;
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,
4044 pinfo,
4045 btle_tree,
4046 control_opcode,
4047 direction,
4048 last_control_proc[other_direction],
4049 last_control_proc[direction],
4051 } else {
4052 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4055 break;
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],
4063 control_opcode);
4065 /* Procedure completes in the same frame. */
4066 if (proc_info) {
4067 proc_info->last_frame = pinfo->num;
4070 break;
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);
4073 offset += 1;
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],
4078 control_opcode);
4080 break;
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);
4083 offset += 1;
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,
4089 pinfo,
4090 btle_tree,
4091 control_opcode,
4092 direction,
4093 last_control_proc[other_direction],
4094 last_control_proc[direction],
4096 } else {
4097 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4100 break;
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],
4108 control_opcode);
4109 } else if (direction == BTLE_DIR_PERIPHERAL_CENTRAL) {
4110 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4113 break;
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,
4121 pinfo,
4122 btle_tree,
4123 control_opcode,
4124 direction,
4125 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
4126 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
4128 } else {
4129 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4132 break;
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);
4139 key[0].length = 1;
4140 key[0].key = &interface_id;
4141 key[1].length = 1;
4142 key[1].key = &adapter_id;
4143 key[2].length = 1;
4144 key[2].key = &connection_access_address;
4145 key[3].length = 1;
4146 key[3].key = &pinfo->num;
4147 key[4].length = 0;
4148 key[4].key = NULL;
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,
4164 pinfo,
4165 btle_tree,
4166 control_opcode,
4167 direction,
4168 last_control_proc[BTLE_DIR_CENTRAL_PERIPHERAL],
4169 last_control_proc[BTLE_DIR_PERIPHERAL_CENTRAL],
4171 } else {
4172 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4175 break;
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],
4183 control_opcode);
4185 /* Procedure completes in the same frame. */
4186 if (proc_info) {
4187 proc_info->last_frame = pinfo->num;
4190 break;
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],
4197 control_opcode);
4199 break;
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,
4207 pinfo,
4208 btle_tree,
4209 control_opcode,
4210 direction,
4211 last_control_proc[other_direction],
4212 last_control_proc[direction],
4214 } else {
4215 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4218 break;
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],
4226 control_opcode);
4228 /* Procedure completes in the same frame. */
4229 if (proc_info) {
4230 proc_info->last_frame = pinfo->num;
4233 break;
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],
4241 control_opcode);
4242 } else if (direction == BTLE_DIR_CENTRAL_PERIPHERAL) {
4243 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4246 break;
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,
4254 pinfo,
4255 btle_tree,
4256 control_opcode,
4257 direction,
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],
4266 control_opcode);
4268 /* Procedure completes in the same frame. */
4269 if (proc_info) {
4270 proc_info->last_frame = pinfo->num;
4272 } else {
4273 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4276 break;
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],
4285 control_opcode);
4287 /* Procedure completes in the same frame. */
4288 if (proc_info) {
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);
4295 break;
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],
4304 control_opcode);
4306 /* Procedure completes in the same frame. */
4307 if (proc_info) {
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);
4314 break;
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],
4322 control_opcode);
4324 /* Procedure completes in the same frame. */
4325 if (proc_info) {
4326 proc_info->last_frame = pinfo->num;
4329 break;
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],
4335 control_opcode);
4337 break;
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,
4344 pinfo,
4345 btle_tree,
4346 control_opcode,
4347 direction,
4348 last_control_proc[other_direction],
4349 last_control_proc[direction],
4351 } else {
4352 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4355 break;
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],
4363 control_opcode);
4364 } else if (direction == BTLE_DIR_PERIPHERAL_CENTRAL) {
4365 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4368 break;
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,
4375 pinfo,
4376 btle_tree,
4377 control_opcode,
4378 direction,
4379 last_control_proc[other_direction],
4380 last_control_proc[direction],
4382 } else {
4383 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4386 break;
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],
4392 control_opcode);
4394 break;
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,
4401 pinfo,
4402 btle_tree,
4403 control_opcode,
4404 direction,
4405 last_control_proc[other_direction],
4406 last_control_proc[direction],
4408 } else {
4409 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4412 break;
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],
4418 control_opcode);
4420 break;
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,
4427 pinfo,
4428 btle_tree,
4429 control_opcode,
4430 direction,
4431 last_control_proc[other_direction],
4432 last_control_proc[direction],
4434 } else {
4435 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4438 break;
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. */
4444 break;
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],
4450 control_opcode);
4452 break;
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,
4459 pinfo,
4460 btle_tree,
4461 control_opcode,
4462 direction,
4463 last_control_proc[other_direction],
4464 last_control_proc[direction],
4466 } else {
4467 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4470 break;
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],
4476 control_opcode);
4478 break;
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,
4485 pinfo,
4486 btle_tree,
4487 control_opcode,
4488 direction,
4489 last_control_proc[other_direction],
4490 last_control_proc[direction],
4492 } else {
4493 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4496 break;
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],
4505 control_opcode);
4507 break;
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,
4514 pinfo,
4515 btle_tree,
4516 control_opcode,
4517 direction,
4518 last_control_proc[other_direction],
4519 last_control_proc[direction],
4521 } else {
4522 expert_add_info(pinfo, control_proc_item, &ei_control_proc_wrong_seq);
4525 break;
4526 default:
4527 offset = dissect_ctrl_pdu_without_data(tvb, pinfo, btle_tree, offset);
4528 break;
4531 break;
4533 default:
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);
4545 key[0].length = 1;
4546 key[0].key = &interface_id;
4547 key[1].length = 1;
4548 key[1].key = &adapter_id;
4549 key[2].length = 1;
4550 key[2].key = &access_address;
4551 key[3].length = 0;
4552 key[3].key = NULL;
4553 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(connection_parameter_info_tree, key);
4554 if (wmem_tree) {
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);
4572 return offset;
4576 static int
4577 dissect_btle_connected_iso(tvbuff_t *tvb,
4578 packet_info *pinfo,
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;
4586 int offset = 0;
4587 uint32_t length;
4588 connectediso_connection_info_t *connection_info = NULL;
4589 wmem_tree_t *wmem_tree;
4590 wmem_tree_key_t key[5];
4592 proto_item *item;
4594 proto_item *data_header_item;
4595 proto_tree *data_header_tree;
4596 uint8_t oct;
4597 uint8_t llid;
4598 uint32_t direction = BTLE_DIR_UNKNOWN;
4600 if (btle_context) {
4601 direction = btle_context->direction;
4604 btle_frame_info_t *btle_frame_info = NULL;
4606 key[0].length = 1;
4607 key[0].key = &interface_id;
4608 key[1].length = 1;
4609 key[1].key = &adapter_id;
4610 key[2].length = 1;
4611 key[2].key = &access_address;
4612 key[3].length = 0;
4613 key[3].key = NULL;
4615 oct = tvb_get_uint8(tvb, offset);
4616 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(connection_info_tree, key);
4617 if (wmem_tree) {
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);
4639 break;
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);
4645 break;
4646 default:
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);
4652 break;
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) {
4662 address *addr;
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);
4685 llid = oct & 0x03;
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);
4690 offset += 1;
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);
4695 offset += 1;
4697 switch (llid) {
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);
4702 offset += length;
4703 break;
4705 default:
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;
4712 return offset;
4716 static int
4717 dissect_btle_broadcast_iso(tvbuff_t *tvb,
4718 packet_info *pinfo,
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;
4726 int offset = 0;
4727 uint32_t length;
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];
4732 proto_item *item;
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;
4739 uint8_t llid;
4740 uint8_t control_opcode;
4742 key[0].length = 1;
4743 key[0].key = &interface_id;
4744 key[1].length = 1;
4745 key[1].key = &adapter_id;
4746 key[2].length = 1;
4747 key[2].key = &seed_access_address;
4748 key[3].length = 0;
4749 key[3].key = NULL;
4751 wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(broadcastiso_connection_info_tree, key);
4752 if (wmem_tree) {
4753 broadcastiso_connection_info = (broadcastiso_connection_info_t *) wmem_tree_lookup32_le(wmem_tree, pinfo->num);
4754 if (broadcastiso_connection_info) {
4755 char *str_addr_src;
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) {
4772 address *addr;
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);
4793 offset += 1;
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);
4798 offset += 1;
4800 switch (llid) {
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);
4805 offset += length;
4806 break;
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);
4811 offset += 1;
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);
4822 offset += 5;
4824 proto_tree_add_item_ret_uint(btle_tree, hf_control_instant, tvb, offset, 2, ENC_LITTLE_ENDIAN, &item_value);
4825 offset += 2;
4826 break;
4828 case 0x01: /* BIG_TERMINATE_IND */
4829 proto_tree_add_item(btle_tree, hf_control_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4830 offset += 1;
4831 proto_tree_add_item_ret_uint(btle_tree, hf_control_instant, tvb, offset, 2, ENC_LITTLE_ENDIAN, &item_value);
4832 offset += 2;
4833 break;
4835 default:
4836 offset = dissect_ctrl_pdu_without_data(tvb, pinfo, btle_tree, offset);
4837 break;
4839 break;
4841 default:
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;
4848 return offset;
4851 static int
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;
4857 int offset = 0;
4858 uint32_t access_address, length;
4859 tvbuff_t *next_tvb;
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,
4867 data,
4868 &adapter_id,
4869 &interface_id);
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);
4878 if (btle_context) {
4879 switch(btle_context->aa_category) {
4880 case E_AA_MATCHED:
4881 expert_add_info(pinfo, sub_item, &ei_access_address_matched);
4882 break;
4883 case E_AA_ILLEGAL:
4884 expert_add_info(pinfo, sub_item, &ei_access_address_illegal);
4885 break;
4886 case E_AA_BIT_ERRORS:
4887 expert_add_info(pinfo, sub_item, &ei_access_address_bit_errors);
4888 break;
4889 default:
4890 break;
4893 offset += 4;
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);
4897 offset += 1;
4900 if (btle_context) {
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,
4907 adapter_id,
4908 access_address);
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,
4914 pinfo,
4915 btle_tree,
4916 btle_context,
4917 adapter_id,
4918 interface_id,
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,
4924 pinfo,
4925 tree,
4926 btle_tree,
4927 btle_context,
4928 adapter_id,
4929 interface_id,
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,
4935 pinfo,
4936 btle_tree,
4937 btle_context,
4938 adapter_id,
4939 interface_id,
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,
4945 pinfo,
4946 btle_tree,
4947 adapter_id,
4948 interface_id,
4949 access_address) - 2;
4950 offset += length + 2;
4951 } else {
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;
4956 offset += length;
4957 } else {
4958 /* Length is unknown. */
4959 length = 0;
4963 offset += dissect_crc(tvb,
4964 btle_tree,
4965 offset,
4966 pinfo,
4967 length,
4968 connection_info,
4969 btle_context,
4970 access_address);
4972 return offset;
4975 void
4976 proto_register_btle(void)
4978 module_t *module;
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,
4985 NULL, HFILL }
4987 { &hf_coding_indicator,
4988 { "Coding Indicator", "btle.coding_indicator",
4989 FT_UINT8, BASE_DEC, VALS(le_coding_indicators), 0x3,
4990 NULL, HFILL }
4992 { &hf_central_bd_addr,
4993 { "Central Address", "btle.central_bd_addr",
4994 FT_ETHER, BASE_NONE, NULL, 0x0,
4995 NULL, HFILL }
4997 { &hf_peripheral_bd_addr,
4998 { "Peripheral Address", "btle.peripheral_bd_addr",
4999 FT_ETHER, BASE_NONE, NULL, 0x0,
5000 NULL, HFILL }
5002 { &hf_length,
5003 { "Length", "btle.length",
5004 FT_UINT8, BASE_DEC, NULL, 0x0,
5005 NULL, HFILL }
5007 { &hf_advertising_header,
5008 { "Packet Header", "btle.advertising_header",
5009 FT_UINT16, BASE_HEX, NULL, 0x0,
5010 NULL, HFILL }
5012 { &hf_advertising_header_pdu_type,
5013 { "PDU Type", "btle.advertising_header.pdu_type",
5014 FT_UINT8, BASE_HEX, NULL, 0x0F,
5015 NULL, HFILL }
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,
5025 NULL, HFILL }
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,
5035 NULL, HFILL }
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,
5045 NULL, HFILL }
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,
5055 NULL, HFILL }
5057 { &hf_advertising_address,
5058 { "Advertising Address", "btle.advertising_address",
5059 FT_ETHER, BASE_NONE, NULL, 0x0,
5060 NULL, HFILL }
5062 { &hf_initiator_addresss,
5063 { "Initiator Address", "btle.initiator_address",
5064 FT_ETHER, BASE_NONE, NULL, 0x0,
5065 NULL, HFILL }
5067 { &hf_target_addresss,
5068 { "Target Address", "btle.target_address",
5069 FT_ETHER, BASE_NONE, NULL, 0x0,
5070 NULL, HFILL }
5072 { &hf_scanning_address,
5073 { "Scanning Address", "btle.scanning_address",
5074 FT_ETHER, BASE_NONE, NULL, 0x0,
5075 NULL, HFILL }
5077 { &hf_scan_response_data,
5078 { "Scan Response Data", "btle.scan_response_data",
5079 FT_BYTES, BASE_NONE, NULL, 0x0,
5080 NULL, HFILL }
5082 { &hf_link_layer_data,
5083 { "Link Layer Data", "btle.link_layer_data",
5084 FT_NONE, BASE_NONE, NULL, 0x0,
5085 NULL, HFILL }
5087 { &hf_link_layer_data_access_address,
5088 { "Access Address", "btle.link_layer_data.access_address",
5089 FT_UINT32, BASE_HEX, NULL, 0x0,
5090 NULL, HFILL }
5092 { &hf_link_layer_data_crc_init,
5093 { "CRC Init", "btle.link_layer_data.crc_init",
5094 FT_UINT24, BASE_HEX, NULL, 0x0,
5095 NULL, HFILL }
5097 { &hf_link_layer_data_window_size,
5098 { "Window Size", "btle.link_layer_data.window_size",
5099 FT_UINT8, BASE_DEC, NULL, 0x0,
5100 NULL, HFILL }
5102 { &hf_link_layer_data_window_offset,
5103 { "Window Offset", "btle.link_layer_data.window_offset",
5104 FT_UINT16, BASE_DEC, NULL, 0x0,
5105 NULL, HFILL }
5107 { &hf_link_layer_data_interval,
5108 { "Interval", "btle.link_layer_data.interval",
5109 FT_UINT16, BASE_DEC, NULL, 0x0,
5110 NULL, HFILL }
5112 { &hf_link_layer_data_latency,
5113 { "Latency", "btle.link_layer_data.latency",
5114 FT_UINT16, BASE_DEC, NULL, 0x0,
5115 NULL, HFILL }
5117 { &hf_link_layer_data_timeout,
5118 { "Timeout", "btle.link_layer_data.timeout",
5119 FT_UINT16, BASE_DEC, NULL, 0x0,
5120 NULL, HFILL }
5122 { &hf_link_layer_data_channel_map,
5123 { "Channel Map", "btle.link_layer_data.channel_map",
5124 FT_BYTES, BASE_NONE, NULL, 0x0,
5125 NULL, HFILL }
5127 { &hf_link_layer_data_hop,
5128 { "Hop", "btle.link_layer_data.hop",
5129 FT_UINT8, BASE_DEC, NULL, 0x1f,
5130 NULL, HFILL }
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,
5135 NULL, HFILL }
5137 { &hf_extended_advertising_header,
5138 { "Extended Advertising Header", "btle.extended_advertising_header",
5139 FT_NONE, BASE_NONE, NULL, 0x0,
5140 NULL, HFILL }
5142 { &hf_extended_advertising_header_length,
5143 { "Extended Header Length", "btle.extended_advertising_header.length",
5144 FT_UINT8, BASE_DEC, NULL, 0x3F,
5145 NULL, HFILL }
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,
5150 NULL, HFILL }
5152 { &hf_extended_advertising_flags,
5153 { "Extended Header Flags", "btle.extended_advertising_header.flags",
5154 FT_UINT8, BASE_HEX, NULL, 0x0,
5155 NULL, HFILL }
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,
5160 NULL, HFILL }
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,
5165 NULL, HFILL }
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,
5170 NULL, HFILL }
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,
5175 NULL, HFILL }
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,
5180 NULL, HFILL }
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,
5185 NULL, HFILL }
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,
5190 NULL, HFILL }
5192 { &hf_extended_advertising_flags_reserved,
5193 { "Reserved", "btle.extended_advertising_header.flags.reserved",
5194 FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x80,
5195 NULL, HFILL }
5197 { &hf_extended_advertising_cte_info,
5198 { "CTE Info", "btle.extended_advertising_header.cte_info",
5199 FT_UINT8, BASE_HEX, NULL, 0x0,
5200 NULL, HFILL }
5202 { &hf_extended_advertising_cte_info_time,
5203 { "CTE Time", "btle.extended_advertising_header.cte_info.time",
5204 FT_UINT8, BASE_HEX, NULL, 0x1F,
5205 NULL, HFILL }
5207 { &hf_extended_advertising_cte_info_rfu,
5208 { "RFU", "btle.extended_advertising_header.cte_info.rfu",
5209 FT_UINT8, BASE_HEX, NULL, 0x20,
5210 NULL, HFILL }
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,
5215 NULL, HFILL }
5217 { &hf_extended_advertising_data_info,
5218 { "Advertiser Data Info", "btle.extended_advertising.advertising_data_info",
5219 FT_UINT16, BASE_HEX, NULL, 0x0,
5220 NULL, HFILL }
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,
5225 NULL, HFILL }
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,
5230 NULL, HFILL }
5232 { &hf_extended_advertising_aux_ptr,
5233 { "Advertiser Aux Pointer", "btle.extended_advertising.aux_pointer",
5234 FT_NONE, BASE_NONE, NULL, 0x0,
5235 NULL, HFILL }
5237 { &hf_extended_advertising_aux_ptr_channel,
5238 { "Channel Index", "btle.extended_advertising_header.aux_pointer.channel",
5239 FT_UINT8, BASE_DEC, NULL, 0x3F,
5240 NULL, HFILL }
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,
5245 NULL, HFILL }
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,
5250 NULL, HFILL }
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,
5255 NULL, HFILL }
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,
5260 NULL, HFILL }
5262 { &hf_extended_advertising_sync_info,
5263 { "Advertiser Sync Info", "btle.extended_advertising.sync_info",
5264 FT_NONE, BASE_NONE, NULL, 0x0,
5265 NULL, HFILL }
5267 { &hf_extended_advertising_had_fragment,
5268 { "Host Advertising Data Fragment", "btle.extended_advertising.had_fragment",
5269 FT_NONE, BASE_NONE, NULL, 0x0,
5270 NULL, HFILL }
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,
5275 NULL, HFILL }
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,
5280 NULL, HFILL }
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,
5285 NULL, HFILL }
5287 { &hf_extended_advertising_sync_info_reserved,
5288 { "Reserved", "btle.extended_advertising_header.sync_info.reserved",
5289 FT_BOOLEAN, 16, NULL, 0x8000,
5290 NULL, HFILL }
5292 { &hf_extended_advertising_sync_info_interval,
5293 { "Interval", "btle.extended_advertising_header.sync_info.interval",
5294 FT_UINT16, BASE_HEX, NULL, 0,
5295 NULL, HFILL }
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,
5300 NULL, HFILL }
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,
5305 NULL, HFILL }
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,
5310 NULL, HFILL }
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,
5315 NULL, HFILL }
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,
5320 NULL, HFILL }
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,
5325 NULL, HFILL }
5327 { &hf_extended_advertising_header_acad,
5328 { "Additional Controller Advertising Data", "btle.extended_advertising_header.acad",
5329 FT_NONE, BASE_NONE, NULL, 0x0,
5330 NULL, HFILL }
5332 { &hf_data_header,
5333 { "Data Header", "btle.data_header",
5334 FT_NONE, BASE_NONE, NULL, 0x0,
5335 NULL, HFILL }
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,
5355 NULL, HFILL }
5357 { &hf_data_header_sequence_number,
5358 { "Sequence Number", "btle.data_header.sequence_number",
5359 FT_UINT8, BASE_DEC, NULL, 0x08,
5360 NULL, HFILL }
5362 { &hf_data_header_more_data,
5363 { "More Data", "btle.data_header.more_data",
5364 FT_BOOLEAN, 8, NULL, 0x10,
5365 NULL, HFILL }
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,
5370 NULL, HFILL }
5372 { &hf_data_header_length,
5373 { "Length", "btle.data_header.length",
5374 FT_UINT8, BASE_DEC, NULL, 0x0,
5375 NULL, HFILL }
5377 { &hf_data_header_cte_info,
5378 { "CTE Info", "btle.data_header.cte_info",
5379 FT_UINT8, BASE_HEX, NULL, 0x0,
5380 NULL, HFILL }
5382 { &hf_data_header_cte_info_time,
5383 { "CTE Time", "btle.data_header.cte_info.time",
5384 FT_UINT8, BASE_HEX, NULL, 0x1F,
5385 NULL, HFILL }
5387 { &hf_data_header_cte_info_rfu,
5388 { "RFU", "btle.data_header.cte_info.rfu",
5389 FT_UINT8, BASE_HEX, NULL, 0x20,
5390 NULL, HFILL }
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,
5395 NULL, HFILL }
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,
5415 NULL, HFILL }
5417 { &hf_data_header_null_pdu_indicator,
5418 { "Null PDU Indicator", "btle.data_header.null_pdu_indicator",
5419 FT_BOOLEAN, 8, NULL, 0x40,
5420 NULL, HFILL }
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,
5425 NULL, HFILL }
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,
5430 NULL, HFILL }
5432 { &hf_control_opcode,
5433 { "Control Opcode", "btle.control_opcode",
5434 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &control_opcode_vals_ext, 0x0,
5435 NULL, HFILL }
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,
5440 NULL, HFILL }
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,
5445 NULL, HFILL }
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,
5450 NULL, HFILL }
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,
5455 NULL, HFILL }
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,
5460 NULL, HFILL }
5462 { &hf_control_subversion_number,
5463 { "Subversion Number", "btle.control.subversion_number",
5464 FT_UINT16, BASE_HEX, NULL, 0x0,
5465 NULL, HFILL }
5467 { &hf_control_feature_set,
5468 { "Feature Set", "btle.control.feature_set",
5469 FT_UINT64, BASE_HEX, NULL, 0x0,
5470 NULL, HFILL }
5472 { &hf_control_feature_set_le_encryption,
5473 { "LE Encryption", "btle.control.feature_set.le_encryption",
5474 FT_BOOLEAN, 8, NULL, 0x01,
5475 NULL, HFILL }
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,
5480 NULL, HFILL }
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,
5485 NULL, HFILL }
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,
5490 NULL, HFILL }
5492 { &hf_control_feature_set_le_ping,
5493 { "LE Ping", "btle.control.feature_set.le_ping",
5494 FT_BOOLEAN, 8, NULL, 0x10,
5495 NULL, HFILL }
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,
5500 NULL, HFILL }
5502 { &hf_control_feature_set_ll_privacy,
5503 { "LL Privacy", "btle.control.feature_set.le_privacy",
5504 FT_BOOLEAN, 8, NULL, 0x40,
5505 NULL, HFILL }
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,
5510 NULL, HFILL }
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,
5515 NULL, HFILL }
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,
5520 NULL, HFILL }
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,
5525 NULL, HFILL }
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,
5530 NULL, HFILL }
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,
5535 NULL, HFILL }
5537 { &hf_control_feature_set_le_periodic_advertising,
5538 { "LE Periodic Advertising", "btle.control.feature_set.periodic_adv",
5539 FT_BOOLEAN, 8, NULL, 0x20,
5540 NULL, HFILL }
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,
5545 NULL, HFILL }
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,
5550 NULL, HFILL }
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,
5555 NULL, HFILL }
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,
5560 NULL, HFILL }
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,
5565 NULL, HFILL }
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,
5570 NULL, HFILL }
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,
5575 NULL, HFILL }
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,
5580 NULL, HFILL }
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,
5585 NULL, HFILL }
5587 { &hf_control_feature_set_cte_rx,
5588 { "Receiving Constant Tone Extensions", "btle.control.feature_set.cte_rx",
5589 FT_BOOLEAN, 8, NULL, 0x80,
5590 NULL, HFILL }
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,
5595 NULL, HFILL }
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,
5600 NULL, HFILL }
5602 { &hf_control_feature_set_sca_updates,
5603 { "Sleep Clock Accuracy Updates", "btle.control.feature_set.sca_updates",
5604 FT_BOOLEAN, 8, NULL, 0x04,
5605 NULL, HFILL }
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,
5610 NULL, HFILL }
5612 { &hf_control_feature_set_cis_central,
5613 { "Connected Isochronous Stream - Central", "btle.control.feature_set.cis_central",
5614 FT_BOOLEAN, 8, NULL, 0x10,
5615 NULL, HFILL }
5617 { &hf_control_feature_set_cis_peripheral,
5618 { "Connected Isochronous Stream - Peripheral", "btle.control.feature_set.cis_peripheral",
5619 FT_BOOLEAN, 8, NULL, 0x20,
5620 NULL, HFILL }
5622 { &hf_control_feature_set_iso_broadcast,
5623 { "Isochronous Broadcaster", "btle.control.feature_set.iso_broadcast",
5624 FT_BOOLEAN, 8, NULL, 0x40,
5625 NULL, HFILL }
5627 { &hf_control_feature_set_synchronized_receiver,
5628 { "Synchronized Receiver", "btle.control.feature_set.synchronized_receiver",
5629 FT_BOOLEAN, 8, NULL, 0x80,
5630 NULL, HFILL }
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,
5635 NULL, HFILL }
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,
5640 NULL, HFILL }
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,
5645 NULL, HFILL }
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,
5650 NULL, HFILL }
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,
5655 NULL, HFILL }
5657 { &hf_control_feature_set_connection_subrating,
5658 { "Connection Subrating", "btle.control.feature_set.connection_subrating",
5659 FT_BOOLEAN, 8, NULL, 0x20,
5660 NULL, HFILL }
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,
5665 NULL, HFILL }
5667 { &hf_control_feature_set_channel_classification,
5668 { "Channel Classification", "btle.control.feature_set.channel_classification",
5669 FT_BOOLEAN, 8, NULL, 0x80,
5670 NULL, HFILL }
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,
5675 NULL, HFILL}
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,
5680 NULL, HFILL}
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,
5685 NULL, HFILL}
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,
5690 NULL, HFILL}
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,
5695 NULL, HFILL}
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,
5700 NULL, HFILL}
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,
5705 NULL, HFILL}
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,
5710 NULL, HFILL}
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,
5715 NULL, HFILL}
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,
5720 NULL, HFILL}
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,
5725 NULL, HFILL}
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,
5730 NULL, HFILL}
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,
5735 NULL, HFILL}
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,
5740 NULL, HFILL}
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,
5745 NULL, HFILL}
5747 { &hf_control_window_size,
5748 { "Window Size", "btle.control.window_size",
5749 FT_UINT8, BASE_DEC, NULL, 0x0,
5750 NULL, HFILL }
5752 { &hf_control_window_offset,
5753 { "Window Offset", "btle.control.window_offset",
5754 FT_UINT16, BASE_DEC, NULL, 0x0,
5755 NULL, HFILL }
5757 { &hf_control_interval,
5758 { "Interval", "btle.control.interval",
5759 FT_UINT16, BASE_DEC, NULL, 0x0,
5760 NULL, HFILL }
5762 { &hf_control_latency,
5763 { "Latency", "btle.control.latency",
5764 FT_UINT16, BASE_DEC, NULL, 0x0,
5765 NULL, HFILL }
5767 { &hf_control_timeout,
5768 { "Timeout", "btle.control.timeout",
5769 FT_UINT16, BASE_DEC, NULL, 0x0,
5770 NULL, HFILL }
5772 { &hf_control_instant,
5773 { "Instant", "btle.control.instant",
5774 FT_UINT16, BASE_DEC, NULL, 0x0,
5775 NULL, HFILL }
5777 { &hf_control_rfu_5,
5778 { "Reserved for future use", "btle.control.reserved",
5779 FT_UINT16, BASE_DEC, NULL, 0x0,
5780 NULL, HFILL }
5782 { &hf_control_interval_min,
5783 { "Interval Min", "btle.control.interval.min",
5784 FT_UINT16, BASE_DEC, NULL, 0x0,
5785 NULL, HFILL }
5787 { &hf_control_interval_max,
5788 { "Interval Max", "btle.control.interval.max",
5789 FT_UINT16, BASE_DEC, NULL, 0x0,
5790 NULL, HFILL }
5792 { &hf_control_preferred_periodicity,
5793 { "Preferred Periodicity", "btle.control.preferred_periodicity",
5794 FT_UINT8, BASE_DEC, NULL, 0x0,
5795 NULL, HFILL }
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,
5800 NULL, HFILL }
5802 { &hf_control_offset_0,
5803 { "Offset 0", "btle.control.offset.0",
5804 FT_UINT16, BASE_DEC, NULL, 0x0,
5805 NULL, HFILL }
5807 { &hf_control_offset_1,
5808 { "Offset 1", "btle.control.offset.1",
5809 FT_UINT16, BASE_DEC, NULL, 0x0,
5810 NULL, HFILL }
5812 { &hf_control_offset_2,
5813 { "Offset 2", "btle.control.offset.2",
5814 FT_UINT16, BASE_DEC, NULL, 0x0,
5815 NULL, HFILL }
5817 { &hf_control_offset_3,
5818 { "Offset 3", "btle.control.offset.3",
5819 FT_UINT16, BASE_DEC, NULL, 0x0,
5820 NULL, HFILL }
5822 { &hf_control_offset_4,
5823 { "Offset 4", "btle.control.offset.4",
5824 FT_UINT16, BASE_DEC, NULL, 0x0,
5825 NULL, HFILL }
5827 { &hf_control_offset_5,
5828 { "Offset 5", "btle.control.offset.5",
5829 FT_UINT16, BASE_DEC, NULL, 0x0,
5830 NULL, HFILL }
5832 { &hf_control_channel_map,
5833 { "Channel Map", "btle.control.channel_map",
5834 FT_BYTES, BASE_NONE, NULL, 0x0,
5835 NULL, HFILL }
5837 { &hf_control_random_number,
5838 { "Random Number", "btle.control.random_number",
5839 FT_UINT64, BASE_DEC_HEX, NULL, 0x0,
5840 NULL, HFILL }
5842 { &hf_control_encrypted_diversifier,
5843 { "Encrypted Diversifier", "btle.control.encrypted_diversifier",
5844 FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5845 NULL, HFILL }
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,
5850 NULL, HFILL }
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,
5855 NULL, HFILL }
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,
5860 NULL, HFILL }
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,
5865 NULL, HFILL }
5867 { &hf_control_max_rx_octets,
5868 { "Max RX octets", "btle.control.max_rx_octets",
5869 FT_UINT16, BASE_DEC, NULL, 0x0,
5870 NULL, HFILL }
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,
5875 NULL, HFILL }
5877 { &hf_control_max_tx_octets,
5878 { "Max TX octets", "btle.control.max_tx_octets",
5879 FT_UINT16, BASE_DEC, NULL, 0x0,
5880 NULL, HFILL }
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,
5885 NULL, HFILL }
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,
5890 NULL, HFILL }
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,
5895 NULL, HFILL }
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,
5900 NULL, HFILL }
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,
5905 NULL, HFILL }
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,
5910 NULL, HFILL }
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,
5915 NULL, HFILL }
5917 { &hf_control_phys_reserved_bits,
5918 { "Reserved for future use", "btle.control.phys.reserved",
5919 FT_UINT8, BASE_DEC, NULL, 0xF8,
5920 NULL, HFILL }
5922 { &hf_control_tx_phys,
5923 { "TX PHYs", "btle.control.tx_phys",
5924 FT_UINT8, BASE_HEX, NULL, 0x0,
5925 NULL, HFILL }
5927 { &hf_control_rx_phys,
5928 { "RX PHYs", "btle.control.rx_phys",
5929 FT_UINT8, BASE_HEX, NULL, 0x0,
5930 NULL, HFILL }
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,
5935 NULL, HFILL }
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,
5940 NULL, HFILL }
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,
5945 NULL, HFILL }
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,
5950 NULL, HFILL }
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,
5955 NULL, HFILL }
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,
5960 NULL, HFILL }
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,
5965 NULL, HFILL }
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,
5970 NULL, HFILL }
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,
5975 NULL, HFILL }
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,
5980 NULL, HFILL }
5982 { &hf_control_phys,
5983 { "PHYs", "btle.control.phys",
5984 FT_UINT8, BASE_HEX, NULL, 0x0,
5985 NULL, HFILL }
5987 { &hf_control_phys_le_1m_phy,
5988 { "LE 1M PHY", "btle.control.phys.le_1m_phy",
5989 FT_BOOLEAN, 8, NULL, 0x01,
5990 NULL, HFILL }
5992 { &hf_control_phys_le_2m_phy,
5993 { "LE 2M PHY", "btle.control.phys.le_2m_phy",
5994 FT_BOOLEAN, 8, NULL, 0x02,
5995 NULL, HFILL }
5997 { &hf_control_phys_le_coded_phy,
5998 { "LE Coded PHY", "btle.control.phys.le_coded_phy",
5999 FT_BOOLEAN, 8, NULL, 0x04,
6000 NULL, HFILL }
6002 { &hf_control_min_used_channels,
6003 { "Minimum Used Channels", "btle.control.min_used_channels",
6004 FT_UINT8, BASE_DEC, NULL, 0x0,
6005 NULL, HFILL }
6007 { &hf_control_cte_min_len_req,
6008 { "MinCTELenReq", "btle.control.cte.min_len_req",
6009 FT_UINT8, BASE_DEC, NULL, 0x1F,
6010 NULL, HFILL }
6012 { &hf_control_cte_rfu,
6013 { "Reserved", "btle.control.cte.rfu",
6014 FT_UINT8, BASE_DEC, NULL, 0x20,
6015 NULL, HFILL }
6017 { &hf_control_cte_type_req,
6018 { "CTETypeReq", "btle.control.cte.type_req",
6019 FT_UINT8, BASE_DEC, VALS(le_cte_type_vals), 0xC0,
6020 NULL, HFILL }
6022 { &hf_control_sync_id,
6023 { "ID", "btle.control.sync.id",
6024 FT_UINT16, BASE_HEX, NULL, 0x0,
6025 NULL, HFILL }
6027 { &hf_control_sync_info_offset,
6028 { "Sync Offset", "btle.control.sync_info.sync_offset",
6029 FT_UINT16, BASE_HEX, NULL, 0x1FFF,
6030 NULL, HFILL }
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,
6035 NULL, HFILL }
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,
6040 NULL, HFILL }
6042 { &hf_control_sync_info_reserved,
6043 { "Reserved", "btle.control.sync_info.reserved",
6044 FT_BOOLEAN, 16, NULL, 0x8000,
6045 NULL, HFILL }
6047 { &hf_control_sync_info_interval,
6048 { "Interval", "btle.control.sync_info.interval",
6049 FT_UINT16, BASE_HEX, NULL, 0,
6050 NULL, HFILL }
6052 { &hf_control_sync_info_channel_map,
6053 { "Channel Map", "btle.control.sync_info.channel_map",
6054 FT_BYTES, BASE_NONE, NULL, 0x0,
6055 NULL, HFILL }
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,
6060 NULL, HFILL }
6062 { &hf_control_sync_info_access_address,
6063 { "Access Address", "btle.control.sync_info.access_address",
6064 FT_UINT32, BASE_HEX, NULL, 0x0,
6065 NULL, HFILL }
6067 { &hf_control_sync_info_crc_init,
6068 { "CRC Init", "btle.control.sync_info.crc_init",
6069 FT_UINT24, BASE_HEX, NULL, 0x0,
6070 NULL, HFILL }
6072 { &hf_control_sync_info_event_counter,
6073 { "Event counter", "btle.control.sync_info.event_counter",
6074 FT_UINT16, BASE_DEC, NULL, 0x0,
6075 NULL, HFILL }
6077 { &hf_control_sync_conn_event_count,
6078 { "connEventCount", "btle.control.sync.conn_event_count",
6079 FT_UINT16, BASE_DEC, NULL, 0x0,
6080 NULL, HFILL }
6082 { &hf_control_sync_last_pa_event_counter,
6083 { "lastPaEventCounter", "btle.control.sync.last_pa_event_counter",
6084 FT_UINT16, BASE_DEC, NULL, 0x0,
6085 NULL, HFILL }
6087 { &hf_control_sync_sid,
6088 { "SID", "btle.control.sync.sid",
6089 FT_UINT8, BASE_HEX, NULL, 0x0F,
6090 NULL, HFILL }
6092 { &hf_control_sync_atype,
6093 { "AType", "btle.control.sync.atype",
6094 FT_UINT8, BASE_DEC, NULL, 0x10,
6095 NULL, HFILL }
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,
6100 NULL, HFILL }
6102 { &hf_control_sync_sync_conn_event_counter,
6103 { "syncConnEventCount", "btle.control.sync.sync_conn_event_count",
6104 FT_UINT16, BASE_DEC, NULL, 0x0,
6105 NULL, HFILL }
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,
6110 NULL, HFILL }
6112 { &hf_control_cig_id,
6113 { "CIG_ID", "btle.control.cig_id",
6114 FT_UINT8, BASE_DEC, NULL, 0x0,
6115 NULL, HFILL }
6117 { &hf_control_cis_id,
6118 { "CIS_ID", "btle.control.cis_id",
6119 FT_UINT8, BASE_DEC, NULL, 0x0,
6120 NULL, HFILL }
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,
6125 NULL, HFILL }
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,
6135 NULL, HFILL }
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,
6140 NULL, HFILL }
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,
6150 NULL, HFILL }
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,
6160 NULL, HFILL }
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,
6170 NULL, HFILL }
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,
6175 NULL, HFILL }
6177 { &hf_control_num_sub_events,
6178 { "Num_Sub_Events", "btle.control.num_sub_events",
6179 FT_UINT8, BASE_DEC, NULL, 0x0,
6180 NULL, HFILL }
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,
6185 NULL, HFILL }
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,
6190 NULL, HFILL }
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,
6195 NULL, HFILL }
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,
6200 NULL, HFILL }
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,
6205 NULL, HFILL }
6207 { &hf_control_iso_interval,
6208 { "ISO_Interval", "btle.control.iso_interval",
6209 FT_UINT16, BASE_DEC, NULL, 0x0,
6210 NULL, HFILL }
6212 { &hf_control_cis_offset_min,
6213 { "CIS_Offset_Min", "btle.control.cis_offset_min",
6214 FT_UINT24, BASE_DEC, NULL, 0x0,
6215 NULL, HFILL }
6217 { &hf_control_cis_offset_max,
6218 { "CIS_Offset_Max", "btle.control.cis_offset_max",
6219 FT_UINT24, BASE_DEC, NULL, 0x0,
6220 NULL, HFILL }
6222 { &hf_control_conn_event_count,
6223 { "connEventCount", "btle.control.conn_event_count",
6224 FT_UINT16, BASE_DEC, NULL, 0x0,
6225 NULL, HFILL }
6227 { &hf_control_access_address,
6228 { "Access Address", "btle.control.access_address",
6229 FT_UINT32, BASE_HEX, NULL, 0x0,
6230 NULL, HFILL }
6232 { &hf_control_cis_offset,
6233 { "CIS_Offset", "btle.control.cis_offset",
6234 FT_UINT24, BASE_DEC, NULL, 0x0,
6235 NULL, HFILL }
6237 { &hf_control_cig_sync_delay,
6238 { "CIG_Sync_Delay", "btle.control.cig_sync_delay",
6239 FT_UINT24, BASE_DEC, NULL, 0x0,
6240 NULL, HFILL }
6242 { &hf_control_cis_sync_delay,
6243 { "CIS_Sync_Delay", "btle.control.cis_sync_delay",
6244 FT_UINT24, BASE_DEC, NULL, 0x0,
6245 NULL, HFILL }
6247 { &hf_control_pwr_phy,
6248 { "Power PHY", "btle.control.pwr_phy",
6249 FT_UINT8, BASE_HEX, NULL, 0x0,
6250 NULL, HFILL }
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,
6255 NULL, HFILL }
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,
6260 NULL, HFILL }
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,
6265 NULL, HFILL }
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,
6270 NULL, HFILL }
6272 { &hf_control_pwr_phy_reserved_bits,
6273 { "Reserved for future use", "btle.control.pwr_phy.reserved",
6274 FT_UINT8, BASE_DEC, NULL, 0xF0,
6275 NULL, HFILL }
6277 { &hf_control_delta,
6278 { "Delta", "btle.control.delta",
6279 FT_INT8, BASE_DEC, NULL, 0x0,
6280 NULL, HFILL }
6282 { &hf_control_txpwr,
6283 { "TxPower", "btle.control.txpower",
6284 FT_INT8, BASE_DEC, NULL, 0x0,
6285 NULL, HFILL }
6287 { &hf_control_pwrflags,
6288 { "Power Flags", "btle.control.pwrflags",
6289 FT_UINT8, BASE_HEX, NULL, 0x0,
6290 NULL, HFILL }
6292 { &hf_control_pwrflags_min,
6293 { "Min", "btle.control.min",
6294 FT_BOOLEAN, 8, NULL, 0x01,
6295 NULL, HFILL }
6297 { &hf_control_pwrflags_max,
6298 { "Max", "btle.control.max",
6299 FT_BOOLEAN, 8, NULL, 0x02,
6300 NULL, HFILL }
6302 { &hf_control_pwrflags_reserved_bits,
6303 { "Reserved for future use", "btle.control.pwrctrl.reserved",
6304 FT_UINT8, BASE_DEC, NULL, 0xFC,
6305 NULL, HFILL }
6307 { &hf_control_acceptable_power_reduction,
6308 { "Acceptable Power Reduction", "btle.control.acceptable_power_reduction",
6309 FT_UINT8, BASE_DEC, NULL, 0x0,
6310 NULL, HFILL }
6312 { &hf_control_subrate_factor_min,
6313 {"Minimum subrating factor", "btle.control.subrate_factor_min",
6314 FT_UINT16, BASE_DEC, NULL, 0x0,
6315 NULL, HFILL }
6317 { &hf_control_subrate_factor_max,
6318 {"Minimum subrating factor", "btle.control.subrate_factor_max",
6319 FT_UINT16, BASE_DEC, NULL, 0x0,
6320 NULL, HFILL }
6322 { &hf_control_max_latency,
6323 {"Maximum peripheral latency in subrated events", "btle.control.max_latency",
6324 FT_UINT16, BASE_DEC, NULL, 0x0,
6325 NULL, HFILL }
6327 { &hf_control_continuation_number,
6328 {"The minimum requested continuation number", "btle.control.continuation_number",
6329 FT_UINT16, BASE_DEC, NULL, 0x0,
6330 NULL, HFILL }
6332 { &hf_control_subrate_factor,
6333 {"Subrate factor", "btle.control.subrate_factor",
6334 FT_UINT16, BASE_DEC, NULL, 0x0,
6335 NULL, HFILL }
6337 { &hf_control_subrate_base_event,
6338 {"Subrate base event", "btle.control.subrate_base_event",
6339 FT_UINT16, BASE_DEC, NULL, 0x0,
6340 NULL, HFILL }
6342 { &hf_control_channel_reporting_enable,
6343 {"Enable channel reporting", "btle.control.channel_reporting_enable",
6344 FT_UINT8, BASE_DEC, NULL, 0x0,
6345 NULL, HFILL }
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,
6350 NULL, HFILL }
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,
6355 NULL, HFILL }
6357 { &hf_control_channel_classification,
6358 {"Channel classification", "btle.control.hf_control_channel_classification",
6359 FT_BYTES, BASE_NONE, NULL, 0x0,
6360 NULL, HFILL }
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,
6365 NULL, HFILL}
6367 { &hf_control_sync_info_num_subevents,
6368 {"Num subevents", "btle.control.sync_info.num_subevents",
6369 FT_UINT8, BASE_DEC, NULL, 0x0,
6370 NULL, HFILL}
6372 { &hf_control_sync_info_subevent_interval,
6373 {"Subevent interval", "btle.control.sync_info.subevent_interval",
6374 FT_UINT8, BASE_HEX, NULL, 0,
6375 NULL, HFILL}
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,
6380 NULL, HFILL}
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,
6385 NULL, HFILL}
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,
6390 NULL, HFILL }
6392 { &hf_l2cap_index,
6393 { "L2CAP Index", "btle.l2cap_index",
6394 FT_UINT32, BASE_DEC, NULL, 0x0,
6395 NULL, HFILL }
6397 { &hf_l2cap_fragment,
6398 { "L2CAP Fragment", "btle.l2cap_data",
6399 FT_NONE, BASE_NONE, NULL, 0x0,
6400 NULL, HFILL }
6402 { &hf_connection_parameters_in,
6403 { "Connection Parameters in", "btle.connection_parameters_in",
6404 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6405 NULL, HFILL }
6407 { &hf_crc,
6408 { "CRC", "btle.crc",
6409 FT_UINT24, BASE_HEX, NULL, 0x0,
6410 NULL, HFILL }
6412 { &hf_isochronous_data,
6413 { "Isochronous Data", "btle.isochronous_data",
6414 FT_BYTES, BASE_NONE, NULL, 0x0,
6415 NULL, HFILL }
6417 { &hf_btle_l2cap_msg_fragments,
6418 { "L2CAP fragments", "btle.l2cap.fragments",
6419 FT_NONE, BASE_NONE, NULL, 0x00,
6420 NULL, HFILL }
6422 { &hf_btle_l2cap_msg_fragment,
6423 { "L2CAP fragment", "btle.l2cap.fragment",
6424 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
6425 NULL, HFILL }
6427 { &hf_btle_l2cap_msg_fragment_overlap,
6428 { "L2CAP fragment overlap", "btle.l2cap.fragment.overlap",
6429 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
6430 NULL, HFILL }
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,
6435 NULL, HFILL }
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,
6440 NULL, HFILL }
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,
6445 NULL, HFILL }
6447 { &hf_btle_l2cap_msg_fragment_error,
6448 { "L2CAP defragmentation error", "btle.l2cap.fragment.error",
6449 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
6450 NULL, HFILL }
6452 { &hf_btle_l2cap_msg_fragment_count,
6453 { "L2CAP fragment count", "btle.l2cap.fragment.count",
6454 FT_UINT32, BASE_DEC, NULL, 0x00,
6455 NULL, HFILL }
6457 { &hf_btle_l2cap_msg_reassembled_in,
6458 { "Reassembled in", "btle.l2cap.reassembled.in",
6459 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
6460 NULL, HFILL }
6462 { &hf_btle_l2cap_msg_reassembled_length,
6463 { "Reassembled L2CAP length", "btle.l2cap.reassembled.length",
6464 FT_UINT32, BASE_DEC, NULL, 0x00,
6465 NULL, HFILL }
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,
6470 NULL, HFILL }
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,
6475 NULL, HFILL }
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,
6480 NULL, HFILL }
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,
6485 NULL, HFILL }
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,
6490 NULL, HFILL }
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,
6495 NULL, HFILL }
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,
6500 NULL, HFILL }
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,
6505 NULL, HFILL }
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,
6510 NULL, HFILL }
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,
6515 NULL, HFILL }
6517 { &hf_request_in_frame,
6518 {"Request in Frame", "btle.request_in_frame",
6519 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
6520 NULL, HFILL}
6522 { &hf_response_in_frame,
6523 {"Response in Frame", "btle.response_in_frame",
6524 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
6525 NULL, HFILL}
6529 static ei_register_info ei[] = {
6530 { &ei_unknown_data,
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 }},
6553 { &ei_retransmit,
6554 { "btle.retransmit", PI_SEQUENCE, PI_NOTE, "Retransmission", EXPFILL }},
6555 { &ei_nack,
6556 { "btle.nack", PI_SEQUENCE, PI_NOTE, "Not acknowledged", EXPFILL }},
6559 static int *ett[] = {
6560 &ett_btle,
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,
6570 &ett_data_header,
6571 &ett_data_header_cte_info,
6572 &ett_features,
6573 &ett_tx_phys,
6574 &ett_rx_phys,
6575 &ett_c_to_p_phy,
6576 &ett_p_to_c_phy,
6577 &ett_phys,
6578 &ett_pwr_phy,
6579 &ett_cte,
6580 &ett_channel_map,
6581 &ett_scan_response_data,
6582 &ett_pwrflags,
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);
6625 void
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
6641 * Local variables:
6642 * c-basic-offset: 4
6643 * tab-width: 8
6644 * indent-tabs-mode: nil
6645 * End:
6647 * vi: set shiftwidth=4 tabstop=8 expandtab:
6648 * :indentSize=4:tabSize=8:noTabs=true: