Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-btavdtp.c
bloba185c1fc2b65891ca87925c7629b339f595887a5
1 /* packet-btavdtp.c
2 * Routines for Bluetooth AVDTP dissection
4 * Copyright 2012, Michal Labedzki for Tieto Corporation
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/unit_strings.h>
20 #include "packet-bluetooth.h"
21 #include "packet-btl2cap.h"
22 #include "packet-btavdtp.h"
23 #include "packet-btavrcp.h"
24 #include "packet-rtp.h"
26 #define AVDTP_MESSAGE_TYPE_MASK 0x03
27 #define AVDTP_PACKET_TYPE_MASK 0x0C
28 #define AVDTP_TRANSACTION_MASK 0xF0
29 #define AVDTP_SIGNAL_ID_MASK 0x3F
30 #define AVDTP_RFA0_MASK 0xC0
32 #define MESSAGE_TYPE_COMMAND 0x00
33 #define MESSAGE_TYPE_GENERAL_REJECT 0x01
34 #define MESSAGE_TYPE_ACCEPT 0x02
35 #define MESSAGE_TYPE_REJECT 0x03
37 #define PACKET_TYPE_SINGLE 0x00
38 #define PACKET_TYPE_START 0x01
39 #define PACKET_TYPE_CONTINUE 0x02
40 #define PACKET_TYPE_END 0x03
42 #define SIGNAL_ID_DISCOVER 0x01
43 #define SIGNAL_ID_GET_CAPABILITIES 0x02
44 #define SIGNAL_ID_SET_CONFIGURATION 0x03
45 #define SIGNAL_ID_GET_CONFIGURATION 0x04
46 #define SIGNAL_ID_RECONFIGURE 0x05
47 #define SIGNAL_ID_OPEN 0x06
48 #define SIGNAL_ID_START 0x07
49 #define SIGNAL_ID_CLOSE 0x08
50 #define SIGNAL_ID_SUSPEND 0x09
51 #define SIGNAL_ID_ABORT 0x0A
52 #define SIGNAL_ID_SECURITY_CONTROL 0x0B
53 #define SIGNAL_ID_GET_ALL_CAPABILITIES 0x0C
54 #define SIGNAL_ID_DELAY_REPORT 0x0D
56 #define SERVICE_CATEGORY_MEDIA_TRANSPORT 0x01
57 #define SERVICE_CATEGORY_REPORTING 0x02
58 #define SERVICE_CATEGORY_RECOVERY 0x03
59 #define SERVICE_CATEGORY_CONTENT_PROTECTION 0x04
60 #define SERVICE_CATEGORY_HEADER_COMPRESSION 0x05
61 #define SERVICE_CATEGORY_MULTIPLEXING 0x06
62 #define SERVICE_CATEGORY_MEDIA_CODEC 0x07
63 #define SERVICE_CATEGORY_DELAY_REPORTING 0x08
65 #define MEDIA_TYPE_AUDIO 0x00
66 #define MEDIA_TYPE_VIDEO 0x01
68 #define SEID_ACP 0x00
69 #define SEID_INT 0x01
71 #define STREAM_TYPE_MEDIA 0x00
72 #define STREAM_TYPE_SIGNAL 0x01
74 #define CODEC_DEFAULT 0xFFFF
75 #define CODEC_SBC 0x00
76 #define CODEC_MPEG12_AUDIO 0x01
77 #define CODEC_MPEG24_AAC 0x02
78 #define CODEC_ATRAC 0x04
79 #define CODEC_APT_X 0xFF01
80 #define CODEC_APT_X_HD 0xFF24
81 #define CODEC_LDAC 0xFFAA
83 #define VENDOR_APT_CODEC_ID_APT_X 0x0001
84 #define VENDOR_APT_CODEC_ID_APT_X_HD 0x0024
85 #define VENDOR_SONY_CODEC_ID_LDAC 0x00AA
86 #define VENDOR_GOOGLE_CODEC_ID_OPUS 0x0001
88 #define CODEC_H263_BASELINE 0x01
89 #define CODEC_MPEG4_VSP 0x02
90 #define CODEC_H263_PROFILE_3 0x03
91 #define CODEC_H263_PROFILE_8 0x04
93 #define CODEC_VENDOR 0xFF
95 #define HEADER_SIZE 2
96 #define SEP_MAX 64
97 #define SEP_SIZE 2
99 /* ========================================================== */
100 /* Story: RTP Player, conversation (probably reassemble too) use address:port as
101 "key" to separate devices/streams. In Bluetooth World it is not enough to
102 separate devices/streams. Example key:
103 uint32_t interface_id (aka frame.interface_id)
104 uint32_t adapter_id (interface like "bluetooth-monitor" or USB provide
105 more than one device over interface, so we must
106 separate information provided by each one)
107 uint16_t hci_chandle (aka "connection handle" use to separate connections to devices)
108 uint16_t l2cap_psm (like hci_chandle but over l2cap layer, need hci_chandle info because
109 the same PSM can be used over chandles)
110 uint8_t rfcomm_channel (like l2cap_psm, but over RFCOMM layer...)
111 etc. like
112 uint8_t stram_endpoint_number
113 uint32_t stream_number (to separate multiple streams for RTP Player)
115 So keys can be various (length or type) and "ports" are not enough to sore
116 all needed information. If one day that changed then all RTP_PLAYER_WORKAROUND
117 block can be removed. This workaround use global number of streams (aka stream ID)
118 to be used as port number in RTP Player to separate streams.
120 #define RTP_PLAYER_WORKAROUND true
122 #if RTP_PLAYER_WORKAROUND == true
123 wmem_tree_t *file_scope_stream_number = NULL;
124 #endif
125 /* ========================================================== */
127 static int proto_btavdtp;
129 static int hf_btavdtp_data;
130 static int hf_btavdtp_message_type;
131 static int hf_btavdtp_packet_type;
132 static int hf_btavdtp_transaction;
133 static int hf_btavdtp_signal;
134 static int hf_btavdtp_signal_id;
135 static int hf_btavdtp_rfa0;
136 static int hf_btavdtp_number_of_signal_packets;
137 static int hf_btavdtp_sep_seid;
138 static int hf_btavdtp_sep_inuse;
139 static int hf_btavdtp_sep_rfa0;
140 static int hf_btavdtp_sep_media_type;
141 static int hf_btavdtp_sep_type;
142 static int hf_btavdtp_sep_rfa1;
143 static int hf_btavdtp_error_code;
144 static int hf_btavdtp_acp_sep;
145 static int hf_btavdtp_acp_seid_item;
146 static int hf_btavdtp_int_seid_item;
147 static int hf_btavdtp_acp_seid;
148 static int hf_btavdtp_int_seid;
149 static int hf_btavdtp_service_category;
150 static int hf_btavdtp_rfa_seid;
151 static int hf_btavdtp_delay;
152 static int hf_btavdtp_length_of_service_category;
153 static int hf_btavdtp_recovery_type;
154 static int hf_btavdtp_maximum_recovery_window_size;
155 static int hf_btavdtp_maximum_number_of_media_packet_in_parity_code;
156 static int hf_btavdtp_multiplexing_fragmentation;
157 static int hf_btavdtp_multiplexing_rfa;
158 static int hf_btavdtp_multiplexing_tsid;
159 static int hf_btavdtp_multiplexing_tcid;
160 static int hf_btavdtp_multiplexing_entry_rfa;
161 static int hf_btavdtp_header_compression_backch;
162 static int hf_btavdtp_header_compression_media;
163 static int hf_btavdtp_header_compression_recovery;
164 static int hf_btavdtp_header_compression_rfa;
165 static int hf_btavdtp_content_protection_type;
166 static int hf_btavdtp_media_codec_media_type;
167 static int hf_btavdtp_media_codec_rfa;
168 static int hf_btavdtp_media_codec_unknown_type;
169 static int hf_btavdtp_media_codec_audio_type;
170 static int hf_btavdtp_media_codec_video_type;
171 static int hf_btavdtp_sbc_sampling_frequency_16000;
172 static int hf_btavdtp_sbc_sampling_frequency_32000;
173 static int hf_btavdtp_sbc_sampling_frequency_44100;
174 static int hf_btavdtp_sbc_sampling_frequency_48000;
175 static int hf_btavdtp_sbc_channel_mode_mono;
176 static int hf_btavdtp_sbc_channel_mode_dual_channel;
177 static int hf_btavdtp_sbc_channel_mode_stereo;
178 static int hf_btavdtp_sbc_channel_mode_joint_stereo;
179 static int hf_btavdtp_sbc_block_4;
180 static int hf_btavdtp_sbc_block_8;
181 static int hf_btavdtp_sbc_block_12;
182 static int hf_btavdtp_sbc_block_16;
183 static int hf_btavdtp_sbc_subbands_4;
184 static int hf_btavdtp_sbc_subbands_8;
185 static int hf_btavdtp_sbc_allocation_method_snr;
186 static int hf_btavdtp_sbc_allocation_method_loudness;
187 static int hf_btavdtp_sbc_min_bitpool;
188 static int hf_btavdtp_sbc_max_bitpool;
189 static int hf_btavdtp_mpeg12_layer_1;
190 static int hf_btavdtp_mpeg12_layer_2;
191 static int hf_btavdtp_mpeg12_layer_3;
192 static int hf_btavdtp_mpeg12_crc_protection;
193 static int hf_btavdtp_mpeg12_channel_mode_mono;
194 static int hf_btavdtp_mpeg12_channel_mode_dual_channel;
195 static int hf_btavdtp_mpeg12_channel_mode_stereo;
196 static int hf_btavdtp_mpeg12_channel_mode_joint_stereo;
197 static int hf_btavdtp_mpeg12_rfa;
198 static int hf_btavdtp_mpeg12_mpf_2;
199 static int hf_btavdtp_mpeg12_sampling_frequency_16000;
200 static int hf_btavdtp_mpeg12_sampling_frequency_22050;
201 static int hf_btavdtp_mpeg12_sampling_frequency_24000;
202 static int hf_btavdtp_mpeg12_sampling_frequency_32000;
203 static int hf_btavdtp_mpeg12_sampling_frequency_44100;
204 static int hf_btavdtp_mpeg12_sampling_frequency_48000;
205 static int hf_btavdtp_mpeg12_vbr_supported;
206 static int hf_btavdtp_mpeg12_bit_rate;
207 static int hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc;
208 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc;
209 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp;
210 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable;
211 static int hf_btavdtp_mpeg24_object_type_rfa;
212 static int hf_btavdtp_mpeg24_sampling_frequency_8000;
213 static int hf_btavdtp_mpeg24_sampling_frequency_11025;
214 static int hf_btavdtp_mpeg24_sampling_frequency_12000;
215 static int hf_btavdtp_mpeg24_sampling_frequency_16000;
216 static int hf_btavdtp_mpeg24_sampling_frequency_22050;
217 static int hf_btavdtp_mpeg24_sampling_frequency_24000;
218 static int hf_btavdtp_mpeg24_sampling_frequency_32000;
219 static int hf_btavdtp_mpeg24_sampling_frequency_44100;
220 static int hf_btavdtp_mpeg24_sampling_frequency_48000;
221 static int hf_btavdtp_mpeg24_sampling_frequency_64000;
222 static int hf_btavdtp_mpeg24_sampling_frequency_88200;
223 static int hf_btavdtp_mpeg24_sampling_frequency_96000;
224 static int hf_btavdtp_mpeg24_channels_1;
225 static int hf_btavdtp_mpeg24_channels_2;
226 static int hf_btavdtp_mpeg24_rfa;
227 static int hf_btavdtp_mpeg24_vbr_supported;
228 static int hf_btavdtp_mpeg24_bit_rate;
229 static int hf_btavdtp_atrac_version;
230 static int hf_btavdtp_atrac_channel_mode_single_channel;
231 static int hf_btavdtp_atrac_channel_mode_dual_channel;
232 static int hf_btavdtp_atrac_channel_mode_joint_stereo;
233 static int hf_btavdtp_atrac_rfa1;
234 static int hf_btavdtp_atrac_rfa2;
235 static int hf_btavdtp_atrac_sampling_frequency_44100;
236 static int hf_btavdtp_atrac_sampling_frequency_48000;
237 static int hf_btavdtp_atrac_vbr_supported;
238 static int hf_btavdtp_atrac_bit_rate;
239 static int hf_btavdtp_atrac_maximum_sul;
240 static int hf_btavdtp_atrac_rfa3;
241 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000;
242 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000;
243 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100;
244 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000;
245 static int hf_btavdtp_vendor_specific_aptx_channel_mode_mono;
246 static int hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel;
247 static int hf_btavdtp_vendor_specific_aptx_channel_mode_stereo;
248 static int hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo;
249 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000;
250 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000;
251 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100;
252 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000;
253 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono;
254 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel;
255 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo;
256 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo;
257 static int hf_btavdtp_vendor_specific_aptxhd_rfa;
258 static int hf_btavdtp_vendor_specific_ldac_rfa1;
259 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_44100;
260 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_48000;
261 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_88200;
262 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_96000;
263 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_176400;
264 static int hf_btavdtp_vendor_specific_ldac_sampling_frequency_192000;
265 static int hf_btavdtp_vendor_specific_ldac_rfa2;
266 static int hf_btavdtp_vendor_specific_ldac_channel_mode_mono;
267 static int hf_btavdtp_vendor_specific_ldac_channel_mode_dual_channel;
268 static int hf_btavdtp_vendor_specific_ldac_channel_mode_stereo;
269 static int hf_btavdtp_vendor_specific_opus_sampling_frequency_48000;
270 static int hf_btavdtp_vendor_specific_opus_rfa;
271 static int hf_btavdtp_vendor_specific_opus_frame_duration_20;
272 static int hf_btavdtp_vendor_specific_opus_frame_duration_10;
273 static int hf_btavdtp_vendor_specific_opus_channel_mode_dual;
274 static int hf_btavdtp_vendor_specific_opus_channel_mode_stereo;
275 static int hf_btavdtp_vendor_specific_opus_channel_mode_mono;
276 static int hf_btavdtp_h263_level_10;
277 static int hf_btavdtp_h263_level_20;
278 static int hf_btavdtp_h263_level_30;
279 static int hf_btavdtp_h263_level_rfa;
280 static int hf_btavdtp_mpeg4_level_0;
281 static int hf_btavdtp_mpeg4_level_1;
282 static int hf_btavdtp_mpeg4_level_2;
283 static int hf_btavdtp_mpeg4_level_3;
284 static int hf_btavdtp_mpeg4_level_rfa;
285 static int hf_btavdtp_vendor_id;
286 static int hf_btavdtp_vendor_specific_codec_id;
287 static int hf_btavdtp_vendor_specific_value;
288 static int hf_btavdtp_vendor_apt_codec_id;
289 static int hf_btavdtp_vendor_sony_codec_id;
290 static int hf_btavdtp_vendor_google_codec_id;
291 static int hf_btavdtp_capabilities;
292 static int hf_btavdtp_service;
293 static int hf_btavdtp_service_multiplexing_entry;
295 static int ett_btavdtp;
296 static int ett_btavdtp_sep;
297 static int ett_btavdtp_capabilities;
298 static int ett_btavdtp_service;
300 static expert_field ei_btavdtp_sbc_min_bitpool_out_of_range;
301 static expert_field ei_btavdtp_sbc_max_bitpool_out_of_range;
302 static expert_field ei_btavdtp_unexpected_losc_data;
304 static dissector_handle_t btavdtp_handle;
305 static dissector_handle_t bta2dp_handle;
306 static dissector_handle_t btvdp_handle;
307 static dissector_handle_t rtp_handle;
309 static wmem_tree_t *channels;
310 static wmem_tree_t *sep_list;
311 static wmem_tree_t *sep_open;
312 static wmem_tree_t *media_packet_times;
314 /* A2DP declarations */
315 static int proto_bta2dp;
316 static int ett_bta2dp;
317 static int proto_bta2dp_cph_scms_t;
318 static int ett_bta2dp_cph_scms_t;
320 static int hf_bta2dp_acp_seid;
321 static int hf_bta2dp_int_seid;
322 static int hf_bta2dp_codec;
323 static int hf_bta2dp_vendor_id;
324 static int hf_bta2dp_vendor_codec_id;
325 static int hf_bta2dp_content_protection;
326 static int hf_bta2dp_stream_start_in_frame;
327 static int hf_bta2dp_stream_end_in_frame;
328 static int hf_bta2dp_stream_number;
329 static int hf_bta2dp_l_bit;
330 static int hf_bta2dp_cp_bit;
331 static int hf_bta2dp_reserved;
333 static dissector_handle_t sbc_handle;
334 static dissector_handle_t mp2t_handle;
335 static dissector_handle_t mpeg_audio_handle;
336 static dissector_handle_t atrac_handle;
338 static bool force_a2dp_scms_t;
339 static int force_a2dp_codec = CODEC_DEFAULT;
341 static const enum_val_t pref_a2dp_codec[] = {
342 { "default", "Default", CODEC_DEFAULT },
343 { "sbc", "SBC", CODEC_SBC },
344 { "mp2t", "MPEG12 AUDIO", CODEC_MPEG12_AUDIO },
345 { "mpeg-audio", "MPEG24 AAC", CODEC_MPEG24_AAC },
346 /* XXX: Not supported in Wireshark yet { "atrac", "ATRAC", CODEC_ATRAC },*/
347 { "aptx", "aptX", CODEC_APT_X },
348 { "aptx-hd", "aptX HD", CODEC_APT_X_HD },
349 { "ldac", "LDAC", CODEC_LDAC },
350 { NULL, NULL, 0 }
354 /* VDP declarations */
355 static int proto_btvdp;
356 static int ett_btvdp;
357 static int proto_btvdp_cph_scms_t;
358 static int ett_btvdp_cph_scms_t;
360 static int hf_btvdp_acp_seid;
361 static int hf_btvdp_int_seid;
362 static int hf_btvdp_codec;
363 static int hf_btvdp_vendor_id;
364 static int hf_btvdp_vendor_codec_id;
365 static int hf_btvdp_content_protection;
366 static int hf_btvdp_stream_start_in_frame;
367 static int hf_btvdp_stream_end_in_frame;
368 static int hf_btvdp_stream_number;
369 static int hf_btvdp_l_bit;
370 static int hf_btvdp_cp_bit;
371 static int hf_btvdp_reserved;
373 static dissector_handle_t h263_handle;
374 static dissector_handle_t mp4v_es_handle;
376 static bool force_vdp_scms_t;
377 static int force_vdp_codec = CODEC_H263_BASELINE;
379 static const enum_val_t pref_vdp_codec[] = {
380 { "h263", "H263", CODEC_H263_BASELINE },
381 { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP },
382 { NULL, NULL, 0 }
385 /* APT-X Codec */
386 static int proto_aptx;
387 static int hf_aptx_data;
388 static int hf_aptx_cumulative_frame_duration;
389 static int hf_aptx_delta_time;
390 static int hf_aptx_avrcp_song_position;
391 static int hf_aptx_delta_time_from_the_beginning;
392 static int hf_aptx_cumulative_duration;
393 static int hf_aptx_diff;
394 static int ett_aptx;
395 static dissector_handle_t aptx_handle;
397 /* LDAC Codec */
398 static int proto_ldac;
399 static int hf_ldac_fragmented;
400 static int hf_ldac_starting_packet;
401 static int hf_ldac_last_packet;
402 static int hf_ldac_rfa;
403 static int hf_ldac_number_of_frames;
405 static int hf_ldac_syncword;
406 static int hf_ldac_sampling_frequency;
407 static int hf_ldac_channel_config_index;
408 static int hf_ldac_frame_length_h;
409 static int hf_ldac_frame_length_l;
410 static int hf_ldac_frame_status;
412 static int hf_ldac_expected_data_speed;
414 static int hf_ldac_data;
415 static int ett_ldac;
416 static int ett_ldac_list;
417 static expert_field ei_ldac_syncword;
418 static expert_field ei_ldac_truncated_or_bad_length;
419 static dissector_handle_t ldac_handle;
420 #define LDAC_CCI_MONO 0x0
421 #define LDAC_CCI_DUAL 0x1
422 #define LDAC_CCI_STEREO 0x2
423 static const value_string ldac_channel_config_index_vals[] = {
424 { LDAC_CCI_MONO, "Mono"},
425 { LDAC_CCI_DUAL, "Dual Channel"},
426 { LDAC_CCI_STEREO, "Stereo"},
427 { 0, NULL }
430 #define LDAC_FSID_044 0x0
431 #define LDAC_FSID_048 0x1
432 #define LDAC_FSID_088 0x2
433 #define LDAC_FSID_096 0x3
434 #define LDAC_FSID_176 0x4
435 #define LDAC_FSID_192 0x5
437 static const value_string ldac_sampling_frequency_vals[] = {
438 { LDAC_FSID_044, "44.1 kHz"},
439 { LDAC_FSID_048, "48.0 kHz"},
440 { LDAC_FSID_088, "88.2 kHz"},
441 { LDAC_FSID_096, "96.0 kHz"},
442 { LDAC_FSID_176, "176.4 kHz"},
443 { LDAC_FSID_192, "192.0 kHz"},
444 { 0, NULL }
448 static const value_string message_type_vals[] = {
449 { 0x00, "Command" },
450 { 0x01, "GeneralReject" },
451 { 0x02, "ResponseAccept" },
452 { 0x03, "ResponseReject" },
453 { 0, NULL }
456 static const value_string packet_type_vals[] = {
457 { 0x00, "Single" },
458 { 0x01, "Start" },
459 { 0x02, "Continue" },
460 { 0x03, "End" },
461 { 0, NULL }
464 static const value_string signal_id_vals[] = {
465 { 0x00, "Reserved" },
466 { 0x01, "Discover" },
467 { 0x02, "GetCapabilities" },
468 { 0x03, "SetConfiguration" },
469 { 0x04, "GetConfiguration" },
470 { 0x05, "Reconfigure" },
471 { 0x06, "Open" },
472 { 0x07, "Start" },
473 { 0x08, "Close" },
474 { 0x09, "Suspend" },
475 { 0x0A, "Abort" },
476 { 0x0B, "SecurityControl" },
477 { 0x0C, "GetAllCapabilities" },
478 { 0x0D, "DelayReport" },
479 { 0, NULL }
482 static const value_string media_type_vals[] = {
483 { 0x00, "Audio" },
484 { 0x01, "Video" },
485 { 0x02, "Multimedia" },
486 { 0, NULL }
489 static const value_string sep_type_vals[] = {
490 { 0x00, "Source" },
491 { 0x01, "Sink" },
492 { 0, NULL }
495 static const value_string true_false[] = {
496 { 0x00, "False" },
497 { 0x01, "True" },
498 { 0, NULL }
501 static const value_string error_code_vals[] = {
502 /* ACP to INT, Signal Response Header Error Codes */
503 { 0x01, "Bad Header Format" },
504 /* ACP to INT, Signal Response Payload Format Error Codes */
505 { 0x11, "Bad Length" },
506 { 0x12, "Bad ACP SEID" },
507 { 0x13, "SEP In Use" },
508 { 0x14, "SEP Not In Use" },
509 { 0x17, "Bad Service Category" },
510 { 0x18, "Bad Payload Format" },
511 { 0x19, "Not Supported Command" },
512 { 0x1A, "Invalid Capabilities" },
513 /* ACP to INT, Signal Response Transport Service Capabilities Error Codes */
514 { 0x22, "Bad Recovery Type" },
515 { 0x23, "Bad Media Transport Format" },
516 { 0x25, "Bad Recovery Format" },
517 { 0x26, "Bad Header Compression Format" },
518 { 0x27, "Bad Content Protection Format" },
519 { 0x28, "Bad Multiplexing Format" },
520 { 0x29, "Unsupported Configuration" },
521 /* ACP to INT, Procedure Error Codes */
522 { 0x31, "Bad State" },
523 /* GAVDTP */
524 { 0x80, "The Service Category Stated is Invalid" },
525 { 0x81, "Lack of Resource New Stream Context" },
526 /* A2DP */
527 { 0xC1, "Invalid Codec Type" },
528 { 0xC2, "Not Supported Codec Type" },
529 { 0xC3, "Invalid Sampling Frequency" },
530 { 0xC4, "Not Supported Sampling Frequency" },
531 { 0xC5, "Invalid Channel Mode" },
532 { 0xC6, "Not Supported Channel Mode" },
533 { 0xC7, "Invalid Subbands" },
534 { 0xC8, "Not Supported Subbands" },
535 { 0xC9, "Invalid Allocation Method" },
536 { 0xCA, "Not Supported Allocation Method" },
537 { 0xCB, "Invalid Minimum Bitpool Value" },
538 { 0xCC, "Not Supported Minimum Bitpool Value" },
539 { 0xCD, "Invalid Maximum Bitpool Value" },
540 { 0xCE, "Not Supported Maximum Bitpool Value" },
541 { 0xCF, "Invalid Layer" },
542 { 0xD0, "Not Supported Layer" },
543 { 0xD1, "Not Supported CRC" },
544 { 0xD2, "Not Supported MPF" },
545 { 0xD3, "Not Supported VBR" },
546 { 0xD4, "Invalid Bit Rate" },
547 { 0xD5, "Not Supported Bit Rate" },
548 { 0xD6, "Invalid Object Type" },
549 { 0xD7, "Not Supported Object Type" },
550 { 0xD8, "Invalid Channels" },
551 { 0xD9, "Not Supported Channels" },
552 { 0xDA, "Invalid Version" },
553 { 0xDB, "Not Supported Version" },
554 { 0xDC, "Not Supported Maximum SUL" },
555 { 0xDD, "Invalid Block Length" },
556 { 0xE0, "Invalid Content Protection Type" },
557 { 0xE1, "Invalid Content Protection Format" },
558 { 0xE2, "Invalid Coded Parameter" },
559 { 0xE3, "Not Supported Codec Parameter" },
560 { 0, NULL }
563 static const value_string service_category_vals[] = {
564 { 0x01, "Media Transport" },
565 { 0x02, "Reporting" },
566 { 0x03, "Recovery" },
567 { 0x04, "Content Protection" },
568 { 0x05, "Header Compression" },
569 { 0x06, "Multiplexing" },
570 { 0x07, "Media Codec" },
571 { 0x08, "Delay Reporting" },
572 { 0, NULL }
575 static const value_string recovery_type_vals[] = {
576 { 0x00, "Forbidden" },
577 { 0x01, "RFC2733" },
578 { 0, NULL }
581 static const value_string multiplexing_tsid_vals[] = {
582 { 0x00, "Used for TSID query" },
583 { 0x1F, "RFD" },
584 { 0, NULL }
587 static const value_string multiplexing_tcid_vals[] = {
588 { 0x00, "Used for TCID query" },
589 { 0x1F, "RFD" },
590 { 0, NULL }
593 static const value_string media_codec_audio_type_vals[] = {
594 { 0x00, "SBC" },
595 { 0x01, "MPEG-1,2 Audio" },
596 { 0x02, "MPEG-2,4 AAC" },
597 { 0x04, "ATRAC family" },
598 { 0xFF, "non-A2DP" },
599 { 0, NULL }
602 static const value_string media_codec_video_type_vals[] = {
603 { 0x01, "H.263 baseline" },
604 { 0x02, "MPEG-4 Visual Simple Profile" },
605 { 0x03, "H.263 profile 3" },
606 { 0x04, "H.263 profile 8" },
607 { 0xFF, "non-VDP" },
608 { 0, NULL }
611 static const value_string content_protection_type_vals[] = {
612 { 0x01, "DTCP" },
613 { 0x02, "SCMS-T" },
614 { 0, NULL }
617 static const value_string vendor_apt_codec_vals[] = {
618 { VENDOR_APT_CODEC_ID_APT_X, "aptX" },
619 { VENDOR_APT_CODEC_ID_APT_X_HD, "aptX HD" },
620 { 0, NULL }
623 static const value_string vendor_sony_codec_vals[] = {
624 { VENDOR_SONY_CODEC_ID_LDAC, "LDAC" },
625 { 0, NULL }
628 static const value_string vendor_google_codec_vals[] = {
629 { VENDOR_GOOGLE_CODEC_ID_OPUS, "Opus" },
630 { 0, NULL }
633 enum sep_state {
634 SEP_STATE_FREE,
635 SEP_STATE_OPEN,
636 SEP_STATE_IN_USE
639 typedef struct _sep_entry_t {
640 uint8_t seid;
641 uint8_t type;
642 uint8_t media_type;
643 uint8_t int_seid;
644 int codec;
645 uint32_t vendor_id;
646 uint16_t vendor_codec;
647 uint8_t configuration_length;
648 uint8_t *configuration;
649 int content_protection_type;
651 enum sep_state state;
652 } sep_entry_t;
654 typedef struct _sep_data_t {
655 int codec;
656 uint32_t vendor_id;
657 uint16_t vendor_codec;
658 uint8_t configuration_length;
659 uint8_t *configuration;
660 uint8_t acp_seid;
661 uint8_t int_seid;
662 int content_protection_type;
663 uint32_t stream_start_in_frame;
664 uint32_t stream_end_in_frame;
665 uint32_t stream_number;
666 media_packet_info_t *previous_media_packet_info;
667 media_packet_info_t *current_media_packet_info;
668 } sep_data_t;
670 typedef struct _media_stream_number_value_t {
671 uint32_t stream_start_in_frame;
672 uint32_t stream_end_in_frame;
673 uint32_t stream_number;
674 } media_stream_number_value_t;
676 typedef struct _channels_info_t {
677 uint32_t control_local_cid;
678 uint32_t control_remote_cid;
679 uint32_t media_local_cid;
680 uint32_t media_remote_cid;
681 wmem_tree_t *stream_numbers;
682 uint32_t disconnect_in_frame;
683 uint32_t *l2cap_disconnect_in_frame;
684 uint32_t *hci_disconnect_in_frame;
685 uint32_t *adapter_disconnect_in_frame;
686 sep_entry_t *sep;
687 } channels_info_t;
690 void proto_register_btavdtp(void);
691 void proto_reg_handoff_btavdtp(void);
692 void proto_register_bta2dp(void);
693 void proto_reg_handoff_bta2dp(void);
694 void proto_register_bta2dp_content_protection_header_scms_t(void);
695 void proto_register_btvdp(void);
696 void proto_reg_handoff_btvdp(void);
697 void proto_register_btvdp_content_protection_header_scms_t(void);
698 void proto_register_aptx(void);
699 void proto_register_ldac(void);
702 static const char *
703 get_sep_type(uint32_t interface_id,
704 uint32_t adapter_id, uint32_t chandle, uint32_t direction, uint32_t seid, uint32_t frame_number)
706 wmem_tree_key_t key[6];
707 wmem_tree_t *subtree;
708 sep_entry_t *sep;
710 key[0].length = 1;
711 key[0].key = &interface_id;
712 key[1].length = 1;
713 key[1].key = &adapter_id;
714 key[2].length = 1;
715 key[2].key = &chandle;
716 key[3].length = 1;
717 key[3].key = &direction;
718 key[4].length = 1;
719 key[4].key = &seid;
720 key[5].length = 0;
721 key[5].key = NULL;
723 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
724 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
725 if (sep) {
726 return val_to_str_const(sep->type, sep_type_vals, "unknown");
729 return "unknown";
732 static const char *
733 get_sep_media_type(uint32_t interface_id,
734 uint32_t adapter_id, uint32_t chandle, uint32_t direction, uint32_t seid, uint32_t frame_number)
736 wmem_tree_key_t key[6];
737 wmem_tree_t *subtree;
738 sep_entry_t *sep;
740 key[0].length = 1;
741 key[0].key = &interface_id;
742 key[1].length = 1;
743 key[1].key = &adapter_id;
744 key[2].length = 1;
745 key[2].key = &chandle;
746 key[3].length = 1;
747 key[3].key = &direction;
748 key[4].length = 1;
749 key[4].key = &seid;
750 key[5].length = 0;
751 key[5].key = NULL;
753 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
754 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
755 if (sep) {
756 return val_to_str_const(sep->media_type, media_type_vals, "unknown");
759 return "unknown";
763 static int
764 dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
765 uint32_t interface_id, uint32_t adapter_id, uint32_t chandle)
767 proto_tree *sep_tree;
768 proto_item *sep_item;
769 unsigned i_sep = 1;
770 unsigned media_type;
771 unsigned type;
772 unsigned seid;
773 unsigned in_use;
774 unsigned items;
775 uint32_t direction;
777 /* Reverse direction to avoid mass reversing it, because this is only case
778 when SEP is provided in ACP role, otherwise INT frequently asking for it
780 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
781 items = tvb_reported_length_remaining(tvb, offset) / 2;
782 while (tvb_reported_length_remaining(tvb, offset) > 0) {
783 seid = tvb_get_uint8(tvb, offset);
784 in_use = seid & 0x02;
785 seid = seid >> 2;
786 media_type = tvb_get_uint8(tvb, offset + 1) >> 4;
787 type = (tvb_get_uint8(tvb, offset + 1) & 0x08) >> 3;
788 sep_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_sep, tvb, offset, 2, "ACP SEP [%u - %s %s] item %u/%u",
789 seid, val_to_str_const(media_type, media_type_vals, "unknown"),
790 val_to_str_const(type, sep_type_vals, "unknown"), i_sep, items);
791 sep_tree = proto_item_add_subtree(sep_item, ett_btavdtp_sep);
793 proto_tree_add_item(sep_tree, hf_btavdtp_sep_seid , tvb, offset, 1, ENC_NA);
794 proto_tree_add_item(sep_tree, hf_btavdtp_sep_inuse, tvb, offset, 1, ENC_NA);
795 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa0 , tvb, offset, 1, ENC_NA);
796 offset+=1;
798 proto_tree_add_item(sep_tree, hf_btavdtp_sep_media_type, tvb, offset, 1, ENC_NA);
799 proto_tree_add_item(sep_tree, hf_btavdtp_sep_type , tvb, offset, 1, ENC_NA);
800 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa1 , tvb, offset, 1, ENC_NA);
802 if (!pinfo->fd->visited) {
803 sep_entry_t *sep_data;
804 wmem_tree_key_t key[7];
805 uint32_t frame_number = pinfo->num;
807 key[0].length = 1;
808 key[0].key = &interface_id;
809 key[1].length = 1;
810 key[1].key = &adapter_id;
811 key[2].length = 1;
812 key[2].key = &chandle;
813 key[3].length = 1;
814 key[3].key = &direction;
815 key[4].length = 1;
816 key[4].key = &seid;
817 key[5].length = 1;
818 key[5].key = &frame_number;
819 key[6].length = 0;
820 key[6].key = NULL;
822 sep_data = wmem_new0(wmem_file_scope(), sep_entry_t);
823 sep_data->seid = seid;
824 sep_data->type = type;
825 sep_data->media_type = media_type;
826 sep_data->codec = -1;
827 if (in_use) {
828 sep_data->state = SEP_STATE_IN_USE;
829 } else {
830 sep_data->state = SEP_STATE_FREE;
833 wmem_tree_insert32_array(sep_list, key, sep_data);
836 offset += 1;
837 i_sep += 1;
840 col_append_fstr(pinfo->cinfo, COL_INFO, " - items: %u", items);
841 return offset;
845 static int
846 dissect_codec(tvbuff_t *tvb, packet_info *pinfo, proto_item *service_item, proto_tree *tree, int offset,
847 unsigned losc, int media_type, int media_codec_type, uint32_t *vendor_id, uint16_t *vendor_codec)
849 proto_item *pitem;
850 uint32_t vendor_codec_id;
851 uint32_t value;
852 uint8_t *value8 = (uint8_t *) &value;
854 switch(media_type) {
855 case MEDIA_TYPE_AUDIO:
856 switch(media_codec_type) {
857 case CODEC_SBC:
858 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_16000, tvb, offset, 1, ENC_NA);
859 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_32000, tvb, offset, 1, ENC_NA);
860 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_44100, tvb, offset, 1, ENC_NA);
861 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_48000, tvb, offset, 1, ENC_NA);
862 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_mono, tvb, offset, 1, ENC_NA);
863 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
864 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_stereo, tvb, offset, 1, ENC_NA);
865 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
867 proto_tree_add_item(tree, hf_btavdtp_sbc_block_4, tvb, offset + 1, 1, ENC_NA);
868 proto_tree_add_item(tree, hf_btavdtp_sbc_block_8, tvb, offset + 1, 1, ENC_NA);
869 proto_tree_add_item(tree, hf_btavdtp_sbc_block_12, tvb, offset + 1, 1, ENC_NA);
870 proto_tree_add_item(tree, hf_btavdtp_sbc_block_16, tvb, offset + 1, 1, ENC_NA);
871 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_4, tvb, offset + 1, 1, ENC_NA);
872 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_8, tvb, offset + 1, 1, ENC_NA);
873 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_snr, tvb, offset + 1, 1, ENC_NA);
874 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_loudness, tvb, offset + 1, 1, ENC_NA);
876 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_min_bitpool, tvb, offset + 2, 1, ENC_NA);
877 value = tvb_get_uint8(tvb, offset + 2);
878 if (value < 2 || value > 250) {
879 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_min_bitpool_out_of_range);
882 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_max_bitpool, tvb, offset + 3, 1, ENC_NA);
883 value = tvb_get_uint8(tvb, offset + 3);
884 if (value < 2 || value > 250) {
885 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_max_bitpool_out_of_range);
888 value = tvb_get_h_uint32(tvb, offset);
889 if (value) {
890 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s%s%s%s%s| %s%s%s%s%s| block: %s%s%s%s%s| subbands: %s%s%s| allocation: %s%s%s| bitpool: %u..%u)",
891 (value8[0] & 0x80) ? "16000 " : "",
892 (value8[0] & 0x40) ? "32000 " : "",
893 (value8[0] & 0x20) ? "44100 " : "",
894 (value8[0] & 0x10) ? "48000 " : "",
895 (value8[0] & 0xF0) ? "" : "not set ",
896 (value8[0] & 0x08) ? "Mono " : "",
897 (value8[0] & 0x04) ? "DualChannel " : "",
898 (value8[0] & 0x02) ? "Stereo " : "",
899 (value8[0] & 0x01) ? "JointStereo " : "",
900 (value8[0] & 0x0F) ? "" : "not set ",
901 (value8[1] & 0x80) ? "4 " : "",
902 (value8[1] & 0x40) ? "8 " : "",
903 (value8[1] & 0x20) ? "12 " : "",
904 (value8[1] & 0x10) ? "16 " : "",
905 (value8[1] & 0xF0) ? "" : "not set ",
906 (value8[1] & 0x08) ? "4 " : "",
907 (value8[1] & 0x04) ? "8 " : "",
908 (value8[1] & 0x0C) ? "" : "not set ",
909 (value8[1] & 0x02) ? "SNR " : "",
910 (value8[1] & 0x01) ? "Loudness " : "",
911 (value8[1] & 0x03) ? "" : "not set ",
912 value8[2],
913 value8[3]);
915 proto_item_append_text(service_item, " (%s%s%s%s%s| %s%s%s%s%s| block: %s%s%s%s%s| subbands: %s%s%s| allocation: %s%s%s| bitpool: %u..%u)",
916 (value8[0] & 0x80) ? "16000 " : "",
917 (value8[0] & 0x40) ? "32000 " : "",
918 (value8[0] & 0x20) ? "44100 " : "",
919 (value8[0] & 0x10) ? "48000 " : "",
920 (value8[0] & 0xF0) ? "" : "not set ",
921 (value8[0] & 0x08) ? "Mono " : "",
922 (value8[0] & 0x04) ? "DualChannel " : "",
923 (value8[0] & 0x02) ? "Stereo " : "",
924 (value8[0] & 0x01) ? "JointStereo " : "",
925 (value8[0] & 0x0F) ? "" : "not set ",
926 (value8[1] & 0x80) ? "4 " : "",
927 (value8[1] & 0x40) ? "8 " : "",
928 (value8[1] & 0x20) ? "12 " : "",
929 (value8[1] & 0x10) ? "16 " : "",
930 (value8[1] & 0xF0) ? "" : "not set ",
931 (value8[1] & 0x08) ? "4 " : "",
932 (value8[1] & 0x04) ? "8 " : "",
933 (value8[1] & 0x0C) ? "" : "not set ",
934 (value8[1] & 0x02) ? "SNR " : "",
935 (value8[1] & 0x01) ? "Loudness " : "",
936 (value8[1] & 0x03) ? "" : "not set ",
937 value8[2],
938 value8[3]);
939 } else {
940 col_append_str(pinfo->cinfo, COL_INFO, " (none)");
941 proto_item_append_text(service_item, " (none)");
944 break;
945 case CODEC_MPEG12_AUDIO:
946 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_1, tvb, offset, 1, ENC_NA);
947 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_2, tvb, offset, 1, ENC_NA);
948 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_3, tvb, offset, 1, ENC_NA);
949 proto_tree_add_item(tree, hf_btavdtp_mpeg12_crc_protection, tvb, offset, 1, ENC_NA);
950 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_mono, tvb, offset, 1, ENC_NA);
951 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
952 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_stereo, tvb, offset, 1, ENC_NA);
953 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
955 proto_tree_add_item(tree, hf_btavdtp_mpeg12_rfa, tvb, offset + 1, 1, ENC_NA);
956 proto_tree_add_item(tree, hf_btavdtp_mpeg12_mpf_2, tvb, offset + 1, 1, ENC_NA);
957 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
958 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
959 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
960 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
961 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
962 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_48000, tvb, offset + 1, 1, ENC_NA);
964 proto_tree_add_item(tree, hf_btavdtp_mpeg12_vbr_supported, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
965 proto_tree_add_item(tree, hf_btavdtp_mpeg12_bit_rate, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
966 break;
967 case CODEC_MPEG24_AAC:
968 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc, tvb, offset, 1, ENC_NA);
969 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc, tvb, offset, 1, ENC_NA);
970 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp, tvb, offset, 1, ENC_NA);
971 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable, tvb, offset, 1, ENC_NA);
972 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_rfa, tvb, offset, 1, ENC_NA);
974 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_8000, tvb, offset + 1, 1, ENC_NA);
975 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_11025, tvb, offset + 1, 1, ENC_NA);
976 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_12000, tvb, offset + 1, 1, ENC_NA);
977 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
978 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
979 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
980 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
981 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
983 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_48000, tvb, offset + 2, 1, ENC_NA);
984 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_64000, tvb, offset + 2, 1, ENC_NA);
985 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_88200, tvb, offset + 2, 1, ENC_NA);
986 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_96000, tvb, offset + 2, 1, ENC_NA);
987 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_1, tvb, offset + 2, 1, ENC_NA);
988 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_2, tvb, offset + 2, 1, ENC_NA);
989 proto_tree_add_item(tree, hf_btavdtp_mpeg24_rfa, tvb, offset + 2, 1, ENC_NA);
991 proto_tree_add_item(tree, hf_btavdtp_mpeg24_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
992 proto_tree_add_item(tree, hf_btavdtp_mpeg24_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
993 break;
994 case CODEC_ATRAC:
995 proto_tree_add_item(tree, hf_btavdtp_atrac_version, tvb, offset, 1, ENC_NA);
996 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_single_channel, tvb, offset, 1, ENC_NA);
997 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
998 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
999 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa1, tvb, offset, 1, ENC_NA);
1001 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa2, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
1002 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_44100, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
1003 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_48000, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
1004 proto_tree_add_item(tree, hf_btavdtp_atrac_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
1005 proto_tree_add_item(tree, hf_btavdtp_atrac_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
1007 proto_tree_add_item(tree, hf_btavdtp_atrac_maximum_sul, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
1009 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa3, tvb, offset + 6, 1, ENC_NA);
1010 break;
1011 case CODEC_VENDOR: /* non-A2DP */
1012 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1014 if (vendor_id)
1015 *vendor_id = tvb_get_letohl(tvb, offset);
1017 if (vendor_codec)
1018 *vendor_codec = tvb_get_letohs(tvb, offset + 4);
1020 switch (tvb_get_letohl(tvb, offset)) {
1021 case 0x004F: /* APT Licensing Ltd. */
1022 case 0x00D7: /* Qualcomm Technologies, Inc. */
1023 proto_tree_add_item_ret_uint(tree, hf_btavdtp_vendor_apt_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN, &vendor_codec_id);
1024 switch (vendor_codec_id) {
1025 case VENDOR_APT_CODEC_ID_APT_X:
1026 case VENDOR_APT_CODEC_ID_APT_X_HD:
1028 if (vendor_codec_id == VENDOR_APT_CODEC_ID_APT_X) {
1029 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000, tvb, offset + 6, 1, ENC_NA);
1030 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000, tvb, offset + 6, 1, ENC_NA);
1031 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
1032 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
1033 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
1034 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel, tvb, offset + 6, 1, ENC_NA);
1035 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
1036 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo, tvb, offset + 6, 1, ENC_NA);
1037 } else {
1038 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000, tvb, offset + 6, 1, ENC_NA);
1039 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000, tvb, offset + 6, 1, ENC_NA);
1040 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
1041 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
1042 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
1043 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel, tvb, offset + 6, 1, ENC_NA);
1044 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
1045 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo, tvb, offset + 6, 1, ENC_NA);
1046 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_rfa, tvb, offset + 7, 4, ENC_NA);
1049 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s -",
1050 val_to_str_const(vendor_codec_id, vendor_apt_codec_vals, "unknown codec"));
1051 proto_item_append_text(service_item, " (%s -",
1052 val_to_str_const(vendor_codec_id, vendor_apt_codec_vals, "unknown codec"));
1054 value = tvb_get_uint8(tvb, offset + 6);
1055 if (value) {
1056 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s,%s%s%s%s%s)",
1057 (value & 0x80) ? " 16000" : "",
1058 (value & 0x40) ? " 32000" : "",
1059 (value & 0x20) ? " 44100" : "",
1060 (value & 0x10) ? " 48000" : "",
1061 (value & 0xF0) ? "" : " not set",
1062 (value & 0x08) ? " Mono" : "",
1063 (value & 0x04) ? " DualChannel" : "",
1064 (value & 0x02) ? " Stereo" : "",
1065 (value & 0x01) ? " JointStereo" : "",
1066 (value & 0x0F) ? "" : " not set");
1068 proto_item_append_text(service_item, "%s%s%s%s%s,%s%s%s%s%s)",
1069 (value & 0x80) ? " 16000" : "",
1070 (value & 0x40) ? " 32000" : "",
1071 (value & 0x20) ? " 44100" : "",
1072 (value & 0x10) ? " 48000" : "",
1073 (value & 0xF0) ? "" : " not set",
1074 (value & 0x08) ? " Mono" : "",
1075 (value & 0x04) ? " DualChannel" : "",
1076 (value & 0x02) ? " Stereo" : "",
1077 (value & 0x01) ? " JointStereo" : "",
1078 (value & 0x0F) ? "" : " not set");
1079 } else {
1080 col_append_str(pinfo->cinfo, COL_INFO, " none)");
1081 proto_item_append_text(service_item, " none)");
1083 break;
1084 default:
1085 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1087 break;
1088 case 0x012D: /* Sony Corporation */
1089 proto_tree_add_item_ret_uint(tree, hf_btavdtp_vendor_sony_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN, &vendor_codec_id);
1090 switch (vendor_codec_id) {
1091 case VENDOR_SONY_CODEC_ID_LDAC:
1092 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_rfa1, tvb, offset + 6, 1, ENC_NA);
1093 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
1094 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
1095 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_88200, tvb, offset + 6, 1, ENC_NA);
1096 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_96000, tvb, offset + 6, 1, ENC_NA);
1097 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_176400, tvb, offset + 6, 1, ENC_NA);
1098 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_sampling_frequency_192000, tvb, offset + 6, 1, ENC_NA);
1099 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_rfa2, tvb, offset + 7, 1, ENC_NA);
1100 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_channel_mode_mono, tvb, offset + 7, 1, ENC_NA);
1101 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_channel_mode_dual_channel, tvb, offset + 7, 1, ENC_NA);
1102 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_ldac_channel_mode_stereo, tvb, offset + 7, 1, ENC_NA);
1104 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s -",
1105 val_to_str_const(vendor_codec_id, vendor_sony_codec_vals, "unknown codec"));
1106 proto_item_append_text(service_item, " (%s -",
1107 val_to_str_const(vendor_codec_id, vendor_sony_codec_vals, "unknown codec"));
1109 value = tvb_get_h_uint16(tvb, offset + 6);
1110 if (value != 0) {
1111 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s%s%s,%s%s%s%s)",
1112 (value8[0] & 0x20) ? " 44100" : "",
1113 (value8[0] & 0x10) ? " 48000" : "",
1114 (value8[0] & 0x08) ? " 88200" : "",
1115 (value8[0] & 0x04) ? " 96000" : "",
1116 (value8[0] & 0x02) ? " 176400" : "",
1117 (value8[0] & 0x01) ? " 192000" : "",
1118 (value8[0] & 0x3F) ? "" : " not set",
1119 (value8[1] & 0x04) ? " Mono" : "",
1120 (value8[1] & 0x02) ? " DualChannel" : "",
1121 (value8[1] & 0x01) ? " Stereo" : "",
1122 (value8[1] & 0x07) ? "" : " not set");
1124 proto_item_append_text(service_item, "%s%s%s%s%s%s%s,%s%s%s%s)",
1125 (value8[0] & 0x20) ? " 44100" : "",
1126 (value8[0] & 0x10) ? " 48000" : "",
1127 (value8[0] & 0x08) ? " 88200" : "",
1128 (value8[0] & 0x04) ? " 96000" : "",
1129 (value8[0] & 0x02) ? " 176400" : "",
1130 (value8[0] & 0x01) ? " 192000" : "",
1131 (value8[0] & 0x3F) ? "" : " not set",
1132 (value8[1] & 0x04) ? " Mono" : "",
1133 (value8[1] & 0x02) ? " DualChannel" : "",
1134 (value8[1] & 0x01) ? " Stereo" : "",
1135 (value8[1] & 0x07) ? "" : " not set");
1136 } else {
1137 col_append_str(pinfo->cinfo, COL_INFO, " none)");
1138 proto_item_append_text(service_item, " none)");
1140 break;
1141 default:
1142 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1144 break;
1145 case 0x00E0: /* Google */
1146 proto_tree_add_item_ret_uint(tree, hf_btavdtp_vendor_google_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN, &vendor_codec_id);
1147 switch (vendor_codec_id) {
1148 case VENDOR_GOOGLE_CODEC_ID_OPUS:
1149 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
1150 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_rfa, tvb, offset + 6, 1, ENC_NA);
1151 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_frame_duration_20, tvb, offset + 6, 1, ENC_NA);
1152 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_frame_duration_10, tvb, offset + 6, 1, ENC_NA);
1153 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_channel_mode_dual, tvb, offset + 6, 1, ENC_NA);
1154 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
1155 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_opus_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
1157 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s -",
1158 val_to_str_const(vendor_codec_id, vendor_google_codec_vals, "unknown codec"));
1159 proto_item_append_text(service_item, " (%s -",
1160 val_to_str_const(vendor_codec_id, vendor_google_codec_vals, "unknown codec"));
1162 value = tvb_get_uint8(tvb, offset + 6);
1163 if (value) {
1164 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s,%s%s%s%s)",
1165 (value & 0x80) ? " 48000" : "",
1166 (value & 0x80) ? "" : " not set",
1167 (value & 0x04) ? " Dual" : "",
1168 (value & 0x02) ? " Stereo" : "",
1169 (value & 0x01) ? " Mono" : "",
1170 (value & 0x07) ? "" : " not set");
1172 proto_item_append_text(service_item, "%s%s,%s%s%s%s)",
1173 (value & 0x80) ? " 48000" : "",
1174 (value & 0x80) ? "" : " not set",
1175 (value & 0x04) ? " Dual" : "",
1176 (value & 0x02) ? " Stereo" : "",
1177 (value & 0x01) ? " Mono" : "",
1178 (value & 0x07) ? "" : " not set");
1179 } else {
1180 col_append_str(pinfo->cinfo, COL_INFO, " none)");
1181 proto_item_append_text(service_item, " none)");
1183 break;
1184 default:
1185 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1187 break;
1188 default:
1189 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1190 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1193 break;
1194 default:
1195 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1197 break;
1198 case MEDIA_TYPE_VIDEO:
1199 switch(media_codec_type) {
1200 case CODEC_H263_BASELINE:
1201 case CODEC_H263_PROFILE_3:
1202 case CODEC_H263_PROFILE_8:
1203 proto_tree_add_item(tree, hf_btavdtp_h263_level_10, tvb, offset, 1, ENC_NA);
1204 proto_tree_add_item(tree, hf_btavdtp_h263_level_20, tvb, offset, 1, ENC_NA);
1205 proto_tree_add_item(tree, hf_btavdtp_h263_level_30, tvb, offset, 1, ENC_NA);
1206 proto_tree_add_item(tree, hf_btavdtp_h263_level_rfa, tvb, offset, 1, ENC_NA);
1207 break;
1208 case CODEC_MPEG4_VSP:
1209 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_0, tvb, offset, 1, ENC_NA);
1210 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_1, tvb, offset, 1, ENC_NA);
1211 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_2, tvb, offset, 1, ENC_NA);
1212 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_3, tvb, offset, 1, ENC_NA);
1213 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_rfa, tvb, offset, 1, ENC_NA);
1214 break;
1215 case CODEC_VENDOR: /* non-VDP */
1216 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1217 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1218 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1219 break;
1220 default:
1221 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1223 break;
1224 default:
1225 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1228 offset += losc;
1230 return offset;
1234 static int
1235 dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo,
1236 proto_tree *tree, int offset, int *codec,
1237 int *content_protection_type, uint32_t *vendor_id,
1238 uint16_t *vendor_codec, uint32_t *configuration_offset,
1239 uint8_t *configuration_length)
1241 proto_item *pitem = NULL;
1242 proto_item *ptree = NULL;
1243 proto_tree *capabilities_tree;
1244 proto_item *capabilities_item;
1245 proto_tree *service_tree = NULL;
1246 proto_item *service_item = NULL;
1247 int service_category = 0;
1248 int losc = 0;
1249 int recovery_type = 0;
1250 int maximum_recovery_window_size = 0;
1251 int maximum_number_of_media_packet_in_parity_code = 0;
1252 int media_type = 0;
1253 int media_codec_type = 0;
1255 capabilities_item = proto_tree_add_item(tree, hf_btavdtp_capabilities, tvb, offset, tvb_reported_length(tvb) - offset, ENC_NA);
1256 capabilities_tree = proto_item_add_subtree(capabilities_item, ett_btavdtp_capabilities);
1258 if (codec)
1259 *codec = -1;
1261 if (vendor_id)
1262 *vendor_id = 0x003F; /* Bluetooth SIG */
1264 if (vendor_codec)
1265 *vendor_codec = 0;
1267 if (configuration_length)
1268 *configuration_length = 0;
1270 if (configuration_offset)
1271 *configuration_offset = 0;
1273 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1274 service_category = tvb_get_uint8(tvb, offset);
1275 losc = tvb_get_uint8(tvb, offset + 1);
1276 service_item = proto_tree_add_none_format(capabilities_tree, hf_btavdtp_service, tvb, offset, 2 + losc, "Service: %s", val_to_str_const(service_category, service_category_vals, "RFD"));
1277 service_tree = proto_item_add_subtree(service_item, ett_btavdtp_service);
1279 proto_tree_add_item(service_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1280 offset += 1;
1282 proto_tree_add_item(service_tree, hf_btavdtp_length_of_service_category, tvb, offset, 1, ENC_NA);
1283 offset += 1;
1285 switch (service_category) {
1286 case SERVICE_CATEGORY_MEDIA_TRANSPORT:
1287 case SERVICE_CATEGORY_REPORTING:
1288 case SERVICE_CATEGORY_DELAY_REPORTING:
1289 /* losc should be 0 */
1290 break;
1291 case SERVICE_CATEGORY_RECOVERY:
1292 recovery_type = tvb_get_uint8(tvb, offset);
1293 pitem = proto_tree_add_item(service_tree, hf_btavdtp_recovery_type, tvb, offset, 1, ENC_NA);
1294 proto_item_append_text(pitem, " (%s)", val_to_str_const(recovery_type, recovery_type_vals, "RFD"));
1295 offset += 1;
1296 losc -= 1;
1298 maximum_recovery_window_size = tvb_get_uint8(tvb, offset);
1299 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1300 if (maximum_recovery_window_size == 0x00) {
1301 proto_item_append_text(pitem, " (Forbidden)");
1302 } else if (maximum_recovery_window_size >= 0x18) {
1303 proto_item_append_text(pitem, " (Undocumented)");
1305 offset += 1;
1306 losc -= 1;
1308 maximum_number_of_media_packet_in_parity_code = tvb_get_uint8(tvb, offset);
1309 proto_tree_add_item(service_tree, hf_btavdtp_maximum_number_of_media_packet_in_parity_code, tvb, offset, 1, ENC_NA);
1310 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1311 if (maximum_number_of_media_packet_in_parity_code == 0x00) {
1312 proto_item_append_text(pitem, " (Forbidden)");
1313 } else if (maximum_number_of_media_packet_in_parity_code >= 0x18) {
1314 proto_item_append_text(pitem, " (Undocumented)");
1316 offset += 1;
1317 losc -= 1;
1318 break;
1319 case SERVICE_CATEGORY_MEDIA_CODEC:
1320 if (configuration_length)
1321 *configuration_length = losc;
1322 if (configuration_offset)
1323 *configuration_offset = offset;
1325 media_type = tvb_get_uint8(tvb, offset) >> 4;
1326 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_media_type, tvb, offset, 1, ENC_NA);
1327 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_rfa , tvb, offset, 1, ENC_NA);
1328 offset += 1;
1329 losc -= 1;
1331 media_codec_type = tvb_get_uint8(tvb, offset);
1332 if (codec) {
1333 *codec = media_codec_type;
1336 if (media_type == MEDIA_TYPE_AUDIO) {
1337 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_audio_type, tvb, offset, 1, ENC_NA);
1338 proto_item_append_text(service_item, " - Audio %s",
1339 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1340 col_append_fstr(pinfo->cinfo, COL_INFO, " - Audio %s",
1341 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1342 } else if (media_type == MEDIA_TYPE_VIDEO) {
1343 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_video_type, tvb, offset, 1, ENC_NA);
1344 proto_item_append_text(service_item, " - Video %s",
1345 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1346 col_append_fstr(pinfo->cinfo, COL_INFO, " - Video %s",
1347 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1348 } else {
1349 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_unknown_type, tvb, offset, 1, ENC_NA);
1350 proto_item_append_text(service_item, " - Unknown 0x%02x", media_codec_type);
1351 col_append_fstr(pinfo->cinfo, COL_INFO, " - Unknown 0x%02x", media_codec_type);
1353 offset += 1;
1354 losc -= 1;
1356 offset = dissect_codec(tvb, pinfo, service_item, service_tree,
1357 offset, losc, media_type, media_codec_type,
1358 vendor_id, vendor_codec);
1359 losc = 0;
1360 break;
1361 case SERVICE_CATEGORY_CONTENT_PROTECTION:
1362 proto_tree_add_item(service_tree, hf_btavdtp_content_protection_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1363 if (content_protection_type) {
1364 *content_protection_type = tvb_get_letohs(tvb, offset);
1366 proto_item_append_text(service_item, " - %s",
1367 val_to_str_const(tvb_get_letohs(tvb, offset), content_protection_type_vals, "unknown"));
1369 offset += 2;
1370 losc -= 2;
1372 if (losc > 0) {
1373 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1374 offset += losc;
1375 losc = 0;
1377 break;
1378 case SERVICE_CATEGORY_HEADER_COMPRESSION:
1379 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_backch, tvb, offset, 1, ENC_NA);
1380 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_media, tvb, offset, 1, ENC_NA);
1381 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_recovery, tvb, offset, 1, ENC_NA);
1382 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_rfa, tvb, offset, 1, ENC_NA);
1383 offset += 1;
1384 losc -= 1;
1385 break;
1386 case SERVICE_CATEGORY_MULTIPLEXING:
1387 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_fragmentation, tvb, offset, 1, ENC_NA);
1388 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_rfa, tvb, offset, 1, ENC_NA);
1389 offset += 1;
1390 losc -= 1;
1392 if (losc >= 2) {
1393 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Media Transport Session");
1394 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1396 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1397 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1398 offset += 1;
1399 losc -= 1;
1400 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1401 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1402 offset += 1;
1403 losc -= 1;
1406 if (losc >= 2) {
1407 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Reporting Transport Session");
1408 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1410 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1411 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1412 offset += 1;
1413 losc -= 1;
1414 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1415 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1416 offset += 1;
1417 losc -= 1;
1420 if (losc >= 2) {
1421 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Recovery Transport Session");
1422 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1424 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1425 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1426 offset += 1;
1427 losc -= 1;
1428 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1429 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1430 offset += 1;
1431 losc -= 1;
1433 break;
1434 default:
1435 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1436 offset += losc;
1437 losc = 0;
1440 if (losc > 0) {
1441 pitem = proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1442 offset += losc;
1444 expert_add_info(pinfo, pitem, &ei_btavdtp_unexpected_losc_data);
1448 return offset;
1451 static int
1452 dissect_seid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1453 int seid_side, int i_item, uint32_t *sep_seid,
1454 uint32_t interface_id, uint32_t adapter_id, uint32_t chandle,
1455 uint32_t frame_number)
1457 uint32_t seid;
1458 proto_tree *seid_tree = NULL;
1459 proto_item *seid_item = NULL;
1460 uint32_t direction;
1462 seid = tvb_get_uint8(tvb, offset) >> 2;
1463 if (sep_seid) {
1464 *sep_seid = seid;
1467 if (seid_side == SEID_ACP) {
1468 direction = pinfo->p2p_dir;
1469 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_seid_item, tvb, offset, 1,
1470 "ACP SEID [%u - %s %s]", seid,
1471 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1472 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1473 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1474 proto_tree_add_item(seid_tree, hf_btavdtp_acp_seid, tvb, offset, 1, ENC_NA);
1475 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1477 col_append_fstr(pinfo->cinfo, COL_INFO, " - ACP SEID [%u - %s %s]",
1478 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1479 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1480 } else {
1481 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
1482 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_int_seid_item, tvb, offset, 1,
1483 "INT SEID [%u - %s %s]", seid,
1484 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1485 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1486 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1487 proto_tree_add_item(seid_tree, hf_btavdtp_int_seid, tvb, offset, 1, ENC_NA);
1488 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1490 col_append_fstr(pinfo->cinfo, COL_INFO, " - INT SEID [%u - %s %s]",
1491 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1492 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1495 proto_tree_add_item(seid_tree, hf_btavdtp_rfa_seid, tvb, offset, 1, ENC_NA);
1496 offset += 1;
1498 return offset;
1502 static int
1503 dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1505 proto_item *ti;
1506 proto_tree *btavdtp_tree = NULL;
1507 proto_tree *signal_tree = NULL;
1508 proto_item *signal_item = NULL;
1509 btl2cap_data_t *l2cap_data;
1510 int offset = 0;
1511 int i_sep = 1;
1512 int packet_type = 0;
1513 int message_type = 0;
1514 int signal_id = 0;
1515 unsigned delay;
1516 wmem_tree_t *subtree;
1517 wmem_tree_key_t key[8];
1518 channels_info_t *channels_info;
1519 uint32_t interface_id;
1520 uint32_t adapter_id;
1521 uint32_t chandle;
1522 uint32_t psm;
1523 uint32_t direction;
1524 uint32_t cid;
1525 uint32_t frame_number;
1526 sep_entry_t *sep;
1527 tvbuff_t *next_tvb;
1528 uint32_t seid;
1529 int codec = -1;
1530 int content_protection_type = 0;
1531 uint32_t configuration_offset;
1532 uint8_t configuration_length;
1534 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP");
1536 direction = pinfo->p2p_dir;
1537 switch (direction) {
1538 case P2P_DIR_SENT:
1539 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
1540 break;
1542 case P2P_DIR_RECV:
1543 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
1544 break;
1545 default:
1546 col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
1547 goto LABEL_data;
1550 l2cap_data = (btl2cap_data_t *) data;
1551 DISSECTOR_ASSERT(l2cap_data);
1553 interface_id = l2cap_data->interface_id;
1554 adapter_id = l2cap_data->adapter_id;
1555 chandle = l2cap_data->chandle;
1556 psm = l2cap_data->psm;
1557 cid = l2cap_data->cid;
1558 frame_number = pinfo->num;
1560 key[0].length = 1;
1561 key[0].key = &interface_id;
1562 key[1].length = 1;
1563 key[1].key = &adapter_id;
1564 key[2].length = 1;
1565 key[2].key = &chandle;
1566 key[3].length = 1;
1567 key[3].key = &psm;
1568 key[4].length = 0;
1569 key[4].key = NULL;
1571 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(channels, key);
1572 channels_info = (subtree) ? (channels_info_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1573 if (!(channels_info &&
1574 ((*channels_info->adapter_disconnect_in_frame >= pinfo->num &&
1575 *channels_info->hci_disconnect_in_frame >= pinfo->num &&
1576 *channels_info->l2cap_disconnect_in_frame >= pinfo->num &&
1577 channels_info->disconnect_in_frame >= pinfo->num) ||
1578 (*channels_info->adapter_disconnect_in_frame == 0 ||
1579 *channels_info->hci_disconnect_in_frame == 0 ||
1580 *channels_info->l2cap_disconnect_in_frame == 0 ||
1581 channels_info->disconnect_in_frame == 0)))) {
1583 channels_info = (channels_info_t *) wmem_new (wmem_file_scope(), channels_info_t);
1584 channels_info->control_local_cid = l2cap_data->local_cid;
1585 channels_info->control_remote_cid = l2cap_data->remote_cid;
1586 channels_info->media_local_cid = BTL2CAP_UNKNOWN_CID;
1587 channels_info->media_remote_cid = BTL2CAP_UNKNOWN_CID;
1588 channels_info->disconnect_in_frame = bluetooth_max_disconnect_in_frame;
1589 channels_info->l2cap_disconnect_in_frame = l2cap_data->disconnect_in_frame;
1590 channels_info->hci_disconnect_in_frame = l2cap_data->hci_disconnect_in_frame;
1591 channels_info->adapter_disconnect_in_frame = l2cap_data->adapter_disconnect_in_frame;
1592 channels_info->sep = NULL;
1594 if (!pinfo->fd->visited || (
1595 *channels_info->adapter_disconnect_in_frame == 0 ||
1596 *channels_info->hci_disconnect_in_frame == 0 ||
1597 *channels_info->l2cap_disconnect_in_frame == 0 ||
1598 channels_info->disconnect_in_frame == 0)) {
1599 key[4].length = 1;
1600 key[4].key = &frame_number;
1601 key[5].length = 0;
1602 key[5].key = NULL;
1604 channels_info->stream_numbers = wmem_tree_new(wmem_file_scope());
1606 if (*channels_info->adapter_disconnect_in_frame > 0 &&
1607 *channels_info->hci_disconnect_in_frame > 0 &&
1608 *channels_info->l2cap_disconnect_in_frame > 0 &&
1609 channels_info->disconnect_in_frame > 0) {
1610 wmem_tree_insert32_array(channels, key, channels_info);
1612 } else {
1613 channels_info->stream_numbers = NULL;
1617 if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1618 l2cap_data->remote_cid == channels_info->control_remote_cid) &&
1619 (channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID ||
1620 (l2cap_data->local_cid == channels_info->media_local_cid &&
1621 l2cap_data->remote_cid == channels_info->media_remote_cid))) {
1623 if (!pinfo->fd->visited && channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID) {
1624 channels_info->media_local_cid = l2cap_data->local_cid;
1625 channels_info->media_remote_cid = l2cap_data->remote_cid;
1627 /* Media Channel */
1629 if (!channels_info->sep) {
1630 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1631 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1633 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1634 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1635 } else {
1636 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream ACP SEID [%u - %s %s]",
1637 channels_info->sep->seid, get_sep_media_type(
1638 interface_id, adapter_id, chandle, direction,
1639 channels_info->sep->seid,
1640 frame_number),
1641 get_sep_type(interface_id, adapter_id, chandle, direction,
1642 channels_info->sep->seid,
1643 frame_number));
1645 if (channels_info->sep->media_type == MEDIA_TYPE_AUDIO) {
1646 sep_data_t sep_data;
1647 media_stream_number_value_t *media_stream_number_value;
1648 media_packet_info_t *previous_media_packet_info;
1649 media_packet_info_t *current_media_packet_info;
1650 nstime_t first_abs_ts;
1651 double cumulative_frame_duration;
1652 double avrcp_song_position = -1.0;
1653 btavrcp_song_position_data_t *song_position_data;
1655 sep_data.codec = channels_info->sep->codec;
1656 sep_data.vendor_id = channels_info->sep->vendor_id;
1657 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1658 sep_data.acp_seid = channels_info->sep->seid;
1659 sep_data.int_seid = channels_info->sep->int_seid;
1660 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1661 sep_data.stream_start_in_frame = 0;
1662 sep_data.stream_end_in_frame = 0;
1663 sep_data.configuration_length = channels_info->sep->configuration_length;
1664 sep_data.configuration = channels_info->sep->configuration;
1666 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1667 if (media_stream_number_value) {
1668 sep_data.stream_number = media_stream_number_value->stream_number;
1669 if (media_stream_number_value->stream_start_in_frame == 0)
1670 media_stream_number_value->stream_start_in_frame = pinfo->num;
1672 if (!pinfo->fd->visited)
1673 media_stream_number_value->stream_end_in_frame = pinfo->num;
1675 sep_data.stream_start_in_frame = media_stream_number_value->stream_start_in_frame;
1676 sep_data.stream_end_in_frame = media_stream_number_value->stream_end_in_frame;
1677 } else {
1678 sep_data.stream_number = 1;
1681 key[0].length = 1;
1682 key[0].key = &interface_id;
1683 key[1].length = 1;
1684 key[1].key = &adapter_id;
1685 key[3].length = 1;
1686 key[3].key = &cid;
1687 key[4].length = 1;
1688 key[4].key = &direction;
1689 key[5].length = 0;
1690 key[5].key = NULL;
1692 key[2].length = 0;
1693 key[2].key = NULL;
1695 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(btavrcp_song_positions, key);
1696 song_position_data = (subtree) ? (btavrcp_song_position_data_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1697 if (song_position_data && (song_position_data->used_in_frame == 0 ||
1698 song_position_data->used_in_frame == frame_number)) {
1699 avrcp_song_position = song_position_data->song_position;
1700 if (!pinfo->fd->visited)
1701 song_position_data->used_in_frame = frame_number;
1704 key[2].length = 1;
1705 key[2].key = &chandle;
1707 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1708 previous_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32_le(subtree, frame_number - 1) : NULL;
1709 if (previous_media_packet_info && previous_media_packet_info->stream_number == sep_data.stream_number ) {
1710 sep_data.previous_media_packet_info = previous_media_packet_info;
1711 first_abs_ts = previous_media_packet_info->first_abs_ts;
1712 cumulative_frame_duration = previous_media_packet_info->cumulative_frame_duration;
1713 if (avrcp_song_position == -1.0)
1714 avrcp_song_position = previous_media_packet_info->avrcp_song_position;
1715 else
1716 previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1717 } else {
1718 if (avrcp_song_position == -1.0)
1719 avrcp_song_position = 0.0;
1720 first_abs_ts = pinfo->abs_ts;
1721 cumulative_frame_duration = 0.0;
1722 sep_data.previous_media_packet_info = (media_packet_info_t *) wmem_new(wmem_epan_scope(), media_packet_info_t);
1723 sep_data.previous_media_packet_info->abs_ts = pinfo->abs_ts;
1724 sep_data.previous_media_packet_info->first_abs_ts = first_abs_ts;
1725 sep_data.previous_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1726 sep_data.previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1727 sep_data.previous_media_packet_info->stream_number = sep_data.stream_number;
1730 if (!pinfo->fd->visited) {
1731 key[5].length = 1;
1732 key[5].key = &frame_number;
1733 key[6].length = 0;
1734 key[6].key = NULL;
1736 if (avrcp_song_position == -1.0)
1737 avrcp_song_position = 0.0;
1739 current_media_packet_info = wmem_new(wmem_file_scope(), media_packet_info_t);
1740 current_media_packet_info->abs_ts = pinfo->abs_ts;
1741 current_media_packet_info->first_abs_ts = first_abs_ts;
1742 current_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1743 current_media_packet_info->avrcp_song_position = avrcp_song_position;
1744 current_media_packet_info->stream_number = sep_data.stream_number;
1746 wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info);
1749 key[5].length = 0;
1750 key[5].key = NULL;
1752 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1753 current_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32(subtree, frame_number) : NULL;
1754 if (current_media_packet_info)
1755 sep_data.current_media_packet_info = current_media_packet_info;
1756 else
1757 sep_data.current_media_packet_info = NULL;
1759 next_tvb = tvb_new_subset_remaining(tvb, offset);
1760 call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data);
1761 } else if (channels_info->sep->media_type == MEDIA_TYPE_VIDEO) {
1762 sep_data_t sep_data;
1763 media_stream_number_value_t *media_stream_number_value;
1765 sep_data.codec = channels_info->sep->codec;
1766 sep_data.vendor_id = channels_info->sep->vendor_id;
1767 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1768 sep_data.acp_seid = channels_info->sep->seid;
1769 sep_data.int_seid = channels_info->sep->int_seid;
1770 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1771 sep_data.stream_start_in_frame = 0;
1772 sep_data.stream_end_in_frame = 0;
1773 sep_data.configuration_length = channels_info->sep->configuration_length;
1774 sep_data.configuration = channels_info->sep->configuration;
1776 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1777 if (media_stream_number_value) {
1778 sep_data.stream_number = media_stream_number_value->stream_number;
1779 } else {
1780 sep_data.stream_number = 1;
1783 next_tvb = tvb_new_subset_remaining(tvb, offset);
1784 call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data);
1785 } else {
1786 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1787 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1789 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1790 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1794 return tvb_reported_length(tvb);
1795 } else if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1796 l2cap_data->remote_cid == channels_info->control_remote_cid)) {
1797 /* Unknown Stream Channel */
1798 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1799 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1801 col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown channel stream on cid=0x%04x", l2cap_data->cid);
1802 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1803 return tvb_reported_length(tvb);
1806 /* Signaling Channel */
1807 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1808 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1810 /* AVDTP signaling*/
1811 message_type = (tvb_get_uint8(tvb, offset) & AVDTP_MESSAGE_TYPE_MASK);
1812 packet_type = (tvb_get_uint8(tvb, offset) & AVDTP_PACKET_TYPE_MASK) >> 2;
1814 signal_item = proto_tree_add_item(btavdtp_tree, hf_btavdtp_signal, tvb, offset,
1815 (packet_type == PACKET_TYPE_START) ? 3 : 2, ENC_NA);
1816 signal_tree = proto_item_add_subtree(signal_item, ett_btavdtp_sep);
1818 proto_tree_add_item(signal_tree, hf_btavdtp_transaction, tvb, offset, 1, ENC_NA);
1819 proto_tree_add_item(signal_tree, hf_btavdtp_packet_type, tvb, offset, 1, ENC_NA);
1820 proto_tree_add_item(signal_tree, hf_btavdtp_message_type, tvb, offset, 1, ENC_NA);
1822 if (packet_type == PACKET_TYPE_START) {
1823 offset += 1;
1824 proto_tree_add_item(signal_tree, hf_btavdtp_number_of_signal_packets, tvb, offset, 1, ENC_NA);
1827 if (packet_type == PACKET_TYPE_CONTINUE || packet_type == PACKET_TYPE_END) goto LABEL_data;
1829 offset += 1;
1830 proto_tree_add_item(signal_tree, hf_btavdtp_rfa0, tvb, offset, 1, ENC_NA);
1831 proto_tree_add_item(signal_tree, hf_btavdtp_signal_id, tvb, offset, 1, ENC_NA);
1833 signal_id = tvb_get_uint8(tvb, offset) & AVDTP_SIGNAL_ID_MASK;
1834 proto_item_append_text(signal_item, ": %s (%s)",
1835 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"),
1836 val_to_str_const(message_type, message_type_vals, "Unknown message type"));
1838 col_append_fstr(pinfo->cinfo, COL_INFO, "%s - %s",
1839 val_to_str_const(message_type, message_type_vals, "Unknown message type"),
1840 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"));
1842 offset += 1;
1843 if (message_type != MESSAGE_TYPE_GENERAL_REJECT) switch (signal_id) {
1844 case SIGNAL_ID_DISCOVER:
1845 if (message_type == MESSAGE_TYPE_COMMAND) break;
1846 if (message_type == MESSAGE_TYPE_REJECT) {
1847 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1848 offset += 1;
1849 break;
1851 offset = dissect_sep(tvb, pinfo, btavdtp_tree, offset,
1852 interface_id, adapter_id, chandle);
1853 break;
1854 case SIGNAL_ID_GET_CAPABILITIES:
1855 case SIGNAL_ID_GET_ALL_CAPABILITIES:
1856 if (message_type == MESSAGE_TYPE_COMMAND) {
1857 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1858 SEID_ACP, 0, NULL, interface_id,
1859 adapter_id, chandle, frame_number);
1860 break;
1862 if (message_type == MESSAGE_TYPE_REJECT) {
1863 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1864 offset += 1;
1865 break;
1867 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1868 break;
1869 case SIGNAL_ID_SET_CONFIGURATION:
1870 if (message_type == MESSAGE_TYPE_COMMAND) {
1871 uint32_t int_seid;
1872 uint32_t vendor_id;
1873 uint16_t vendor_codec;
1874 uint32_t reverse_direction;
1876 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1877 SEID_ACP, 0, &seid, interface_id,
1878 adapter_id, chandle, frame_number);
1879 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1880 SEID_INT, 0, &int_seid, interface_id,
1881 adapter_id, chandle, frame_number);
1882 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1883 &codec, &content_protection_type, &vendor_id,
1884 &vendor_codec, &configuration_offset, &configuration_length);
1886 if (!pinfo->fd->visited) {
1887 key[0].length = 1;
1888 key[0].key = &interface_id;
1889 key[1].length = 1;
1890 key[1].key = &adapter_id;
1891 key[2].length = 1;
1892 key[2].key = &chandle;
1893 key[3].length = 1;
1894 key[3].key = &direction;
1895 key[4].length = 1;
1896 key[4].key = &seid;
1897 key[5].length = 0;
1898 key[5].key = NULL;
1900 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1901 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1902 if (sep) {
1903 sep->codec = codec;
1904 sep->vendor_id = vendor_id;
1905 sep->vendor_codec = vendor_codec;
1906 sep->content_protection_type = content_protection_type;
1907 sep->int_seid = int_seid;
1908 if (configuration_length > 0) {
1909 sep->configuration_length = configuration_length;
1910 sep->configuration = (uint8_t *) tvb_memdup(wmem_file_scope(),
1911 tvb, configuration_offset, configuration_length);
1914 if (direction == P2P_DIR_SENT)
1915 reverse_direction = P2P_DIR_RECV;
1916 else if (direction == P2P_DIR_RECV)
1917 reverse_direction = P2P_DIR_SENT;
1918 else
1919 reverse_direction = P2P_DIR_UNKNOWN;
1921 key[3].length = 1;
1922 key[3].key = &reverse_direction;
1923 key[4].length = 1;
1924 key[4].key = &int_seid;
1925 key[5].length = 1;
1926 key[5].key = &frame_number;
1927 key[6].length = 0;
1928 key[6].key = NULL;
1930 wmem_tree_insert32_array(sep_list, key, sep);
1935 break;
1937 if (message_type == MESSAGE_TYPE_REJECT) {
1938 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1939 offset += 1;
1941 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1942 offset += 1;
1943 break;
1945 break;
1946 case SIGNAL_ID_GET_CONFIGURATION:
1947 if (message_type == MESSAGE_TYPE_COMMAND) {
1948 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1949 SEID_ACP, 0, NULL, interface_id,
1950 adapter_id, chandle, frame_number);
1951 break;
1953 if (message_type == MESSAGE_TYPE_REJECT) {
1954 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1955 offset += 1;
1956 break;
1958 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1959 break;
1960 case SIGNAL_ID_RECONFIGURE:
1961 if (message_type == MESSAGE_TYPE_COMMAND) {
1962 uint32_t vendor_id;
1963 uint16_t vendor_codec;
1965 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1966 SEID_ACP, 0, &seid, interface_id,
1967 adapter_id, chandle, frame_number);
1968 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1969 &codec, &content_protection_type, &vendor_id,
1970 &vendor_codec, &configuration_offset, &configuration_length);
1972 if (!pinfo->fd->visited) {
1973 key[0].length = 1;
1974 key[0].key = &interface_id;
1975 key[1].length = 1;
1976 key[1].key = &adapter_id;
1977 key[2].length = 1;
1978 key[2].key = &chandle;
1979 key[3].length = 1;
1980 key[3].key = &direction;
1981 key[4].length = 1;
1982 key[4].key = &seid;
1983 key[5].length = 0;
1984 key[5].key = NULL;
1986 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1987 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1988 if (sep) {
1989 sep->codec = codec;
1990 sep->vendor_id = vendor_id;
1991 sep->vendor_codec = vendor_codec;
1992 sep->content_protection_type = content_protection_type;
1993 if (configuration_length > 0) {
1994 sep->configuration_length = configuration_length;
1995 sep->configuration = (uint8_t *) tvb_memdup(wmem_file_scope(),
1996 tvb, configuration_offset, configuration_length);
2001 break;
2003 if (message_type == MESSAGE_TYPE_REJECT) {
2004 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
2005 offset += 1;
2007 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2008 offset += 1;
2009 break;
2011 break;
2012 case SIGNAL_ID_OPEN:
2013 if (message_type == MESSAGE_TYPE_COMMAND) {
2014 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2015 SEID_ACP, 0, &seid, interface_id,
2016 adapter_id, chandle, frame_number);
2018 if (!pinfo->fd->visited) {
2019 key[0].length = 1;
2020 key[0].key = &interface_id;
2021 key[1].length = 1;
2022 key[1].key = &adapter_id;
2023 key[2].length = 1;
2024 key[2].key = &chandle;
2025 key[3].length = 1;
2026 key[3].key = &direction;
2027 key[4].length = 1;
2028 key[4].key = &seid;
2029 key[5].length = 0;
2030 key[5].key = NULL;
2032 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
2033 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
2034 if (sep) {
2035 sep->state = SEP_STATE_OPEN;
2037 key[3].length = 1;
2038 key[3].key = &frame_number;
2039 key[4].length = 0;
2040 key[4].key = NULL;
2042 wmem_tree_insert32_array(sep_open, key, sep);
2045 break;
2047 if (message_type == MESSAGE_TYPE_REJECT) {
2048 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2049 offset += 1;
2050 break;
2052 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->visited) {
2054 key[0].length = 1;
2055 key[0].key = &interface_id;
2056 key[1].length = 1;
2057 key[1].key = &adapter_id;
2058 key[2].length = 1;
2059 key[2].key = &chandle;
2060 key[3].length = 0;
2061 key[3].key = NULL;
2063 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_open, key);
2064 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
2065 if (sep && sep->state == SEP_STATE_OPEN) {
2066 sep->state = SEP_STATE_IN_USE;
2067 channels_info->sep = sep;
2070 break;
2071 case SIGNAL_ID_START:
2072 if (message_type == MESSAGE_TYPE_COMMAND) {
2073 i_sep = 1;
2074 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2075 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2076 SEID_ACP, i_sep, NULL,
2077 interface_id, adapter_id, chandle, frame_number);
2078 i_sep += 1;
2080 break;
2082 if (message_type == MESSAGE_TYPE_REJECT) {
2083 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2084 SEID_ACP, 0, NULL,
2085 interface_id, adapter_id, chandle, frame_number);
2086 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2087 offset += 1;
2088 break;
2091 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->visited) {
2092 media_stream_number_value_t *media_stream_number_value;
2093 uint32_t stream_number = 0;
2095 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
2096 #if RTP_PLAYER_WORKAROUND == true
2098 media_stream_number_value_t *file_scope_stream_number_value;
2100 if (media_stream_number_value) {
2101 stream_number = media_stream_number_value->stream_number;
2102 } else {
2103 file_scope_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(file_scope_stream_number, frame_number - 1);
2104 if (file_scope_stream_number_value)
2105 stream_number = file_scope_stream_number_value->stream_number + 1;
2106 else
2107 stream_number = 0;
2110 file_scope_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
2111 file_scope_stream_number_value->stream_number = stream_number;
2112 wmem_tree_insert32(file_scope_stream_number, frame_number, file_scope_stream_number_value);
2114 #else
2115 if (media_stream_number_value)
2116 stream_number = media_stream_number_value->stream_number;
2117 else
2118 stream_number = 0;
2119 #endif
2121 media_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
2122 media_stream_number_value->stream_number = stream_number + 1;
2123 media_stream_number_value->stream_start_in_frame = 0;
2124 media_stream_number_value->stream_end_in_frame = 0;
2126 wmem_tree_insert32(channels_info->stream_numbers, frame_number, media_stream_number_value);
2128 break;
2129 case SIGNAL_ID_CLOSE:
2130 if (message_type == MESSAGE_TYPE_COMMAND) {
2131 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2132 SEID_ACP, 0, NULL, interface_id,
2133 adapter_id, chandle, frame_number);
2134 break;
2136 if (message_type == MESSAGE_TYPE_REJECT) {
2137 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2138 offset += 1;
2139 break;
2141 if (!pinfo->fd->visited && message_type == MESSAGE_TYPE_ACCEPT &&
2142 channels_info->disconnect_in_frame > pinfo->num) {
2143 channels_info->disconnect_in_frame = pinfo->num;
2145 break;
2146 case SIGNAL_ID_SUSPEND:
2147 if (message_type == MESSAGE_TYPE_COMMAND) {
2148 i_sep = 1;
2149 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2150 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2151 SEID_ACP, i_sep, NULL,
2152 interface_id, adapter_id, chandle, frame_number);
2153 i_sep += 1;
2155 break;
2157 if (message_type == MESSAGE_TYPE_REJECT) {
2158 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2159 SEID_ACP, 0, NULL, interface_id,
2160 adapter_id, chandle, frame_number);
2161 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2162 offset += 1;
2163 break;
2165 break;
2166 case SIGNAL_ID_ABORT:
2167 if (message_type == MESSAGE_TYPE_COMMAND) {
2168 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2169 SEID_ACP, 0, NULL, interface_id,
2170 adapter_id, chandle, frame_number);
2171 break;
2173 if (message_type == MESSAGE_TYPE_REJECT) {
2174 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2175 offset += 1;
2176 break;
2178 if (!pinfo->fd->visited && message_type == MESSAGE_TYPE_ACCEPT &&
2179 channels_info->disconnect_in_frame > pinfo->num) {
2180 channels_info->disconnect_in_frame = pinfo->num;
2182 break;
2183 case SIGNAL_ID_SECURITY_CONTROL:
2184 if (message_type == MESSAGE_TYPE_COMMAND) {
2185 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2186 SEID_ACP, 0, NULL, interface_id,
2187 adapter_id, chandle, frame_number);
2188 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2189 offset += tvb_reported_length_remaining(tvb, offset);
2190 break;
2192 if (message_type == MESSAGE_TYPE_REJECT) {
2193 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2194 offset += 1;
2195 break;
2198 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2199 offset += tvb_reported_length_remaining(tvb, offset);
2200 break;
2201 case SIGNAL_ID_DELAY_REPORT:
2202 if (message_type == MESSAGE_TYPE_COMMAND) {
2203 proto_item *pitem;
2204 delay = tvb_get_ntohs(tvb, offset + 1);
2205 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u.%u ms)", delay/10, delay%10);
2206 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2207 SEID_ACP, 0, NULL,
2208 interface_id, adapter_id, chandle, frame_number);
2209 pitem = proto_tree_add_item(btavdtp_tree, hf_btavdtp_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
2210 proto_item_append_text(pitem, " (1/10 ms)");
2211 offset += 2;
2212 break;
2214 if (message_type == MESSAGE_TYPE_REJECT) {
2215 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2216 offset += 1;
2217 break;
2219 break;
2222 LABEL_data:
2224 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2225 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2228 return offset;
2232 void
2233 proto_register_btavdtp(void)
2235 module_t *module;
2237 static hf_register_info hf[] = {
2238 { &hf_btavdtp_signal,
2239 { "Signal", "btavdtp.signal",
2240 FT_NONE, BASE_NONE, NULL, 0x00,
2241 NULL, HFILL }
2243 { &hf_btavdtp_message_type,
2244 { "Message Type", "btavdtp.message_type",
2245 FT_UINT8, BASE_HEX, VALS(message_type_vals), AVDTP_MESSAGE_TYPE_MASK,
2246 NULL, HFILL }
2248 { &hf_btavdtp_packet_type,
2249 { "Packet Type", "btavdtp.packet_type",
2250 FT_UINT8, BASE_HEX, VALS(packet_type_vals), AVDTP_PACKET_TYPE_MASK,
2251 NULL, HFILL }
2253 { &hf_btavdtp_transaction,
2254 { "Transaction", "btavdtp.transaction",
2255 FT_UINT8, BASE_HEX, NULL, AVDTP_TRANSACTION_MASK,
2256 NULL, HFILL }
2258 { &hf_btavdtp_signal_id,
2259 { "Signal", "btavdtp.signal_id",
2260 FT_UINT8, BASE_HEX, VALS(signal_id_vals), AVDTP_SIGNAL_ID_MASK,
2261 NULL, HFILL }
2263 { &hf_btavdtp_rfa0,
2264 { "RFA", "btavdtp.rfa0",
2265 FT_UINT8, BASE_HEX, NULL, AVDTP_RFA0_MASK,
2266 NULL, HFILL }
2268 { &hf_btavdtp_number_of_signal_packets,
2269 { "Number of signal packets", "btavdtp.num_signal_packets",
2270 FT_UINT8, BASE_DEC, NULL, 0,
2271 NULL, HFILL }
2273 { &hf_btavdtp_error_code,
2274 { "Error Code", "btavdtp.error_code",
2275 FT_UINT8, BASE_HEX, VALS(error_code_vals), 0x00,
2276 NULL, HFILL }
2278 { &hf_btavdtp_sep_seid,
2279 { "SEID", "btavdtp.sep_seid",
2280 FT_UINT8, BASE_DEC, NULL, 0xFC,
2281 NULL, HFILL }
2283 { &hf_btavdtp_sep_inuse,
2284 { "In Use", "btavdtp.sep_inuse",
2285 FT_UINT8, BASE_HEX, VALS(true_false), 0x02,
2286 NULL, HFILL }
2288 { &hf_btavdtp_sep_rfa0,
2289 { "RFA0", "btavdtp.sep_rfa0",
2290 FT_UINT8, BASE_HEX, NULL, 0x01,
2291 NULL, HFILL }
2293 { &hf_btavdtp_sep_media_type,
2294 { "Media Type", "btavdtp.sep_media_type",
2295 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2296 NULL, HFILL }
2298 { &hf_btavdtp_sep_type,
2299 { "Type", "btavdtp.sep_type",
2300 FT_UINT8, BASE_HEX, VALS(sep_type_vals), 0x08,
2301 NULL, HFILL }
2303 { &hf_btavdtp_sep_rfa1,
2304 { "RFA1", "btavdtp.sep_rfa1",
2305 FT_UINT8, BASE_HEX, NULL, 0x07,
2306 NULL, HFILL }
2308 { &hf_btavdtp_acp_sep,
2309 { "ACP SEP", "btavdtp.acp_sep",
2310 FT_NONE, BASE_NONE, NULL, 0x00,
2311 NULL, HFILL }
2313 { &hf_btavdtp_acp_seid_item,
2314 { "ACP SEID", "btavdtp.acp_seid_item",
2315 FT_NONE, BASE_NONE, NULL, 0x00,
2316 NULL, HFILL }
2318 { &hf_btavdtp_int_seid_item,
2319 { "INT SEID", "btavdtp.int_seid_item",
2320 FT_NONE, BASE_NONE, NULL, 0x00,
2321 NULL, HFILL }
2323 { &hf_btavdtp_acp_seid,
2324 { "ACP SEID", "btavdtp.acp_seid",
2325 FT_UINT8, BASE_DEC, NULL, 0xFC,
2326 NULL, HFILL }
2328 { &hf_btavdtp_int_seid,
2329 { "INT SEID", "btavdtp.int_seid",
2330 FT_UINT8, BASE_DEC, NULL, 0xFC,
2331 NULL, HFILL }
2333 { &hf_btavdtp_rfa_seid,
2334 { "RFA", "btavdtp.rfa_seid",
2335 FT_UINT8, BASE_HEX, NULL, 0x03,
2336 NULL, HFILL }
2338 { &hf_btavdtp_service_category,
2339 { "Service Category", "btavdtp.service_category",
2340 FT_UINT8, BASE_HEX, VALS(service_category_vals), 0x00,
2341 NULL, HFILL }
2343 { &hf_btavdtp_length_of_service_category,
2344 { "Length of Service Category", "btavdtp.length_of_service_category",
2345 FT_UINT8, BASE_HEX, NULL, 0x00,
2346 NULL, HFILL }
2348 { &hf_btavdtp_delay,
2349 { "Delay", "btavdtp.delay",
2350 FT_UINT16, BASE_DEC, NULL, 0x00,
2351 NULL, HFILL }
2353 { &hf_btavdtp_recovery_type,
2354 { "Service Category", "btavdtp.recovery_type",
2355 FT_UINT8, BASE_HEX, VALS(recovery_type_vals), 0x00,
2356 NULL, HFILL }
2358 { &hf_btavdtp_maximum_recovery_window_size,
2359 { "Service Category", "btavdtp.maximum_recovery_window_size",
2360 FT_UINT8, BASE_HEX, NULL, 0x00,
2361 NULL, HFILL }
2363 { &hf_btavdtp_maximum_number_of_media_packet_in_parity_code,
2364 { "Service Category", "btavdtp.maximum_number_of_media_packet_in_parity_code",
2365 FT_UINT8, BASE_HEX, NULL, 0x00,
2366 NULL, HFILL }
2368 { &hf_btavdtp_multiplexing_fragmentation,
2369 { "Fragmentation", "btavdtp.multiplexing_fragmentation",
2370 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2371 NULL, HFILL }
2373 { &hf_btavdtp_multiplexing_rfa,
2374 { "RFA", "btavdtp.multiplexing_rfa",
2375 FT_UINT8, BASE_HEX, NULL, 0x7F,
2376 NULL, HFILL }
2378 { &hf_btavdtp_multiplexing_tsid,
2379 { "TSID", "btavdtp.multiplexing_tsid",
2380 FT_UINT8, BASE_HEX, VALS(multiplexing_tsid_vals), 0xF8,
2381 NULL, HFILL }
2383 { &hf_btavdtp_multiplexing_tcid,
2384 { "TCID", "btavdtp.multiplexing_tcid",
2385 FT_UINT8, BASE_HEX, VALS(multiplexing_tcid_vals), 0xF8,
2386 NULL, HFILL }
2388 { &hf_btavdtp_multiplexing_entry_rfa,
2389 { "RFA", "btavdtp.multiplexing_entry_rfa",
2390 FT_UINT8, BASE_HEX, NULL, 0x07,
2391 NULL, HFILL }
2393 { &hf_btavdtp_header_compression_backch,
2394 { "BackCh", "btavdtp.header_compression_backch",
2395 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2396 NULL, HFILL }
2398 { &hf_btavdtp_header_compression_media,
2399 { "Media", "btavdtp.header_compression_media",
2400 FT_UINT8, BASE_HEX, VALS(true_false), 0x40,
2401 NULL, HFILL }
2403 { &hf_btavdtp_header_compression_recovery,
2404 { "Recovery", "btavdtp.header_compression_recovery",
2405 FT_UINT8, BASE_HEX, VALS(true_false), 0x20,
2406 NULL, HFILL }
2408 { &hf_btavdtp_header_compression_rfa,
2409 { "RFA", "btavdtp.header_compression_rfa",
2410 FT_UINT8, BASE_HEX, NULL, 0x1f,
2411 NULL, HFILL }
2413 { &hf_btavdtp_content_protection_type,
2414 { "Type", "btavdtp.content_protection_type",
2415 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0,
2416 NULL, HFILL }
2418 { &hf_btavdtp_media_codec_media_type,
2419 { "Media Type", "btavdtp.media_codec_media_type",
2420 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2421 NULL, HFILL }
2423 { &hf_btavdtp_media_codec_rfa,
2424 { "RFA", "btavdtp.media_codec_rfa",
2425 FT_UINT8, BASE_HEX, NULL, 0x0F,
2426 NULL, HFILL }
2428 { &hf_btavdtp_media_codec_audio_type,
2429 { "Media Codec Audio Type", "btavdtp.media_codec_audio_type",
2430 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
2431 NULL, HFILL }
2433 { &hf_btavdtp_media_codec_video_type,
2434 { "Media Codec Video Type", "btavdtp.media_codec_video_type",
2435 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
2436 NULL, HFILL }
2438 { &hf_btavdtp_media_codec_unknown_type,
2439 { "Media Codec Unknown Type", "btavdtp.media_codec_unknown_type",
2440 FT_UINT8, BASE_HEX, NULL, 0x00,
2441 NULL, HFILL }
2443 { &hf_btavdtp_sbc_sampling_frequency_16000,
2444 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2445 FT_BOOLEAN, 8, NULL, 0x80,
2446 NULL, HFILL }
2448 { &hf_btavdtp_sbc_sampling_frequency_32000,
2449 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2450 FT_BOOLEAN, 8, NULL, 0x40,
2451 NULL, HFILL }
2453 { &hf_btavdtp_sbc_sampling_frequency_44100,
2454 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2455 FT_BOOLEAN, 8, NULL, 0x20,
2456 NULL, HFILL }
2458 { &hf_btavdtp_sbc_sampling_frequency_48000,
2459 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2460 FT_BOOLEAN, 8, NULL, 0x10,
2461 NULL, HFILL }
2463 { &hf_btavdtp_sbc_channel_mode_mono,
2464 { "Channel Mode Mono", "btavdtp.codec.sbc.channel_mode.mono",
2465 FT_BOOLEAN, 8, NULL, 0x08,
2466 NULL, HFILL }
2468 { &hf_btavdtp_sbc_channel_mode_dual_channel,
2469 { "Channel Mode Dual Channel", "btavdtp.codec.sbc.channel_mode.dual_channel",
2470 FT_BOOLEAN, 8, NULL, 0x04,
2471 NULL, HFILL }
2473 { &hf_btavdtp_sbc_channel_mode_stereo,
2474 { "Channel Mode Stereo", "btavdtp.codec.sbc.channel_mode.stereo",
2475 FT_BOOLEAN, 8, NULL, 0x02,
2476 NULL, HFILL }
2478 { &hf_btavdtp_sbc_channel_mode_joint_stereo,
2479 { "Channel Mode Joint Stereo", "btavdtp.codec.sbc.channel_mode.joint_stereo",
2480 FT_BOOLEAN, 8, NULL, 0x01,
2481 NULL, HFILL }
2483 { &hf_btavdtp_sbc_block_4,
2484 { "Block Length 4", "btavdtp.codec.sbc.block.4",
2485 FT_BOOLEAN, 8, NULL, 0x80,
2486 NULL, HFILL }
2488 { &hf_btavdtp_sbc_block_8,
2489 { "Block Length 8", "btavdtp.codec.sbc.block.8",
2490 FT_BOOLEAN, 8, NULL, 0x40,
2491 NULL, HFILL }
2493 { &hf_btavdtp_sbc_block_12,
2494 { "Block Length 12", "btavdtp.codec.sbc.block.12",
2495 FT_BOOLEAN, 8, NULL, 0x20,
2496 NULL, HFILL }
2498 { &hf_btavdtp_sbc_block_16,
2499 { "Block Length 16", "btavdtp.codec.sbc.block.16",
2500 FT_BOOLEAN, 8, NULL, 0x10,
2501 NULL, HFILL }
2503 { &hf_btavdtp_sbc_subbands_4,
2504 { "Subbands 4", "btavdtp.codec.sbc.subbands.4",
2505 FT_BOOLEAN, 8, NULL, 0x08,
2506 NULL, HFILL }
2508 { &hf_btavdtp_sbc_subbands_8,
2509 { "Subbands 8", "btavdtp.codec.sbc.subbands.8",
2510 FT_BOOLEAN, 8, NULL, 0x04,
2511 NULL, HFILL }
2513 { &hf_btavdtp_sbc_allocation_method_snr,
2514 { "Allocation Method SNR", "btavdtp.codec.sbc.allocation_method.snr",
2515 FT_BOOLEAN, 8, NULL, 0x02,
2516 NULL, HFILL }
2518 { &hf_btavdtp_sbc_allocation_method_loudness,
2519 { "Allocation Method Loudness", "btavdtp.codec.sbc.allocation_method.loudness",
2520 FT_BOOLEAN, 8, NULL, 0x01,
2521 NULL, HFILL }
2523 { &hf_btavdtp_sbc_min_bitpool,
2524 { "Minimum Bitpool", "btavdtp.codec.sbc.minimum_bitpool",
2525 FT_UINT8, BASE_DEC, NULL, 0x00,
2526 NULL, HFILL }
2528 { &hf_btavdtp_sbc_max_bitpool,
2529 { "Maximum Bitpool", "btavdtp.codec.sbc.maximum_bitpool",
2530 FT_UINT8, BASE_DEC, NULL, 0x00,
2531 NULL, HFILL }
2533 { &hf_btavdtp_mpeg12_layer_1,
2534 { "MP1", "btavdtp.codec.mpeg12.layer_1",
2535 FT_BOOLEAN, 8, NULL, 0x80,
2536 "MPEG Layer 1", HFILL }
2538 { &hf_btavdtp_mpeg12_layer_2,
2539 { "MP2", "btavdtp.codec.mpeg12.layer_2",
2540 FT_BOOLEAN, 8, NULL, 0x40,
2541 "MPEG Layer 2", HFILL }
2543 { &hf_btavdtp_mpeg12_layer_3,
2544 { "MP3", "btavdtp.codec.mpeg12.layer_3",
2545 FT_BOOLEAN, 8, NULL, 0x20,
2546 "MPEG Layer 3", HFILL }
2548 { &hf_btavdtp_mpeg12_crc_protection,
2549 { "CRC Protection", "btavdtp.codec.mpeg12.crc_protection",
2550 FT_BOOLEAN, 8, NULL, 0x10,
2551 NULL, HFILL }
2553 { &hf_btavdtp_mpeg12_channel_mode_mono,
2554 { "Channel Mode Mono", "btavdtp.codec.mpeg12.channel_mode.mono",
2555 FT_BOOLEAN, 8, NULL, 0x08,
2556 NULL, HFILL }
2558 { &hf_btavdtp_mpeg12_channel_mode_dual_channel,
2559 { "Channel Mode Dual Channel", "btavdtp.codec.mpeg12.channel_mode.dual_channel",
2560 FT_BOOLEAN, 8, NULL, 0x04,
2561 NULL, HFILL }
2563 { &hf_btavdtp_mpeg12_channel_mode_stereo,
2564 { "Channel Mode Stereo", "btavdtp.codec.mpeg12.channel_mode.stereo",
2565 FT_BOOLEAN, 8, NULL, 0x02,
2566 NULL, HFILL }
2568 { &hf_btavdtp_mpeg12_channel_mode_joint_stereo,
2569 { "Channel Mode Joint Stereo", "btavdtp.codec.mpeg12.channel_mode.joint_stereo",
2570 FT_BOOLEAN, 8, NULL, 0x01,
2571 NULL, HFILL }
2573 { &hf_btavdtp_mpeg12_rfa,
2574 { "RFA", "btavdtp.codec.mpeg12.rfa",
2575 FT_BOOLEAN, 8, NULL, 0x80,
2576 NULL, HFILL }
2578 { &hf_btavdtp_mpeg12_mpf_2,
2579 { "Media Payload Format 2", "btavdtp.codec.mpeg12.mpf_2",
2580 FT_BOOLEAN, 8, NULL, 0x40,
2581 NULL, HFILL }
2583 { &hf_btavdtp_mpeg12_sampling_frequency_16000,
2584 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2585 FT_BOOLEAN, 8, NULL, 0x20,
2586 NULL, HFILL }
2588 { &hf_btavdtp_mpeg12_sampling_frequency_22050,
2589 { "Sampling Frequency 22050 Hz", "btavdtp.codec.sbc.sampling_frequency.22050",
2590 FT_BOOLEAN, 8, NULL, 0x10,
2591 NULL, HFILL }
2593 { &hf_btavdtp_mpeg12_sampling_frequency_24000,
2594 { "Sampling Frequency 24000 Hz", "btavdtp.codec.sbc.sampling_frequency.24000",
2595 FT_BOOLEAN, 8, NULL, 0x08,
2596 NULL, HFILL }
2598 { &hf_btavdtp_mpeg12_sampling_frequency_32000,
2599 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2600 FT_BOOLEAN, 8, NULL, 0x04,
2601 NULL, HFILL }
2603 { &hf_btavdtp_mpeg12_sampling_frequency_44100,
2604 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2605 FT_BOOLEAN, 8, NULL, 0x02,
2606 NULL, HFILL }
2608 { &hf_btavdtp_mpeg12_sampling_frequency_48000,
2609 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2610 FT_BOOLEAN, 8, NULL, 0x01,
2611 NULL, HFILL }
2613 { &hf_btavdtp_mpeg12_vbr_supported,
2614 { "VBR Supported", "btavdtp.codec.mpeg12.vbr",
2615 FT_BOOLEAN, 16, NULL, 0x8000,
2616 NULL, HFILL }
2618 { &hf_btavdtp_mpeg12_bit_rate,
2619 { "Bit Rate", "btavdtp.codec.mpeg12.bit_rate",
2620 FT_UINT16, BASE_HEX, NULL, 0x7FFF,
2621 NULL, HFILL }
2623 { &hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc,
2624 { "MPEG2 AAC LC", "btavdtp.codec.mpeg24.object_type.mpeg2_aac_lc",
2625 FT_BOOLEAN, 8, NULL, 0x80,
2626 NULL, HFILL }
2628 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc,
2629 { "MPEG4 AAC LC", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_lc",
2630 FT_BOOLEAN, 8, NULL, 0x40,
2631 NULL, HFILL }
2633 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp,
2634 { "MPEG4 AAC LTP", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_ltp",
2635 FT_BOOLEAN, 8, NULL, 0x20,
2636 NULL, HFILL }
2638 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable,
2639 { "MPEG4 AAC Scalable", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_scalable",
2640 FT_BOOLEAN, 8, NULL, 0x10,
2641 NULL, HFILL }
2643 { &hf_btavdtp_mpeg24_object_type_rfa,
2644 { "RFA", "btavdtp.codec.mpeg24.object_type.rfa",
2645 FT_UINT8, BASE_HEX, NULL, 0x0F,
2646 NULL, HFILL }
2648 { &hf_btavdtp_mpeg24_sampling_frequency_8000,
2649 { "Sampling Frequency 8000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.8000",
2650 FT_BOOLEAN, 8, NULL, 0x80,
2651 NULL, HFILL }
2653 { &hf_btavdtp_mpeg24_sampling_frequency_11025,
2654 { "Sampling Frequency 11025 Hz", "btavdtp.codec.mpeg24.sampling_frequency.11025",
2655 FT_BOOLEAN, 8, NULL, 0x40,
2656 NULL, HFILL }
2658 { &hf_btavdtp_mpeg24_sampling_frequency_12000,
2659 { "Sampling Frequency 12000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.12000",
2660 FT_BOOLEAN, 8, NULL, 0x20,
2661 NULL, HFILL }
2663 { &hf_btavdtp_mpeg24_sampling_frequency_16000,
2664 { "Sampling Frequency 16000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.16000",
2665 FT_BOOLEAN, 8, NULL, 0x10,
2666 NULL, HFILL }
2668 { &hf_btavdtp_mpeg24_sampling_frequency_22050,
2669 { "Sampling Frequency 22050 Hz", "btavdtp.codec.mpeg24.sampling_frequency.22050",
2670 FT_BOOLEAN, 8, NULL, 0x08,
2671 NULL, HFILL }
2673 { &hf_btavdtp_mpeg24_sampling_frequency_24000,
2674 { "Sampling Frequency 24000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.24000",
2675 FT_BOOLEAN, 8, NULL, 0x04,
2676 NULL, HFILL }
2678 { &hf_btavdtp_mpeg24_sampling_frequency_32000,
2679 { "Sampling Frequency 32000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.32000",
2680 FT_BOOLEAN, 8, NULL, 0x02,
2681 NULL, HFILL }
2683 { &hf_btavdtp_mpeg24_sampling_frequency_44100,
2684 { "Sampling Frequency 44100 Hz", "btavdtp.codec.mpeg24.sampling_frequency.44100",
2685 FT_BOOLEAN, 8, NULL, 0x01,
2686 NULL, HFILL }
2688 { &hf_btavdtp_mpeg24_sampling_frequency_48000,
2689 { "Sampling Frequency 48000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.48000",
2690 FT_BOOLEAN, 8, NULL, 0x80,
2691 NULL, HFILL }
2693 { &hf_btavdtp_mpeg24_sampling_frequency_64000,
2694 { "Sampling Frequency 64000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.64000",
2695 FT_BOOLEAN, 8, NULL, 0x40,
2696 NULL, HFILL }
2698 { &hf_btavdtp_mpeg24_sampling_frequency_88200,
2699 { "Sampling Frequency 88200 Hz", "btavdtp.codec.mpeg24.sampling_frequency.88200",
2700 FT_BOOLEAN, 8, NULL, 0x20,
2701 NULL, HFILL }
2703 { &hf_btavdtp_mpeg24_sampling_frequency_96000,
2704 { "Sampling Frequency 96000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.96000",
2705 FT_BOOLEAN, 8, NULL, 0x10,
2706 NULL, HFILL }
2708 { &hf_btavdtp_mpeg24_channels_1,
2709 { "Channels 1", "btavdtp.codec.mpeg24.channels.1",
2710 FT_BOOLEAN, 8, NULL, 0x08,
2711 NULL, HFILL }
2713 { &hf_btavdtp_mpeg24_channels_2,
2714 { "Channels 2", "btavdtp.codec.mpeg24.channels.2",
2715 FT_BOOLEAN, 8, NULL, 0x04,
2716 NULL, HFILL }
2718 { &hf_btavdtp_mpeg24_rfa,
2719 { "RFA", "btavdtp.codec.mpeg24.rfa",
2720 FT_UINT8, BASE_HEX, NULL, 0x03,
2721 NULL, HFILL }
2723 { &hf_btavdtp_mpeg24_vbr_supported,
2724 { "VBR Supported", "btavdtp.codec.mpeg24.vbr",
2725 FT_BOOLEAN, 24, NULL, 0x800000,
2726 NULL, HFILL }
2728 { &hf_btavdtp_mpeg24_bit_rate,
2729 { "Bit Rate", "btavdtp.codec.mpeg24.bit_rate",
2730 FT_UINT24, BASE_HEX, NULL, 0x7FFFFF,
2731 NULL, HFILL }
2733 { &hf_btavdtp_atrac_version,
2734 { "Version", "btavdtp.codec.atrac.version",
2735 FT_UINT8, BASE_DEC, NULL, 0xE0,
2736 NULL, HFILL }
2738 { &hf_btavdtp_atrac_channel_mode_single_channel,
2739 { "Channel Mode Single Channel", "btavdtp.codec.atrac.channel_mode.single_channel",
2740 FT_BOOLEAN, 8, NULL, 0x10,
2741 NULL, HFILL }
2743 { &hf_btavdtp_atrac_channel_mode_dual_channel,
2744 { "Channel Mode Dual Channel", "btavdtp.codec.atrac.channel_mode.dual_channel",
2745 FT_BOOLEAN, 8, NULL, 0x08,
2746 NULL, HFILL }
2748 { &hf_btavdtp_atrac_channel_mode_joint_stereo,
2749 { "Channel Mode Joint Stereo", "btavdtp.codec.atrac.channel_mode.joint_stereo",
2750 FT_BOOLEAN, 8, NULL, 0x04,
2751 NULL, HFILL }
2753 { &hf_btavdtp_atrac_rfa1,
2754 { "RFA", "btavdtp.codec.atrac.rfa1",
2755 FT_UINT8, BASE_HEX, NULL, 0x03,
2756 NULL, HFILL }
2758 { &hf_btavdtp_atrac_rfa2,
2759 { "RFA", "btavdtp.codec.atrac.rfa2",
2760 FT_UINT24, BASE_HEX, NULL, 0xC00000,
2761 NULL, HFILL }
2763 { &hf_btavdtp_atrac_sampling_frequency_44100,
2764 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2765 FT_BOOLEAN, 24, NULL, 0x200000,
2766 NULL, HFILL }
2768 { &hf_btavdtp_atrac_sampling_frequency_48000,
2769 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2770 FT_BOOLEAN, 24, NULL, 0x100000,
2771 NULL, HFILL }
2773 { &hf_btavdtp_atrac_vbr_supported,
2774 { "VBR Supported", "btavdtp.codec.atrac.vbr",
2775 FT_BOOLEAN, 24, NULL, 0x080000,
2776 NULL, HFILL }
2778 { &hf_btavdtp_atrac_bit_rate,
2779 { "Bit Rate", "btavdtp.codec.atrac.bit_rate",
2780 FT_UINT24, BASE_HEX, NULL, 0x07FFFF,
2781 NULL, HFILL }
2783 { &hf_btavdtp_atrac_maximum_sul,
2784 { "Maximum SUL", "btavdtp.codec.atrac.maximum_sul",
2785 FT_UINT16, BASE_DEC, NULL, 0x0,
2786 "Sound Unit Length (SUL) is one of the parameters that determine bit rate of the audio stream.", HFILL }
2788 { &hf_btavdtp_atrac_rfa3,
2789 { "RFA", "btavdtp.codec.atrac.rfa3",
2790 FT_UINT8, BASE_HEX, NULL, 0x0,
2791 NULL, HFILL }
2793 { &hf_btavdtp_h263_level_10,
2794 { "H264 Level 10", "btavdtp.codec.h264.level.10",
2795 FT_BOOLEAN, 8, NULL, 0x80,
2796 NULL, HFILL }
2798 { &hf_btavdtp_h263_level_20,
2799 { "H264 Level 20", "btavdtp.codec.h264.level.20",
2800 FT_BOOLEAN, 8, NULL, 0x40,
2801 NULL, HFILL }
2803 { &hf_btavdtp_h263_level_30,
2804 { "H264 Level 30", "btavdtp.codec.h264.level.30",
2805 FT_BOOLEAN, 8, NULL, 0x20,
2806 NULL, HFILL }
2808 { &hf_btavdtp_h263_level_rfa,
2809 { "H264 Level RFA", "btavdtp.codec.h264.level.rfa",
2810 FT_UINT8, BASE_HEX, NULL, 0x1F,
2811 NULL, HFILL }
2813 { &hf_btavdtp_mpeg4_level_0,
2814 { "MPEG Level 0", "btavdtp.codec.mpeg4.level.0",
2815 FT_BOOLEAN, 8, NULL, 0x80,
2816 NULL, HFILL }
2818 { &hf_btavdtp_mpeg4_level_1,
2819 { "MPEG Level 1", "btavdtp.codec.mpeg4.level.1",
2820 FT_BOOLEAN, 8, NULL, 0x40,
2821 NULL, HFILL }
2823 { &hf_btavdtp_mpeg4_level_2,
2824 { "MPEG Level 2", "btavdtp.codec.mpeg4.level.2",
2825 FT_BOOLEAN, 8, NULL, 0x20,
2826 NULL, HFILL }
2828 { &hf_btavdtp_mpeg4_level_3,
2829 { "MPEG4 Level 3", "btavdtp.codec.mpeg4.level.3",
2830 FT_BOOLEAN, 8, NULL, 0x10,
2831 NULL, HFILL }
2833 { &hf_btavdtp_mpeg4_level_rfa,
2834 { "MPEG4 Level RFA", "btavdtp.codec.mpeg4.level.rfa",
2835 FT_UINT8, BASE_HEX, NULL, 0x0F,
2836 NULL, HFILL }
2838 { &hf_btavdtp_vendor_id,
2839 { "Vendor ID", "btavdtp.codec.vendor.vendor_id",
2840 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
2841 NULL, HFILL }
2843 { &hf_btavdtp_vendor_specific_codec_id,
2844 { "Codec", "btavdtp.codec.vendor.codec_id",
2845 FT_UINT16, BASE_HEX, NULL, 0x0,
2846 NULL, HFILL }
2848 { &hf_btavdtp_vendor_specific_value,
2849 { "Value", "btavdtp.codec.vendor.value",
2850 FT_BYTES, BASE_NONE, NULL, 0x0,
2851 NULL, HFILL }
2853 { &hf_btavdtp_vendor_apt_codec_id,
2854 { "Codec", "btavdtp.codec.vendor.codec_id",
2855 FT_UINT16, BASE_HEX, VALS(vendor_apt_codec_vals), 0x0,
2856 NULL, HFILL }
2858 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000,
2859 { "Sampling Frequency 16000 Hz", "btavdtp.codec.aptx.sampling_frequency.16000",
2860 FT_BOOLEAN, 8, NULL, 0x80,
2861 NULL, HFILL }
2863 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000,
2864 { "Sampling Frequency 32000 Hz", "btavdtp.codec.aptx.sampling_frequency.32000",
2865 FT_BOOLEAN, 8, NULL, 0x40,
2866 NULL, HFILL }
2868 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100,
2869 { "Sampling Frequency 44100 Hz", "btavdtp.codec.aptx.sampling_frequency.44100",
2870 FT_BOOLEAN, 8, NULL, 0x20,
2871 NULL, HFILL }
2873 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000,
2874 { "Sampling Frequency 48000 Hz", "btavdtp.codec.aptx.sampling_frequency.48000",
2875 FT_BOOLEAN, 8, NULL, 0x10,
2876 NULL, HFILL }
2878 { &hf_btavdtp_vendor_specific_aptx_channel_mode_mono,
2879 { "Channel Mode Mono", "btavdtp.codec.aptx.channel_mode.mono",
2880 FT_BOOLEAN, 8, NULL, 0x08,
2881 NULL, HFILL }
2883 { &hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel,
2884 { "Channel Mode Dual Channel", "btavdtp.codec.aptx.channel_mode.dual_channel",
2885 FT_BOOLEAN, 8, NULL, 0x04,
2886 NULL, HFILL }
2888 { &hf_btavdtp_vendor_specific_aptx_channel_mode_stereo,
2889 { "Channel Mode Stereo", "btavdtp.codec.aptx.channel_mode.stereo",
2890 FT_BOOLEAN, 8, NULL, 0x02,
2891 NULL, HFILL }
2893 { &hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo,
2894 { "Channel Mode Joint Stereo", "btavdtp.codec.aptx.channel_mode.joint_stereo",
2895 FT_BOOLEAN, 8, NULL, 0x01,
2896 NULL, HFILL }
2898 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000,
2899 { "Sampling Frequency 16000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.16000",
2900 FT_BOOLEAN, 8, NULL, 0x80,
2901 NULL, HFILL }
2903 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000,
2904 { "Sampling Frequency 32000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.32000",
2905 FT_BOOLEAN, 8, NULL, 0x40,
2906 NULL, HFILL }
2908 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100,
2909 { "Sampling Frequency 44100 Hz", "btavdtp.codec.aptxhd.sampling_frequency.44100",
2910 FT_BOOLEAN, 8, NULL, 0x20,
2911 NULL, HFILL }
2913 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000,
2914 { "Sampling Frequency 48000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.48000",
2915 FT_BOOLEAN, 8, NULL, 0x10,
2916 NULL, HFILL }
2918 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono,
2919 { "Channel Mode Mono", "btavdtp.codec.aptxhd.channel_mode.mono",
2920 FT_BOOLEAN, 8, NULL, 0x08,
2921 NULL, HFILL }
2923 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel,
2924 { "Channel Mode Dual Channel", "btavdtp.codec.aptxhd.channel_mode.dual_channel",
2925 FT_BOOLEAN, 8, NULL, 0x04,
2926 NULL, HFILL }
2928 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo,
2929 { "Channel Mode Stereo", "btavdtp.codec.aptxhd.channel_mode.stereo",
2930 FT_BOOLEAN, 8, NULL, 0x02,
2931 NULL, HFILL }
2933 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo,
2934 { "Channel Mode Joint Stereo", "btavdtp.codec.aptxhd.channel_mode.joint_stereo",
2935 FT_BOOLEAN, 8, NULL, 0x01,
2936 NULL, HFILL }
2938 { &hf_btavdtp_vendor_specific_aptxhd_rfa,
2939 { "RFA", "btavdtp.codec.aptxhd.rfa",
2940 FT_UINT32, BASE_HEX, NULL, 0x0,
2941 NULL, HFILL }
2943 { &hf_btavdtp_vendor_sony_codec_id,
2944 { "Codec", "btavdtp.codec.vendor.codec_id",
2945 FT_UINT16, BASE_HEX, VALS(vendor_sony_codec_vals), 0x00,
2946 NULL, HFILL }
2948 { &hf_btavdtp_vendor_specific_ldac_rfa1,
2949 { "RFA1", "btavdtp.codec.ldac.rfa1",
2950 FT_UINT8, BASE_HEX, NULL, 0xC0,
2951 NULL, HFILL }
2953 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_44100,
2954 { "Sampling Frequency 44100 Hz", "btavdtp.codec.ldac.sampling_frequency.44100",
2955 FT_BOOLEAN, 8, NULL, 0x20,
2956 NULL, HFILL }
2958 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_48000,
2959 { "Sampling Frequency 48000 Hz", "btavdtp.codec.ldac.sampling_frequency.48000",
2960 FT_BOOLEAN, 8, NULL, 0x10,
2961 NULL, HFILL }
2963 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_88200,
2964 { "Sampling Frequency 88200 Hz", "btavdtp.codec.ldac.sampling_frequency.88200",
2965 FT_BOOLEAN, 8, NULL, 0x08,
2966 NULL, HFILL }
2968 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_96000,
2969 { "Sampling Frequency 96000 Hz", "btavdtp.codec.ldac.sampling_frequency.96000",
2970 FT_BOOLEAN, 8, NULL, 0x04,
2971 NULL, HFILL }
2973 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_176400,
2974 { "Sampling Frequency 176400 Hz", "btavdtp.codec.ldac.sampling_frequency.176400",
2975 FT_BOOLEAN, 8, NULL, 0x02,
2976 NULL, HFILL }
2978 { &hf_btavdtp_vendor_specific_ldac_sampling_frequency_192000,
2979 { "Sampling Frequency 192000 Hz", "btavdtp.codec.ldac.sampling_frequency.192000",
2980 FT_BOOLEAN, 8, NULL, 0x01,
2981 NULL, HFILL }
2983 { &hf_btavdtp_vendor_specific_ldac_rfa2,
2984 { "RFA2", "btavdtp.codec.ldac.rfa2",
2985 FT_UINT8, BASE_HEX, NULL, 0xF8,
2986 NULL, HFILL }
2988 { &hf_btavdtp_vendor_specific_ldac_channel_mode_mono,
2989 { "Channel Mode Mono", "btavdtp.codec.ldac.channel_mode.mono",
2990 FT_BOOLEAN, 8, NULL, 0x04,
2991 NULL, HFILL }
2993 { &hf_btavdtp_vendor_specific_ldac_channel_mode_dual_channel,
2994 { "Channel Mode Dual Channel", "btavdtp.codec.ldac.channel_mode.dual_channel",
2995 FT_BOOLEAN, 8, NULL, 0x02,
2996 NULL, HFILL }
2998 { &hf_btavdtp_vendor_specific_ldac_channel_mode_stereo,
2999 { "Channel Mode Stereo", "btavdtp.codec.ldac.channel_mode.stereo",
3000 FT_BOOLEAN, 8, NULL, 0x01,
3001 NULL, HFILL }
3003 { &hf_btavdtp_vendor_google_codec_id,
3004 { "Codec", "btavdtp.codec.vendor.codec_id",
3005 FT_UINT16, BASE_HEX, VALS(vendor_google_codec_vals), 0x00,
3006 NULL, HFILL }
3008 { &hf_btavdtp_vendor_specific_opus_sampling_frequency_48000,
3009 { "Sampling Frequency 48000 Hz", "btavdtp.codec.opus.sampling_frequency.48000",
3010 FT_BOOLEAN, 8, NULL, 0x80,
3011 NULL, HFILL }
3013 { &hf_btavdtp_vendor_specific_opus_rfa,
3014 { "RFA", "btavdtp.codec.opus.rfa1",
3015 FT_UINT8, BASE_HEX, NULL, 0x60,
3016 NULL, HFILL }
3018 { &hf_btavdtp_vendor_specific_opus_frame_duration_20,
3019 { "Frame Duration 20 ms", "btavdtp.codec.opus.frame_duration.20",
3020 FT_BOOLEAN, 8, NULL, 0x10,
3021 NULL, HFILL }
3023 { &hf_btavdtp_vendor_specific_opus_frame_duration_10,
3024 { "Frame Duration 10 ms", "btavdtp.codec.opus.frame_duration.10",
3025 FT_BOOLEAN, 8, NULL, 0x08,
3026 NULL, HFILL }
3028 { &hf_btavdtp_vendor_specific_opus_channel_mode_dual,
3029 { "Channel Mode Dual", "btavdtp.codec.opus.channel_mode.dual",
3030 FT_BOOLEAN, 8, NULL, 0x04,
3031 NULL, HFILL }
3033 { &hf_btavdtp_vendor_specific_opus_channel_mode_stereo,
3034 { "Channel Mode Stereo", "btavdtp.codec.opus.channel_mode.stereo",
3035 FT_BOOLEAN, 8, NULL, 0x02,
3036 NULL, HFILL }
3038 { &hf_btavdtp_vendor_specific_opus_channel_mode_mono,
3039 { "Channel Mode Mono", "btavdtp.codec.opus.channel_mode.mono",
3040 FT_BOOLEAN, 8, NULL, 0x01,
3041 NULL, HFILL }
3043 { &hf_btavdtp_capabilities,
3044 { "Capabilities", "btavdtp.capabilities",
3045 FT_NONE, BASE_NONE, NULL, 0x0,
3046 NULL, HFILL }
3048 { &hf_btavdtp_service,
3049 { "Service", "btavdtp.service",
3050 FT_NONE, BASE_NONE, NULL, 0x0,
3051 NULL, HFILL }
3053 { &hf_btavdtp_service_multiplexing_entry,
3054 { "Entry", "btavdtp.service_multiplexing_entry",
3055 FT_NONE, BASE_NONE, NULL, 0x0,
3056 NULL, HFILL }
3058 { &hf_btavdtp_data,
3059 { "Data", "btavdtp.data",
3060 FT_NONE, BASE_NONE, NULL, 0x0,
3061 NULL, HFILL }
3065 static int *ett[] = {
3066 &ett_btavdtp,
3067 &ett_btavdtp_sep,
3068 &ett_btavdtp_capabilities,
3069 &ett_btavdtp_service,
3072 proto_btavdtp = proto_register_protocol("Bluetooth AVDTP Protocol", "BT AVDTP", "btavdtp");
3073 btavdtp_handle = register_dissector("btavdtp", dissect_btavdtp, proto_btavdtp);
3075 proto_register_field_array(proto_btavdtp, hf, array_length(hf));
3076 proto_register_subtree_array(ett, array_length(ett));
3078 module = prefs_register_protocol_subtree("Bluetooth", proto_btavdtp, NULL);
3079 prefs_register_static_text_preference(module, "avdtp.version",
3080 "Bluetooth Protocol AVDTP version: 1.3",
3081 "Version of protocol supported by this dissector.");
3083 channels = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3084 sep_list = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3085 sep_open = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3086 media_packet_times = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3087 #if RTP_PLAYER_WORKAROUND == true
3088 file_scope_stream_number = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3089 #endif
3092 void
3093 proto_reg_handoff_btavdtp(void)
3095 dissector_add_string("bluetooth.uuid", "19", btavdtp_handle);
3097 dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_AVDTP, btavdtp_handle);
3099 dissector_add_for_decode_as("btl2cap.cid", btavdtp_handle);
3103 static int
3104 dissect_aptx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3106 proto_item *aptx_item;
3107 proto_tree *aptx_tree;
3108 proto_item *pitem;
3109 bta2dp_codec_info_t *info;
3110 double cumulative_frame_duration = 0;
3112 info = (bta2dp_codec_info_t *) data;
3114 col_set_str(pinfo->cinfo, COL_PROTOCOL, "aptX");
3116 switch (pinfo->p2p_dir) {
3118 case P2P_DIR_SENT:
3119 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3120 break;
3122 case P2P_DIR_RECV:
3123 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3124 break;
3126 case P2P_DIR_UNKNOWN:
3127 col_clear(pinfo->cinfo, COL_INFO);
3128 break;
3130 default:
3131 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3132 pinfo->p2p_dir);
3133 break;
3136 col_append_str(pinfo->cinfo, COL_INFO, "aptX");
3138 aptx_item = proto_tree_add_item(tree, proto_aptx, tvb, 0, -1, ENC_NA);
3139 aptx_tree = proto_item_add_subtree(aptx_item, ett_aptx);
3141 proto_tree_add_item(aptx_tree, hf_aptx_data, tvb, 0, -1, ENC_NA);
3143 if (info && info->configuration && info->configuration_length >= 9) {
3144 bool fail = false;
3145 double expected_speed_data;
3146 double frame_duration;
3147 double frame_length = 2 * 2 * 4;
3148 int number_of_channels;
3149 int frequency;
3150 int sample_bits;
3152 switch (info->configuration[8] >> 4) {
3153 case 0x01:
3154 frequency = 48000;
3155 break;
3156 case 0x02:
3157 frequency = 44100;
3158 break;
3159 case 0x04:
3160 frequency = 32000;
3161 break;
3162 case 0x08:
3163 frequency = 16000;
3164 break;
3165 default:
3166 fail = true;
3169 if (fail)
3170 return tvb_reported_length(tvb);
3172 switch (info->configuration[8] & 0x0F) {
3173 case 0x01:
3174 case 0x02:
3175 case 0x04:
3176 number_of_channels = 2;
3177 break;
3178 case 0x08:
3179 number_of_channels = 1;
3180 break;
3181 default:
3182 fail = true;
3185 if (fail)
3186 return tvb_reported_length(tvb);
3188 sample_bits = 16;
3190 expected_speed_data = frequency * (sample_bits / 8.0) * number_of_channels;
3191 frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0);
3193 cumulative_frame_duration = (tvb_reported_length(tvb) / 4.0) * frame_duration;
3195 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_frame_duration, tvb, 0, 0, cumulative_frame_duration);
3196 proto_item_set_generated(pitem);
3198 if (info && info->previous_media_packet_info && info->current_media_packet_info) {
3199 nstime_t delta;
3201 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->abs_ts);
3202 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time, tvb, 0, 0, nstime_to_msec(&delta));
3203 proto_item_set_generated(pitem);
3205 pitem = proto_tree_add_double(aptx_tree, hf_aptx_avrcp_song_position, tvb, 0, 0, info->previous_media_packet_info->avrcp_song_position);
3206 proto_item_set_generated(pitem);
3208 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->first_abs_ts);
3209 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time_from_the_beginning, tvb, 0, 0, nstime_to_msec(&delta));
3210 proto_item_set_generated(pitem);
3212 if (!pinfo->fd->visited)
3213 info->current_media_packet_info->cumulative_frame_duration += cumulative_frame_duration;
3215 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_duration, tvb, 0, 0, info->previous_media_packet_info->cumulative_frame_duration);
3216 proto_item_set_generated(pitem);
3218 pitem = proto_tree_add_double(aptx_tree, hf_aptx_diff, tvb, 0, 0, info->previous_media_packet_info->cumulative_frame_duration - nstime_to_msec(&delta));
3219 proto_item_set_generated(pitem);
3223 return tvb_reported_length(tvb);
3226 void
3227 proto_register_aptx(void)
3229 static hf_register_info hf[] = {
3230 { &hf_aptx_data,
3231 { "Data", "aptx.data",
3232 FT_BYTES, BASE_NONE, NULL, 0x00,
3233 NULL, HFILL }
3235 { &hf_aptx_cumulative_frame_duration,
3236 { "Cumulative Frame Duration", "aptx.cumulative_frame_duration",
3237 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3238 NULL, HFILL }
3240 { &hf_aptx_delta_time,
3241 { "Delta time", "aptx.delta_time",
3242 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3243 NULL, HFILL }
3245 { &hf_aptx_avrcp_song_position,
3246 { "AVRCP Song Position", "aptx.avrcp_song_position",
3247 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3248 NULL, HFILL }
3250 { &hf_aptx_delta_time_from_the_beginning,
3251 { "Delta time from the beginning", "aptx.delta_time_from_the_beginning",
3252 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3253 NULL, HFILL }
3255 { &hf_aptx_cumulative_duration,
3256 { "Cumulative Music Duration", "aptx.cumulative_music_duration",
3257 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3258 NULL, HFILL }
3260 { &hf_aptx_diff,
3261 { "Diff", "aptx.diff",
3262 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x00,
3263 NULL, HFILL }
3267 static int *ett[] = {
3268 &ett_aptx
3271 proto_aptx = proto_register_protocol("aptX Codec", "aptX", "aptx");
3272 proto_register_field_array(proto_aptx, hf, array_length(hf));
3273 proto_register_subtree_array(ett, array_length(ett));
3275 aptx_handle = register_dissector("aptx", dissect_aptx, proto_aptx);
3278 static int
3279 dissect_ldac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3281 proto_item *ti;
3282 proto_tree *ldac_tree;
3283 proto_item *pitem;
3284 proto_tree *rtree;
3285 int offset = 0;
3286 uint8_t number_of_frames;
3287 uint8_t syncword;
3288 uint8_t byte;
3289 uint8_t cci;
3290 unsigned frequency;
3291 int available;
3292 int ldac_channels;
3293 int counter = 1;
3294 int frame_length;
3295 int frame_sample_size;
3296 int expected_speed_data;
3298 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDAC");
3300 ti = proto_tree_add_item(tree, proto_ldac, tvb, offset, -1, ENC_NA);
3301 ldac_tree = proto_item_add_subtree(ti, ett_ldac);
3303 proto_tree_add_item(ldac_tree, hf_ldac_fragmented, tvb, offset, 1, ENC_BIG_ENDIAN);
3304 proto_tree_add_item(ldac_tree, hf_ldac_starting_packet, tvb, offset, 1, ENC_BIG_ENDIAN);
3305 proto_tree_add_item(ldac_tree, hf_ldac_last_packet, tvb, offset, 1, ENC_BIG_ENDIAN);
3306 proto_tree_add_item(ldac_tree, hf_ldac_rfa, tvb, offset, 1, ENC_BIG_ENDIAN);
3307 proto_tree_add_item(ldac_tree, hf_ldac_number_of_frames, tvb, offset, 1, ENC_BIG_ENDIAN);
3308 number_of_frames = tvb_get_uint8(tvb, offset) & 0x0F;
3309 offset += 1;
3311 while (tvb_reported_length_remaining(tvb, offset) > 0) {
3312 available = tvb_reported_length_remaining(tvb, offset);
3314 syncword = tvb_get_uint8(tvb, offset);
3315 if (syncword != 0xAA) {
3316 rtree = proto_tree_add_subtree_format(ldac_tree, tvb, offset, 1,
3317 ett_ldac_list, NULL, "Frame: %3u/%3u", counter, number_of_frames);
3318 pitem = proto_tree_add_item(rtree, hf_ldac_syncword, tvb, offset, 1, ENC_BIG_ENDIAN);
3319 offset += 1;
3320 expert_add_info(pinfo, pitem, &ei_ldac_syncword);
3321 break;
3324 if (available > 1) {
3325 byte = tvb_get_uint8(tvb, offset + 1);
3326 frequency = (byte & 0xE0) >> 5;
3327 cci = (byte & 0x18)>> 3;
3328 frame_length = byte & 0x07;
3329 frame_length <<= 6;
3330 } else {
3331 frequency = 0;
3332 cci = 0;
3335 if (available > 2) {
3336 byte = tvb_get_uint8(tvb, offset + 2);
3337 frame_length |= (byte & 0xFC) >> 2;
3338 frame_length +=1;
3339 } else {
3340 frame_length = 0;
3343 rtree = proto_tree_add_subtree_format(ldac_tree, tvb, offset,
3344 3 + frame_length > available ? available : 3 + frame_length,
3345 ett_ldac_list, NULL, "Frame: %3u/%3u", counter, number_of_frames);
3347 if (3 + frame_length > available) {
3348 expert_add_info(pinfo, rtree, &ei_ldac_truncated_or_bad_length);
3351 proto_tree_add_item(rtree, hf_ldac_syncword, tvb, offset, 1, ENC_BIG_ENDIAN);
3352 offset += 1;
3354 if (cci == LDAC_CCI_MONO)
3355 ldac_channels = 1;
3356 else
3357 ldac_channels = 2;
3359 switch (frequency) {
3360 case LDAC_FSID_044:
3361 frequency = 44100;
3362 frame_sample_size = 128;
3363 break;
3364 case LDAC_FSID_048:
3365 frequency = 48000;
3366 frame_sample_size = 128;
3367 break;
3368 case LDAC_FSID_088:
3369 frequency = 88200;
3370 frame_sample_size = 256;
3371 break;
3372 case LDAC_FSID_096:
3373 frequency = 96000;
3374 frame_sample_size = 256;
3375 break;
3376 case LDAC_FSID_176:
3377 frequency = 176400;
3378 frame_sample_size = 512;
3379 break;
3380 case LDAC_FSID_192:
3381 frequency = 192000;
3382 frame_sample_size = 512;
3383 break;
3384 default:
3385 frequency = 0;
3386 frame_sample_size = 1;
3389 proto_tree_add_item(rtree, hf_ldac_sampling_frequency, tvb, offset, 1, ENC_BIG_ENDIAN);
3390 pitem = proto_tree_add_item(rtree, hf_ldac_channel_config_index, tvb, offset, 1, ENC_BIG_ENDIAN);
3391 proto_item_append_text(pitem, ", Number of channels : %d", ldac_channels);
3392 proto_tree_add_item(rtree, hf_ldac_frame_length_h, tvb, offset, 1, ENC_BIG_ENDIAN);
3393 offset += 1;
3394 proto_tree_add_item(rtree, hf_ldac_frame_length_l, tvb, offset, 1, ENC_BIG_ENDIAN);
3395 proto_tree_add_item(rtree, hf_ldac_frame_status, tvb, offset, 1, ENC_BIG_ENDIAN);
3396 offset += 1;
3398 proto_tree_add_item(rtree, hf_ldac_data, tvb, offset, frame_length, ENC_NA);
3399 offset += frame_length;
3401 expected_speed_data = (8*(frame_length+3) * frequency) / (frame_sample_size*1000);
3402 pitem = proto_tree_add_uint(rtree, hf_ldac_expected_data_speed, tvb, offset, 0, expected_speed_data);
3403 proto_item_append_text(pitem, " kbits/sec");
3404 proto_item_set_generated(pitem);
3405 counter += 1;
3408 col_append_fstr(pinfo->cinfo, COL_INFO, " Frames=%u", number_of_frames);
3410 return offset;
3412 void
3413 proto_register_ldac(void)
3415 expert_module_t* expert_ldac;
3417 static hf_register_info hf[] = {
3418 { &hf_ldac_fragmented,
3419 { "Fragmented", "ldac.fragmented",
3420 FT_BOOLEAN, 8, NULL, 0x80,
3421 NULL, HFILL }
3423 { &hf_ldac_starting_packet,
3424 { "Starting Packet", "ldac.starting_packet",
3425 FT_BOOLEAN, 8, NULL, 0x40,
3426 NULL, HFILL }
3428 { &hf_ldac_last_packet,
3429 { "Last Packet", "ldac.last_packet",
3430 FT_BOOLEAN, 8, NULL, 0x20,
3431 NULL, HFILL }
3433 { &hf_ldac_rfa,
3434 { "RFA", "ldac.rfa",
3435 FT_BOOLEAN, 8, NULL, 0x10,
3436 NULL, HFILL }
3438 { &hf_ldac_number_of_frames,
3439 { "Number of Frames", "ldac.number_of_frames",
3440 FT_UINT8, BASE_DEC, NULL, 0x0F,
3441 NULL, HFILL }
3443 { &hf_ldac_syncword,
3444 { "Sync Word", "ldac.syncword",
3445 FT_UINT8, BASE_HEX, NULL, 0x00,
3446 NULL, HFILL }
3448 { &hf_ldac_sampling_frequency,
3449 { "Sampling Frequency", "ldac.sampling_frequency",
3450 FT_UINT8, BASE_HEX, VALS(ldac_sampling_frequency_vals), 0xE0,
3451 NULL, HFILL }
3453 { &hf_ldac_channel_config_index,
3454 { "Channel Config Index", "ldac.channel_config_index",
3455 FT_UINT8, BASE_HEX, VALS(ldac_channel_config_index_vals), 0x18,
3456 NULL, HFILL }
3458 { &hf_ldac_frame_length_h,
3459 { "Frame Length Index(H)", "ldac.frame_length_index_H",
3460 FT_UINT8, BASE_HEX, NULL, 0x07,
3461 NULL, HFILL }
3463 { &hf_ldac_frame_length_l,
3464 { "Frame Length Index(L)", "ldac.frame_length_index_L",
3465 FT_UINT8, BASE_HEX, NULL, 0xFC,
3466 NULL, HFILL }
3468 { &hf_ldac_frame_status,
3469 { "Frame Status", "ldac.frame_status",
3470 FT_UINT8, BASE_DEC, NULL, 0x03,
3471 NULL, HFILL }
3473 { &hf_ldac_expected_data_speed,
3474 { "Bitrate", "ldac.expected_speed_data",
3475 FT_UINT32, BASE_DEC, NULL, 0x00,
3476 NULL, HFILL }
3478 { &hf_ldac_data,
3479 { "Frame Data", "ldac.data",
3480 FT_NONE, BASE_NONE, NULL, 0x00,
3481 NULL, HFILL }
3485 static int *ett[] = {
3486 &ett_ldac,
3487 &ett_ldac_list,
3490 static ei_register_info ei[] = {
3491 { &ei_ldac_syncword, { "ldac.syncword.unexpected", PI_PROTOCOL, PI_WARN, "Unexpected syncword", EXPFILL }},
3492 { &ei_ldac_truncated_or_bad_length, { "ldac.data.truncated", PI_PROTOCOL, PI_WARN, "Either bad frame length or data truncated", EXPFILL }},
3495 proto_ldac = proto_register_protocol("LDAC Codec", "LDAC", "ldac");
3497 proto_register_field_array(proto_ldac, hf, array_length(hf));
3498 proto_register_subtree_array(ett, array_length(ett));
3499 expert_ldac = expert_register_protocol(proto_ldac);
3500 expert_register_field_array(expert_ldac, ei, array_length(ei));
3502 ldac_handle = register_dissector("ldac", dissect_ldac, proto_ldac);
3506 static int
3507 dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3509 proto_item *ti;
3510 proto_tree *bta2dp_tree;
3511 proto_item *pitem;
3512 int offset = 0;
3513 dissector_handle_t codec_dissector = NULL;
3514 bta2dp_codec_info_t bta2dp_codec_info;
3515 sep_data_t sep_data;
3516 bool no_avdtp_session;
3518 no_avdtp_session = (proto_btavdtp != (int) GPOINTER_TO_UINT(wmem_list_frame_data(
3519 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3521 sep_data.codec = CODEC_SBC;
3522 sep_data.content_protection_type = 0;
3523 sep_data.acp_seid = 0;
3524 sep_data.int_seid = 0;
3525 sep_data.previous_media_packet_info = NULL;
3526 sep_data.current_media_packet_info = NULL;
3527 sep_data.stream_start_in_frame = 0;
3528 sep_data.stream_end_in_frame = 0;
3529 sep_data.stream_number = 1;
3530 sep_data.vendor_id = 0;
3531 sep_data.vendor_codec = 0;
3532 sep_data.configuration_length = 0;
3533 sep_data.configuration = NULL;
3535 if (force_a2dp_scms_t || force_a2dp_codec != CODEC_DEFAULT) {
3536 if (force_a2dp_scms_t)
3537 sep_data.content_protection_type = 2;
3538 else if (data && !no_avdtp_session)
3539 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
3541 if (force_a2dp_codec != CODEC_DEFAULT)
3542 sep_data.codec = force_a2dp_codec;
3543 else if (data && !no_avdtp_session)
3544 sep_data.codec = ((sep_data_t *) data)->codec;
3545 } else {
3546 if (data && !no_avdtp_session)
3547 sep_data = *((sep_data_t *) data);
3550 col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP");
3552 switch (pinfo->p2p_dir) {
3554 case P2P_DIR_SENT:
3555 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3556 break;
3558 case P2P_DIR_RECV:
3559 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3560 break;
3562 case P2P_DIR_UNKNOWN:
3563 col_clear(pinfo->cinfo, COL_INFO);
3564 break;
3566 default:
3567 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3568 pinfo->p2p_dir);
3569 break;
3572 ti = proto_tree_add_item(tree, proto_bta2dp, tvb, offset, -1, ENC_NA);
3573 col_append_fstr(pinfo->cinfo, COL_INFO, "Audio stream - %s",
3574 val_to_str_const(sep_data.codec, media_codec_audio_type_vals, "unknown codec"));
3576 bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp);
3578 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3579 proto_item_set_generated(pitem);
3581 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_int_seid, tvb, 0, 0, sep_data.int_seid);
3582 proto_item_set_generated(pitem);
3584 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, 0, 0, sep_data.codec);
3585 proto_item_set_generated(pitem);
3587 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3588 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3589 proto_item_set_generated(pitem);
3591 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3592 proto_item_set_generated(pitem);
3594 if ((sep_data.vendor_id == 0x004F && sep_data.vendor_codec == VENDOR_APT_CODEC_ID_APT_X) ||
3595 (sep_data.vendor_id == 0x00D7 && sep_data.vendor_codec == VENDOR_APT_CODEC_ID_APT_X_HD))
3596 codec_dissector = aptx_handle;
3598 if (sep_data.vendor_id == 0x012D && sep_data.vendor_codec == VENDOR_SONY_CODEC_ID_LDAC)
3599 codec_dissector = ldac_handle;
3602 if (sep_data.content_protection_type > 0) {
3603 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3604 proto_item_set_generated(pitem);
3607 if (sep_data.stream_start_in_frame > 0) {
3608 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3609 proto_item_set_generated(pitem);
3612 if (sep_data.stream_end_in_frame > 0) {
3613 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3614 proto_item_set_generated(pitem);
3617 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_number, tvb, 0, 0, sep_data.stream_number);
3618 proto_item_set_generated(pitem);
3620 switch (sep_data.codec) {
3621 case CODEC_SBC:
3622 codec_dissector = sbc_handle;
3623 break;
3624 case CODEC_MPEG12_AUDIO:
3625 codec_dissector = mp2t_handle;
3626 break;
3627 case CODEC_MPEG24_AAC:
3628 codec_dissector = mpeg_audio_handle;
3629 break;
3630 case CODEC_ATRAC:
3631 codec_dissector = atrac_handle;
3632 break;
3633 case CODEC_APT_X:
3634 case CODEC_APT_X_HD:
3635 codec_dissector = aptx_handle;
3636 break;
3637 case CODEC_LDAC:
3638 codec_dissector = ldac_handle;
3639 break;
3642 bta2dp_codec_info.codec_dissector = codec_dissector;
3643 bta2dp_codec_info.configuration_length = sep_data.configuration_length;
3644 bta2dp_codec_info.configuration = sep_data.configuration;
3645 bta2dp_codec_info.content_protection_type = sep_data.content_protection_type;
3646 bta2dp_codec_info.previous_media_packet_info = sep_data.previous_media_packet_info;
3647 bta2dp_codec_info.current_media_packet_info = sep_data.current_media_packet_info;
3649 #if RTP_PLAYER_WORKAROUND == true
3650 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3651 weak to recognize Bluetooth streams (key is: uint32_t interface_id, uint32_t adapter_id, uint32_t chandle, uint32_t cid, uint32_t direction -> uint32_t stream_number) */
3652 pinfo->srcport = sep_data.stream_number;
3653 pinfo->destport = sep_data.stream_number;
3654 #endif
3656 if (bta2dp_codec_info.content_protection_type == 0 && codec_dissector == aptx_handle) {
3657 call_dissector_with_data(aptx_handle, tvb, pinfo, tree, &bta2dp_codec_info);
3658 } else {
3659 bluetooth_add_address(pinfo, &pinfo->net_dst, sep_data.stream_number, "BT A2DP", pinfo->num, RTP_MEDIA_AUDIO, &bta2dp_codec_info);
3660 call_dissector(rtp_handle, tvb, pinfo, tree);
3662 offset += tvb_reported_length_remaining(tvb, offset);
3664 return offset;
3667 void
3668 proto_register_bta2dp(void)
3670 module_t *module;
3672 static hf_register_info hf[] = {
3673 { &hf_bta2dp_acp_seid,
3674 { "ACP SEID", "bta2dp.acp_seid",
3675 FT_UINT8, BASE_DEC, NULL, 0x00,
3676 NULL, HFILL }
3678 { &hf_bta2dp_int_seid,
3679 { "INT SEID", "bta2dp.int_seid",
3680 FT_UINT8, BASE_DEC, NULL, 0x00,
3681 NULL, HFILL }
3683 { &hf_bta2dp_codec,
3684 { "Codec", "bta2dp.codec",
3685 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
3686 NULL, HFILL }
3688 { &hf_bta2dp_vendor_id,
3689 { "Vendor ID", "bta2dp.codec.vendor.vendor_id",
3690 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3691 NULL, HFILL }
3693 { &hf_bta2dp_vendor_codec_id,
3694 { "Vendor Codec", "bta2dp.codec.vendor.codec_id",
3695 FT_UINT16, BASE_HEX, NULL, 0x00,
3696 NULL, HFILL }
3698 { &hf_bta2dp_content_protection,
3699 { "Content Protection", "bta2dp.content_protection",
3700 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0,
3701 NULL, HFILL }
3703 { &hf_bta2dp_stream_start_in_frame,
3704 { "Stream Start in Frame", "bta2dp.stream_start_in_frame",
3705 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3706 NULL, HFILL }
3708 { &hf_bta2dp_stream_end_in_frame,
3709 { "Stream End in Frame", "bta2dp.stream_end_in_frame",
3710 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3711 NULL, HFILL }
3713 { &hf_bta2dp_stream_number,
3714 { "Stream Number", "bta2dp.stream_number",
3715 FT_UINT32, BASE_DEC, NULL, 0x00,
3716 NULL, HFILL }
3720 static int *ett[] = {
3721 &ett_bta2dp
3724 proto_bta2dp = proto_register_protocol("Bluetooth A2DP Profile", "BT A2DP", "bta2dp");
3725 proto_register_field_array(proto_bta2dp, hf, array_length(hf));
3726 proto_register_subtree_array(ett, array_length(ett));
3728 bta2dp_handle = register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp);
3730 module = prefs_register_protocol_subtree("Bluetooth", proto_bta2dp, NULL);
3731 prefs_register_static_text_preference(module, "a2dp.version",
3732 "Bluetooth Profile A2DP version: 1.3",
3733 "Version of profile supported by this dissector.");
3735 prefs_register_bool_preference(module, "a2dp.content_protection.scms_t",
3736 "Force SCMS-T decoding",
3737 "Force decoding stream as A2DP with Content Protection SCMS-T ",
3738 &force_a2dp_scms_t);
3740 prefs_register_enum_preference(module, "a2dp.codec",
3741 "Force codec",
3742 "Force decoding stream as A2DP with specified codec",
3743 &force_a2dp_codec, pref_a2dp_codec, false);
3746 void
3747 proto_reg_handoff_bta2dp(void)
3749 sbc_handle = find_dissector_add_dependency("sbc", proto_bta2dp);
3750 mp2t_handle = find_dissector_add_dependency("mp2t", proto_bta2dp);
3751 mpeg_audio_handle = find_dissector_add_dependency("mpeg-audio", proto_bta2dp);
3752 /* TODO: ATRAC dissector does not exist yet */
3753 atrac_handle = find_dissector_add_dependency("atrac", proto_bta2dp);
3755 rtp_handle = find_dissector_add_dependency("rtp", proto_bta2dp);
3757 dissector_add_string("bluetooth.uuid", "110a", bta2dp_handle);
3758 dissector_add_string("bluetooth.uuid", "110b", bta2dp_handle);
3759 dissector_add_string("bluetooth.uuid", "110d", bta2dp_handle);
3761 dissector_add_for_decode_as("btl2cap.cid", bta2dp_handle);
3764 static int
3765 dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3767 proto_item *ti;
3768 proto_tree *btvdp_tree;
3769 proto_item *pitem;
3770 int offset = 0;
3771 dissector_handle_t codec_dissector = NULL;
3772 btvdp_codec_info_t btvdp_codec_info;
3773 sep_data_t sep_data;
3774 bool no_avdtp_session;
3776 no_avdtp_session = (proto_btavdtp != (int) GPOINTER_TO_UINT(wmem_list_frame_data(
3777 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3779 sep_data.codec = CODEC_H263_BASELINE;
3780 sep_data.content_protection_type = 0;
3781 sep_data.acp_seid = 0;
3782 sep_data.int_seid = 0;
3783 sep_data.previous_media_packet_info = NULL;
3784 sep_data.current_media_packet_info = NULL;
3785 sep_data.stream_start_in_frame = 0;
3786 sep_data.stream_end_in_frame = 0;
3787 sep_data.stream_number = 1;
3788 sep_data.vendor_id = 0;
3789 sep_data.vendor_codec = 0;
3790 sep_data.configuration_length = 0;
3791 sep_data.configuration = NULL;
3793 if (force_vdp_scms_t || force_vdp_codec) {
3794 if (force_vdp_scms_t)
3795 sep_data.content_protection_type = 2;
3796 else if (data && !no_avdtp_session)
3797 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
3799 if (force_vdp_codec)
3800 sep_data.codec = force_vdp_codec;
3801 else if (data && !no_avdtp_session)
3802 sep_data.codec = ((sep_data_t *) data)->codec;
3803 } else {
3804 if (data && !no_avdtp_session)
3805 sep_data = *((sep_data_t *) data);
3808 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP");
3810 switch (pinfo->p2p_dir) {
3812 case P2P_DIR_SENT:
3813 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3814 break;
3816 case P2P_DIR_RECV:
3817 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3818 break;
3820 case P2P_DIR_UNKNOWN:
3821 col_clear(pinfo->cinfo, COL_INFO);
3822 break;
3824 default:
3825 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3826 pinfo->p2p_dir);
3827 break;
3830 ti = proto_tree_add_item(tree, proto_btvdp, tvb, offset, -1, ENC_NA);
3831 col_append_fstr(pinfo->cinfo, COL_INFO, "Video stream - %s",
3832 val_to_str_const(sep_data.codec, media_codec_video_type_vals, "unknown codec"));
3834 btvdp_tree = proto_item_add_subtree(ti, ett_btvdp);
3836 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3837 proto_item_set_generated(pitem);
3839 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_int_seid, tvb, 0, 0, sep_data.int_seid);
3840 proto_item_set_generated(pitem);
3842 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, 0, 0, sep_data.codec);
3843 proto_item_set_generated(pitem);
3845 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3846 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3847 proto_item_set_generated(pitem);
3849 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3850 proto_item_set_generated(pitem);
3853 if (sep_data.content_protection_type > 0) {
3854 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3855 proto_item_set_generated(pitem);
3858 if (sep_data.stream_start_in_frame > 0) {
3859 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3860 proto_item_set_generated(pitem);
3863 if (sep_data.stream_end_in_frame > 0) {
3864 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3865 proto_item_set_generated(pitem);
3868 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_number, tvb, 0, 0, sep_data.stream_number);
3869 proto_item_set_generated(pitem);
3871 switch (sep_data.codec) {
3872 case CODEC_H263_BASELINE:
3873 case CODEC_H263_PROFILE_3:
3874 case CODEC_H263_PROFILE_8:
3875 codec_dissector = h263_handle;
3876 break;
3877 case CODEC_MPEG4_VSP:
3878 codec_dissector = mp4v_es_handle;
3879 break;
3882 btvdp_codec_info.codec_dissector = codec_dissector;
3883 btvdp_codec_info.content_protection_type = sep_data.content_protection_type;
3885 #if RTP_PLAYER_WORKAROUND == true
3886 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3887 weak to recognize Bluetooth streams (key is: uint32_t interface_id, uint32_t adapter_id, uint32_t chandle, uint32_t cid, uint32_t direction -> uint32_t stream_number) */
3888 pinfo->srcport = sep_data.stream_number;
3889 pinfo->destport = sep_data.stream_number;
3890 #endif
3892 bluetooth_add_address(pinfo, &pinfo->net_dst, 0, "BT VDP", pinfo->num, RTP_MEDIA_VIDEO, &btvdp_codec_info);
3893 call_dissector(rtp_handle, tvb, pinfo, tree);
3894 offset += tvb_reported_length_remaining(tvb, offset);
3896 return offset;
3899 void
3900 proto_register_btvdp(void)
3902 module_t *module;
3903 expert_module_t* expert_btavdtp;
3905 static hf_register_info hf[] = {
3906 { &hf_btvdp_acp_seid,
3907 { "ACP SEID", "btvdp.acp_seid",
3908 FT_UINT8, BASE_DEC, NULL, 0x00,
3909 NULL, HFILL }
3911 { &hf_btvdp_int_seid,
3912 { "INT SEID", "btvdp.int_seid",
3913 FT_UINT8, BASE_DEC, NULL, 0x00,
3914 NULL, HFILL }
3916 { &hf_btvdp_codec,
3917 { "Codec", "btvdp.codec",
3918 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
3919 NULL, HFILL }
3921 { &hf_btvdp_vendor_id,
3922 { "Vendor ID", "btvdp.codec.vendor.vendor_id",
3923 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3924 NULL, HFILL }
3926 { &hf_btvdp_vendor_codec_id,
3927 { "Vendor Codec", "btvdp.codec.vendor.codec_id",
3928 FT_UINT16, BASE_HEX, NULL, 0x00,
3929 NULL, HFILL }
3931 { &hf_btvdp_content_protection,
3932 { "Content Protection", "btvdp.content_protection",
3933 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0,
3934 NULL, HFILL }
3936 { &hf_btvdp_stream_start_in_frame,
3937 { "Stream Start in Frame", "btvdp.stream_start_in_frame",
3938 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3939 NULL, HFILL }
3941 { &hf_btvdp_stream_end_in_frame,
3942 { "Stream End in Frame", "btvdp.stream_end_in_frame",
3943 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3944 NULL, HFILL }
3946 { &hf_btvdp_stream_number,
3947 { "Stream Number", "btvdp.stream_number",
3948 FT_UINT32, BASE_DEC, NULL, 0x00,
3949 NULL, HFILL }
3953 static int *ett[] = {
3954 &ett_btvdp
3957 static ei_register_info ei[] = {
3958 { &ei_btavdtp_sbc_min_bitpool_out_of_range, { "btavdtp.codec.sbc.minimum_bitpool.out_of_range", PI_PROTOCOL, PI_WARN, "Bitpool is out of range. Should be 2..250.", EXPFILL }},
3959 { &ei_btavdtp_sbc_max_bitpool_out_of_range, { "btavdtp.codec.sbc.maximum_bitpool.out_of_range", PI_PROTOCOL, PI_WARN, "Bitpool is out of range. Should be 2..250.", EXPFILL }},
3960 { &ei_btavdtp_unexpected_losc_data, { "btavdtp.unexpected_losc_data", PI_PROTOCOL, PI_WARN, "Unexpected losc data", EXPFILL }},
3963 proto_btvdp = proto_register_protocol("Bluetooth VDP Profile", "BT VDP", "btvdp");
3964 btvdp_handle = register_dissector("btvdp", dissect_btvdp, proto_btvdp);
3965 proto_register_field_array(proto_btvdp, hf, array_length(hf));
3966 proto_register_subtree_array(ett, array_length(ett));
3967 expert_btavdtp = expert_register_protocol(proto_btvdp);
3968 expert_register_field_array(expert_btavdtp, ei, array_length(ei));
3970 module = prefs_register_protocol_subtree("Bluetooth", proto_btvdp, NULL);
3971 prefs_register_static_text_preference(module, "vdp.version",
3972 "Bluetooth Profile VDP version: 1.1",
3973 "Version of profile supported by this dissector.");
3975 prefs_register_bool_preference(module, "vdp.content_protection.scms_t",
3976 "Force SCMS-T decoding",
3977 "Force decoding stream as VDP with Content Protection SCMS-T ",
3978 &force_vdp_scms_t);
3980 prefs_register_enum_preference(module, "vdp.codec",
3981 "Force codec",
3982 "Force decoding stream as VDP with specified codec",
3983 &force_vdp_codec, pref_vdp_codec, false);
3986 void
3987 proto_reg_handoff_btvdp(void)
3989 h263_handle = find_dissector_add_dependency("h263", proto_btvdp);
3990 mp4v_es_handle = find_dissector_add_dependency("mp4v-es", proto_btvdp);
3992 rtp_handle = find_dissector_add_dependency("rtp", proto_btvdp);
3994 dissector_add_string("bluetooth.uuid", "1303", btvdp_handle);
3995 dissector_add_string("bluetooth.uuid", "1304", btvdp_handle);
3996 dissector_add_string("bluetooth.uuid", "1305", btvdp_handle);
3998 dissector_add_for_decode_as("btl2cap.cid", btvdp_handle);
4003 static int
4004 dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4006 proto_item *main_item;
4007 proto_tree *main_tree;
4008 int offset = 0;
4010 main_item = proto_tree_add_item(tree, proto_bta2dp_cph_scms_t, tvb, offset, 1, ENC_NA);
4011 main_tree = proto_item_add_subtree(main_item, ett_bta2dp_cph_scms_t);
4013 proto_tree_add_item(main_tree, hf_bta2dp_reserved , tvb, offset, 1, ENC_NA);
4014 proto_tree_add_item(main_tree, hf_bta2dp_cp_bit, tvb, offset, 1, ENC_NA);
4015 proto_tree_add_item(main_tree, hf_bta2dp_l_bit , tvb, offset, 1, ENC_NA);
4016 offset += 1;
4018 return offset;
4021 void
4022 proto_register_bta2dp_content_protection_header_scms_t(void)
4024 static hf_register_info hf[] = {
4025 { &hf_bta2dp_l_bit,
4026 { "L-bit", "bta2dp.content_protection_header.scms_t.l_bit",
4027 FT_BOOLEAN, 8, NULL, 0x01,
4028 NULL, HFILL }
4030 { &hf_bta2dp_cp_bit,
4031 { "Cp-bit", "bta2dp.content_protection_header.scms_t.cp_bit",
4032 FT_BOOLEAN, 8, NULL, 0x02,
4033 NULL, HFILL }
4035 { &hf_bta2dp_reserved,
4036 { "Reserved", "bta2dp.content_protection_header.scms_t.reserved",
4037 FT_BOOLEAN, 8, NULL, 0xFC,
4038 NULL, HFILL }
4042 static int *ett[] = {
4043 &ett_bta2dp_cph_scms_t
4046 proto_bta2dp_cph_scms_t = proto_register_protocol("Bluetooth A2DP Content Protection Header SCMS-T", "BT A2DP Content Protection Header SCMS-T", "bta2dp_content_protection_header_scms_t");
4047 proto_register_field_array(proto_bta2dp_cph_scms_t, hf, array_length(hf));
4048 proto_register_subtree_array(ett, array_length(ett));
4050 register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t);
4053 static int
4054 dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4056 proto_item *main_item;
4057 proto_tree *main_tree;
4058 int offset = 0;
4060 main_item = proto_tree_add_item(tree, proto_btvdp_cph_scms_t, tvb, offset, 1, ENC_NA);
4061 main_tree = proto_item_add_subtree(main_item, ett_btvdp_cph_scms_t);
4063 proto_tree_add_item(main_tree, hf_btvdp_reserved , tvb, offset, 1, ENC_NA);
4064 proto_tree_add_item(main_tree, hf_btvdp_cp_bit, tvb, offset, 1, ENC_NA);
4065 proto_tree_add_item(main_tree, hf_btvdp_l_bit , tvb, offset, 1, ENC_NA);
4066 offset += 1;
4068 return offset;
4071 void
4072 proto_register_btvdp_content_protection_header_scms_t(void)
4074 static hf_register_info hf[] = {
4075 { &hf_btvdp_l_bit,
4076 { "L-bit", "btvdp.content_protection_header.scms_t.l_bit",
4077 FT_BOOLEAN, 8, NULL, 0x01,
4078 NULL, HFILL }
4080 { &hf_btvdp_cp_bit,
4081 { "Cp-bit", "btvdp.content_protection_header.scms_t.cp_bit",
4082 FT_BOOLEAN, 8, NULL, 0x02,
4083 NULL, HFILL }
4085 { &hf_btvdp_reserved,
4086 { "Reserved", "btvdp.content_protection_header.scms_t.reserved",
4087 FT_BOOLEAN, 8, NULL, 0xFC,
4088 NULL, HFILL }
4092 static int *ett[] = {
4093 &ett_btvdp_cph_scms_t
4096 proto_btvdp_cph_scms_t = proto_register_protocol("Bluetooth VDP Content Protection Header SCMS-T", "BT VDP Content Protection Header SCMS-T", "btvdp_content_protection_header_scms_t");
4097 proto_register_field_array(proto_btvdp_cph_scms_t, hf, array_length(hf));
4098 proto_register_subtree_array(ett, array_length(ett));
4100 register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t);
4104 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4106 * Local variables:
4107 * c-basic-offset: 4
4108 * tab-width: 8
4109 * indent-tabs-mode: nil
4110 * End:
4112 * vi: set shiftwidth=4 tabstop=8 expandtab:
4113 * :indentSize=4:tabSize=8:noTabs=true: