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
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
19 #include "packet-bluetooth.h"
20 #include "packet-btl2cap.h"
21 #include "packet-btsdp.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
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
82 #define CODECID_APT_X 0x0001
83 #define CODECID_APT_X_HD 0x0024
85 #define CODEC_H263_BASELINE 0x01
86 #define CODEC_MPEG4_VSP 0x02
87 #define CODEC_H263_PROFILE_3 0x03
88 #define CODEC_H263_PROFILE_8 0x04
90 #define CODEC_VENDOR 0xFF
96 /* ========================================================== */
97 /* Story: RTP Player, conversation (probably reassemble too) use address:port as
98 "key" to separate devices/streams. In Bluetooth World it is not enough to
99 separate devices/streams. Example key:
100 guint32 interface_id (aka frame.interface_id)
101 guint32 adapter_id (interface like "bluetooth-monitor" or USB provide
102 more than one device over interface, so we must
103 separate information provided by each one)
104 guint16 hci_chandle (aka "connection handle" use to separate connections to devices)
105 guint16 l2cap_psm (like hci_chandle but over l2cap layer, need hci_chandle info because
106 the same PSM can be used over chandles)
107 guint8 rfcomm_channel (like l2cap_psm, but over RFCOMM layer...)
109 guint8 stram_endpoint_number
110 guint32 stream_number (to separate multiple streams for RTP Player)
112 So keys can be various (length or type) and "ports" are not enough to sore
113 all needed information. If one day that changed then all RTP_PLAYER_WORKAROUND
114 block can be removed. This workaround use global number of streams (aka stream ID)
115 to be used as port number in RTP Player to separate streams.
117 #define RTP_PLAYER_WORKAROUND TRUE
119 #if RTP_PLAYER_WORKAROUND == TRUE
120 wmem_tree_t *file_scope_stream_number = NULL;
122 /* ========================================================== */
124 static int proto_btavdtp = -1;
126 static int hf_btavdtp_data = -1;
127 static int hf_btavdtp_message_type = -1;
128 static int hf_btavdtp_packet_type = -1;
129 static int hf_btavdtp_transaction = -1;
130 static int hf_btavdtp_signal = -1;
131 static int hf_btavdtp_signal_id = -1;
132 static int hf_btavdtp_rfa0 = -1;
133 static int hf_btavdtp_number_of_signal_packets = -1;
134 static int hf_btavdtp_sep_seid = -1;
135 static int hf_btavdtp_sep_inuse = -1;
136 static int hf_btavdtp_sep_rfa0 = -1;
137 static int hf_btavdtp_sep_media_type = -1;
138 static int hf_btavdtp_sep_type = -1;
139 static int hf_btavdtp_sep_rfa1 = -1;
140 static int hf_btavdtp_error_code = -1;
141 static int hf_btavdtp_acp_sep = -1;
142 static int hf_btavdtp_acp_seid_item = -1;
143 static int hf_btavdtp_int_seid_item = -1;
144 static int hf_btavdtp_acp_seid = -1;
145 static int hf_btavdtp_int_seid = -1;
146 static int hf_btavdtp_service_category = -1;
147 static int hf_btavdtp_rfa_seid = -1;
148 static int hf_btavdtp_delay = -1;
149 static int hf_btavdtp_length_of_service_category = -1;
150 static int hf_btavdtp_recovery_type = -1;
151 static int hf_btavdtp_maximum_recovery_window_size = -1;
152 static int hf_btavdtp_maximum_number_of_media_packet_in_parity_code = -1;
153 static int hf_btavdtp_multiplexing_fragmentation = -1;
154 static int hf_btavdtp_multiplexing_rfa = -1;
155 static int hf_btavdtp_multiplexing_tsid = -1;
156 static int hf_btavdtp_multiplexing_tcid = -1;
157 static int hf_btavdtp_multiplexing_entry_rfa = -1;
158 static int hf_btavdtp_header_compression_backch = -1;
159 static int hf_btavdtp_header_compression_media = -1;
160 static int hf_btavdtp_header_compression_recovery = -1;
161 static int hf_btavdtp_header_compression_rfa = -1;
162 static int hf_btavdtp_content_protection_type = -1;
163 static int hf_btavdtp_media_codec_media_type = -1;
164 static int hf_btavdtp_media_codec_rfa = -1;
165 static int hf_btavdtp_media_codec_unknown_type = -1;
166 static int hf_btavdtp_media_codec_audio_type = -1;
167 static int hf_btavdtp_media_codec_video_type = -1;
168 static int hf_btavdtp_sbc_sampling_frequency_16000 = -1;
169 static int hf_btavdtp_sbc_sampling_frequency_32000 = -1;
170 static int hf_btavdtp_sbc_sampling_frequency_44100 = -1;
171 static int hf_btavdtp_sbc_sampling_frequency_48000 = -1;
172 static int hf_btavdtp_sbc_channel_mode_mono = -1;
173 static int hf_btavdtp_sbc_channel_mode_dual_channel = -1;
174 static int hf_btavdtp_sbc_channel_mode_stereo = -1;
175 static int hf_btavdtp_sbc_channel_mode_joint_stereo = -1;
176 static int hf_btavdtp_sbc_block_4 = -1;
177 static int hf_btavdtp_sbc_block_8 = -1;
178 static int hf_btavdtp_sbc_block_12 = -1;
179 static int hf_btavdtp_sbc_block_16 = -1;
180 static int hf_btavdtp_sbc_subbands_4 = -1;
181 static int hf_btavdtp_sbc_subbands_8 = -1;
182 static int hf_btavdtp_sbc_allocation_method_snr = -1;
183 static int hf_btavdtp_sbc_allocation_method_loudness = -1;
184 static int hf_btavdtp_sbc_min_bitpool = -1;
185 static int hf_btavdtp_sbc_max_bitpool = -1;
186 static int hf_btavdtp_mpeg12_layer_1 = -1;
187 static int hf_btavdtp_mpeg12_layer_2 = -1;
188 static int hf_btavdtp_mpeg12_layer_3 = -1;
189 static int hf_btavdtp_mpeg12_crc_protection = -1;
190 static int hf_btavdtp_mpeg12_channel_mode_mono = -1;
191 static int hf_btavdtp_mpeg12_channel_mode_dual_channel = -1;
192 static int hf_btavdtp_mpeg12_channel_mode_stereo = -1;
193 static int hf_btavdtp_mpeg12_channel_mode_joint_stereo = -1;
194 static int hf_btavdtp_mpeg12_rfa = -1;
195 static int hf_btavdtp_mpeg12_mpf_2 = -1;
196 static int hf_btavdtp_mpeg12_sampling_frequency_16000 = -1;
197 static int hf_btavdtp_mpeg12_sampling_frequency_22050 = -1;
198 static int hf_btavdtp_mpeg12_sampling_frequency_24000 = -1;
199 static int hf_btavdtp_mpeg12_sampling_frequency_32000 = -1;
200 static int hf_btavdtp_mpeg12_sampling_frequency_44100 = -1;
201 static int hf_btavdtp_mpeg12_sampling_frequency_48000 = -1;
202 static int hf_btavdtp_mpeg12_vbr_supported = -1;
203 static int hf_btavdtp_mpeg12_bit_rate = -1;
204 static int hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc = -1;
205 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc = -1;
206 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp = -1;
207 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable = -1;
208 static int hf_btavdtp_mpeg24_object_type_rfa = -1;
209 static int hf_btavdtp_mpeg24_sampling_frequency_8000 = -1;
210 static int hf_btavdtp_mpeg24_sampling_frequency_11025 = -1;
211 static int hf_btavdtp_mpeg24_sampling_frequency_12000 = -1;
212 static int hf_btavdtp_mpeg24_sampling_frequency_16000 = -1;
213 static int hf_btavdtp_mpeg24_sampling_frequency_22050 = -1;
214 static int hf_btavdtp_mpeg24_sampling_frequency_24000 = -1;
215 static int hf_btavdtp_mpeg24_sampling_frequency_32000 = -1;
216 static int hf_btavdtp_mpeg24_sampling_frequency_44100 = -1;
217 static int hf_btavdtp_mpeg24_sampling_frequency_48000 = -1;
218 static int hf_btavdtp_mpeg24_sampling_frequency_64000 = -1;
219 static int hf_btavdtp_mpeg24_sampling_frequency_88200 = -1;
220 static int hf_btavdtp_mpeg24_sampling_frequency_96000 = -1;
221 static int hf_btavdtp_mpeg24_channels_1 = -1;
222 static int hf_btavdtp_mpeg24_channels_2 = -1;
223 static int hf_btavdtp_mpeg24_rfa = -1;
224 static int hf_btavdtp_mpeg24_vbr_supported = -1;
225 static int hf_btavdtp_mpeg24_bit_rate = -1;
226 static int hf_btavdtp_atrac_version = -1;
227 static int hf_btavdtp_atrac_channel_mode_single_channel = -1;
228 static int hf_btavdtp_atrac_channel_mode_dual_channel = -1;
229 static int hf_btavdtp_atrac_channel_mode_joint_stereo = -1;
230 static int hf_btavdtp_atrac_rfa1 = -1;
231 static int hf_btavdtp_atrac_rfa2 = -1;
232 static int hf_btavdtp_atrac_sampling_frequency_44100 = -1;
233 static int hf_btavdtp_atrac_sampling_frequency_48000 = -1;
234 static int hf_btavdtp_atrac_vbr_supported = -1;
235 static int hf_btavdtp_atrac_bit_rate = -1;
236 static int hf_btavdtp_atrac_maximum_sul = -1;
237 static int hf_btavdtp_atrac_rfa3 = -1;
238 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000 = -1;
239 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000 = -1;
240 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100 = -1;
241 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000 = -1;
242 static int hf_btavdtp_vendor_specific_aptx_channel_mode_mono = -1;
243 static int hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel = -1;
244 static int hf_btavdtp_vendor_specific_aptx_channel_mode_stereo = -1;
245 static int hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo = -1;
246 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000 = -1;
247 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000 = -1;
248 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100 = -1;
249 static int hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000 = -1;
250 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono = -1;
251 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel = -1;
252 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo = -1;
253 static int hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo = -1;
254 static int hf_btavdtp_vendor_specific_aptxhd_rfa = -1;
255 static int hf_btavdtp_h263_level_10 = -1;
256 static int hf_btavdtp_h263_level_20 = -1;
257 static int hf_btavdtp_h263_level_30 = -1;
258 static int hf_btavdtp_h263_level_rfa = -1;
259 static int hf_btavdtp_mpeg4_level_0 = -1;
260 static int hf_btavdtp_mpeg4_level_1 = -1;
261 static int hf_btavdtp_mpeg4_level_2 = -1;
262 static int hf_btavdtp_mpeg4_level_3 = -1;
263 static int hf_btavdtp_mpeg4_level_rfa = -1;
264 static int hf_btavdtp_vendor_id = -1;
265 static int hf_btavdtp_vendor_specific_codec_id = -1;
266 static int hf_btavdtp_vendor_specific_value = -1;
267 static int hf_btavdtp_vendor_specific_apt_codec_id = -1;
268 static int hf_btavdtp_capabilities = -1;
269 static int hf_btavdtp_service = -1;
270 static int hf_btavdtp_service_multiplexing_entry = -1;
272 static gint ett_btavdtp = -1;
273 static gint ett_btavdtp_sep = -1;
274 static gint ett_btavdtp_capabilities = -1;
275 static gint ett_btavdtp_service = -1;
277 static expert_field ei_btavdtp_sbc_min_bitpool_out_of_range = EI_INIT;
278 static expert_field ei_btavdtp_sbc_max_bitpool_out_of_range = EI_INIT;
279 static expert_field ei_btavdtp_unexpected_losc_data = EI_INIT;
281 static dissector_handle_t btavdtp_handle;
282 static dissector_handle_t bta2dp_handle;
283 static dissector_handle_t btvdp_handle;
284 static dissector_handle_t rtp_handle;
286 static wmem_tree_t *channels = NULL;
287 static wmem_tree_t *sep_list = NULL;
288 static wmem_tree_t *sep_open = NULL;
289 static wmem_tree_t *media_packet_times = NULL;
291 /* A2DP declarations */
292 static gint proto_bta2dp = -1;
293 static gint ett_bta2dp = -1;
294 static gint proto_bta2dp_cph_scms_t = -1;
295 static gint ett_bta2dp_cph_scms_t = -1;
297 static int hf_bta2dp_acp_seid = -1;
298 static int hf_bta2dp_int_seid = -1;
299 static int hf_bta2dp_codec = -1;
300 static int hf_bta2dp_vendor_id = -1;
301 static int hf_bta2dp_vendor_codec_id = -1;
302 static int hf_bta2dp_content_protection = -1;
303 static int hf_bta2dp_stream_start_in_frame = -1;
304 static int hf_bta2dp_stream_end_in_frame = -1;
305 static int hf_bta2dp_stream_number = -1;
306 static int hf_bta2dp_l_bit = -1;
307 static int hf_bta2dp_cp_bit = -1;
308 static int hf_bta2dp_reserved = -1;
310 static dissector_handle_t sbc_handle;
311 static dissector_handle_t mp2t_handle;
312 static dissector_handle_t mpeg_audio_handle;
313 static dissector_handle_t atrac_handle;
315 static gboolean force_a2dp_scms_t = FALSE;
316 static gint force_a2dp_codec = CODEC_DEFAULT;
318 static const enum_val_t pref_a2dp_codec[] = {
319 { "default", "Default", CODEC_DEFAULT },
320 { "sbc", "SBC", CODEC_SBC },
321 { "mp2t", "MPEG12 AUDIO", CODEC_MPEG12_AUDIO },
322 { "mpeg-audio", "MPEG24 AAC", CODEC_MPEG24_AAC },
323 /* XXX: Not supported in Wireshark yet { "atrac", "ATRAC", CODEC_ATRAC },*/
324 { "aptx", "aptX", CODEC_APT_X },
325 { "aptx-hd", "aptX HD", CODEC_APT_X_HD },
330 /* VDP declarations */
331 static gint proto_btvdp = -1;
332 static gint ett_btvdp = -1;
333 static gint proto_btvdp_cph_scms_t = -1;
334 static gint ett_btvdp_cph_scms_t = -1;
336 static int hf_btvdp_acp_seid = -1;
337 static int hf_btvdp_int_seid = -1;
338 static int hf_btvdp_codec = -1;
339 static int hf_btvdp_vendor_id = -1;
340 static int hf_btvdp_vendor_codec_id = -1;
341 static int hf_btvdp_content_protection = -1;
342 static int hf_btvdp_stream_start_in_frame = -1;
343 static int hf_btvdp_stream_end_in_frame = -1;
344 static int hf_btvdp_stream_number = -1;
345 static int hf_btvdp_l_bit = -1;
346 static int hf_btvdp_cp_bit = -1;
347 static int hf_btvdp_reserved = -1;
349 static dissector_handle_t h263_handle;
350 static dissector_handle_t mp4v_es_handle;
352 static gboolean force_vdp_scms_t = FALSE;
353 static gint force_vdp_codec = CODEC_H263_BASELINE;
355 static const enum_val_t pref_vdp_codec[] = {
356 { "h263", "H263", CODEC_H263_BASELINE },
357 { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP },
362 static int proto_aptx = -1;
363 static int hf_aptx_data = -1;
364 static int hf_aptx_cumulative_frame_duration = -1;
365 static int hf_aptx_delta_time = -1;
366 static int hf_aptx_avrcp_song_position = -1;
367 static int hf_aptx_delta_time_from_the_beginning = -1;
368 static int hf_aptx_cumulative_duration = -1;
369 static int hf_aptx_diff = -1;
370 static gint ett_aptx = -1;
371 static dissector_handle_t aptx_handle;
374 static const value_string message_type_vals[] = {
376 { 0x01, "GeneralReject" },
377 { 0x02, "ResponseAccept" },
378 { 0x03, "ResponseReject" },
382 static const value_string packet_type_vals[] = {
385 { 0x02, "Continue" },
390 static const value_string signal_id_vals[] = {
391 { 0x00, "Reserved" },
392 { 0x01, "Discover" },
393 { 0x02, "GetCapabilities" },
394 { 0x03, "SetConfiguration" },
395 { 0x04, "GetConfiguration" },
396 { 0x05, "Reconfigure" },
402 { 0x0B, "SecurityControl" },
403 { 0x0C, "GetAllCapabilities" },
404 { 0x0D, "DelayReport" },
408 static const value_string media_type_vals[] = {
411 { 0x02, "Multimedia" },
415 static const value_string sep_type_vals[] = {
421 static const value_string true_false[] = {
427 static const value_string error_code_vals[] = {
428 /* ACP to INT, Signal Response Header Error Codes */
429 { 0x01, "Bad Header Format" },
430 /* ACP to INT, Signal Response Payload Format Error Codes */
431 { 0x11, "Bad Length" },
432 { 0x12, "Bad ACP SEID" },
433 { 0x13, "SEP In Use" },
434 { 0x14, "SEP Not In Use" },
435 { 0x17, "Bad Service Category" },
436 { 0x18, "Bad Payload Format" },
437 { 0x19, "Not Supported Command" },
438 { 0x1A, "Invalid Capabilities" },
439 /* ACP to INT, Signal Response Transport Service Capabilities Error Codes */
440 { 0x22, "Bad Recovery Type" },
441 { 0x23, "Bad Media Transport Format" },
442 { 0x25, "Bad Recovery Format" },
443 { 0x26, "Bad Header Compression Format" },
444 { 0x27, "Bad Content Protection Format" },
445 { 0x28, "Bad Multiplexing Format" },
446 { 0x29, "Unsupported Configuration" },
447 /* ACP to INT, Procedure Error Codes */
448 { 0x31, "Bad State" },
450 { 0x80, "The Service Category Stated is Invalid" },
451 { 0x81, "Lack of Resource New Stream Context" },
453 { 0xC1, "Invalid Codec Type" },
454 { 0xC2, "Not Supported Codec Type" },
455 { 0xC3, "Invalid Sampling Frequency" },
456 { 0xC4, "Not Supported Sampling Frequency" },
457 { 0xC5, "Invalid Channel Mode" },
458 { 0xC6, "Not Supported Channel Mode" },
459 { 0xC7, "Invalid Subbands" },
460 { 0xC8, "Not Supported Subbands" },
461 { 0xC9, "Invalid Allocation Method" },
462 { 0xCA, "Not Supported Allocation Method" },
463 { 0xCB, "Invalid Minimum Bitpool Value" },
464 { 0xCC, "Not Supported Minimum Bitpool Value" },
465 { 0xCD, "Invalid Maximum Bitpool Value" },
466 { 0xCE, "Not Supported Maximum Bitpool Value" },
467 { 0xCF, "Invalid Layer" },
468 { 0xD0, "Not Supported Layer" },
469 { 0xD1, "Not Supported CRC" },
470 { 0xD2, "Not Supported MPF" },
471 { 0xD3, "Not Supported VBR" },
472 { 0xD4, "Invalid Bit Rate" },
473 { 0xD5, "Not Supported Bit Rate" },
474 { 0xD6, "Invalid Object Type" },
475 { 0xD7, "Not Supported Object Type" },
476 { 0xD8, "Invalid Channels" },
477 { 0xD9, "Not Supported Channels" },
478 { 0xDA, "Invalid Version" },
479 { 0xDB, "Not Supported Version" },
480 { 0xDC, "Not Supported Maximum SUL" },
481 { 0xDD, "Invalid Block Length" },
482 { 0xE0, "Invalid Content Protection Type" },
483 { 0xE1, "Invalid Content Protection Format" },
484 { 0xE2, "Invalid Coded Parameter" },
485 { 0xE3, "Not Supported Codec Parameter" },
489 static const value_string service_category_vals[] = {
490 { 0x01, "Media Transport" },
491 { 0x02, "Reporting" },
492 { 0x03, "Recovery" },
493 { 0x04, "Content Protection" },
494 { 0x05, "Header Compression" },
495 { 0x06, "Multiplexing" },
496 { 0x07, "Media Codec" },
497 { 0x08, "Delay Reporting" },
501 static const value_string recovery_type_vals[] = {
502 { 0x00, "Forbidden" },
507 static const value_string multiplexing_tsid_vals[] = {
508 { 0x00, "Used for TSID query" },
513 static const value_string multiplexing_tcid_vals[] = {
514 { 0x00, "Used for TCID query" },
519 static const value_string media_codec_audio_type_vals[] = {
521 { 0x01, "MPEG-1,2 Audio" },
522 { 0x02, "MPEG-2,4 AAC" },
523 { 0x04, "ATRAC family" },
524 { 0xFF, "non-A2DP" },
528 static const value_string media_codec_video_type_vals[] = {
529 { 0x01, "H.263 baseline" },
530 { 0x02, "MPEG-4 Visual Simple Profile" },
531 { 0x03, "H.263 profile 3" },
532 { 0x04, "H.263 profile 8" },
537 static const value_string content_protection_type_vals[] = {
543 static const value_string vendor_apt_codec_vals[] = {
544 { CODECID_APT_X, "aptX" },
545 { CODECID_APT_X_HD, "aptX HD" },
555 typedef struct _sep_entry_t {
562 guint16 vendor_codec;
563 guint8 configuration_length;
564 guint8 *configuration;
565 gint content_protection_type;
567 enum sep_state state;
570 typedef struct _sep_data_t {
573 guint16 vendor_codec;
574 guint8 configuration_length;
575 guint8 *configuration;
578 gint content_protection_type;
579 guint32 stream_start_in_frame;
580 guint32 stream_end_in_frame;
581 guint32 stream_number;
582 media_packet_info_t *previous_media_packet_info;
583 media_packet_info_t *current_media_packet_info;
586 typedef struct _media_stream_number_value_t {
587 guint32 stream_start_in_frame;
588 guint32 stream_end_in_frame;
589 guint32 stream_number;
590 } media_stream_number_value_t;
592 typedef struct _channels_info_t {
593 guint32 control_local_cid;
594 guint32 control_remote_cid;
595 guint32 media_local_cid;
596 guint32 media_remote_cid;
597 wmem_tree_t *stream_numbers;
598 guint32 disconnect_in_frame;
599 guint32 *l2cap_disconnect_in_frame;
600 guint32 *hci_disconnect_in_frame;
601 guint32 *adapter_disconnect_in_frame;
606 void proto_register_btavdtp(void);
607 void proto_reg_handoff_btavdtp(void);
608 void proto_register_bta2dp(void);
609 void proto_reg_handoff_bta2dp(void);
610 void proto_register_bta2dp_content_protection_header_scms_t(void);
611 void proto_register_btvdp(void);
612 void proto_reg_handoff_btvdp(void);
613 void proto_register_btvdp_content_protection_header_scms_t(void);
614 void proto_register_aptx(void);
618 get_sep_type(guint32 interface_id,
619 guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
621 wmem_tree_key_t key[6];
622 wmem_tree_t *subtree;
626 key[0].key = &interface_id;
628 key[1].key = &adapter_id;
630 key[2].key = &chandle;
632 key[3].key = &direction;
638 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
639 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
641 return val_to_str_const(sep->type, sep_type_vals, "unknown");
648 get_sep_media_type(guint32 interface_id,
649 guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
651 wmem_tree_key_t key[6];
652 wmem_tree_t *subtree;
656 key[0].key = &interface_id;
658 key[1].key = &adapter_id;
660 key[2].key = &chandle;
662 key[3].key = &direction;
668 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
669 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
671 return val_to_str_const(sep->media_type, media_type_vals, "unknown");
679 dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
680 guint32 interface_id, guint32 adapter_id, guint32 chandle)
682 proto_tree *sep_tree;
683 proto_item *sep_item;
692 /* Reverse direction to avoid mass reversing it, because this is only case
693 when SEP is provided in ACP role, otherwise INT frequently asking for it
695 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
696 items = tvb_reported_length_remaining(tvb, offset) / 2;
697 while (tvb_reported_length_remaining(tvb, offset) > 0) {
698 seid = tvb_get_guint8(tvb, offset);
699 in_use = seid & 0x02;
701 media_type = tvb_get_guint8(tvb, offset + 1) >> 4;
702 type = (tvb_get_guint8(tvb, offset + 1) & 0x08) >> 3;
703 sep_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_sep, tvb, offset, 2, "ACP SEP [%u - %s %s] item %u/%u",
704 seid, val_to_str_const(media_type, media_type_vals, "unknown"),
705 val_to_str_const(type, sep_type_vals, "unknown"), i_sep, items);
706 sep_tree = proto_item_add_subtree(sep_item, ett_btavdtp_sep);
708 proto_tree_add_item(sep_tree, hf_btavdtp_sep_seid , tvb, offset, 1, ENC_NA);
709 proto_tree_add_item(sep_tree, hf_btavdtp_sep_inuse, tvb, offset, 1, ENC_NA);
710 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa0 , tvb, offset, 1, ENC_NA);
713 proto_tree_add_item(sep_tree, hf_btavdtp_sep_media_type, tvb, offset, 1, ENC_NA);
714 proto_tree_add_item(sep_tree, hf_btavdtp_sep_type , tvb, offset, 1, ENC_NA);
715 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa1 , tvb, offset, 1, ENC_NA);
717 if (!pinfo->fd->flags.visited) {
718 sep_entry_t *sep_data;
719 wmem_tree_key_t key[7];
720 guint32 frame_number = pinfo->num;
723 key[0].key = &interface_id;
725 key[1].key = &adapter_id;
727 key[2].key = &chandle;
729 key[3].key = &direction;
733 key[5].key = &frame_number;
737 sep_data = wmem_new0(wmem_file_scope(), sep_entry_t);
738 sep_data->seid = seid;
739 sep_data->type = type;
740 sep_data->media_type = media_type;
741 sep_data->codec = -1;
743 sep_data->state = SEP_STATE_IN_USE;
745 sep_data->state = SEP_STATE_FREE;
748 wmem_tree_insert32_array(sep_list, key, sep_data);
755 col_append_fstr(pinfo->cinfo, COL_INFO, " - items: %u", items);
761 dissect_codec(tvbuff_t *tvb, packet_info *pinfo, proto_item *service_item, proto_tree *tree, gint offset,
762 guint losc, gint media_type, gint media_codec_type, guint32 *vendor_id, guint16 *vendor_codec)
766 guint8 *value8 = (guint8 *) &value;
769 case MEDIA_TYPE_AUDIO:
770 switch(media_codec_type) {
772 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_16000, tvb, offset, 1, ENC_NA);
773 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_32000, tvb, offset, 1, ENC_NA);
774 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_44100, tvb, offset, 1, ENC_NA);
775 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_48000, tvb, offset, 1, ENC_NA);
776 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_mono, tvb, offset, 1, ENC_NA);
777 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
778 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_stereo, tvb, offset, 1, ENC_NA);
779 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
781 proto_tree_add_item(tree, hf_btavdtp_sbc_block_4, tvb, offset + 1, 1, ENC_NA);
782 proto_tree_add_item(tree, hf_btavdtp_sbc_block_8, tvb, offset + 1, 1, ENC_NA);
783 proto_tree_add_item(tree, hf_btavdtp_sbc_block_12, tvb, offset + 1, 1, ENC_NA);
784 proto_tree_add_item(tree, hf_btavdtp_sbc_block_16, tvb, offset + 1, 1, ENC_NA);
785 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_4, tvb, offset + 1, 1, ENC_NA);
786 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_8, tvb, offset + 1, 1, ENC_NA);
787 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_snr, tvb, offset + 1, 1, ENC_NA);
788 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_loudness, tvb, offset + 1, 1, ENC_NA);
790 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_min_bitpool, tvb, offset + 2, 1, ENC_NA);
791 value = tvb_get_guint8(tvb, offset + 2);
792 if (value < 2 || value > 250) {
793 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_min_bitpool_out_of_range);
796 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_max_bitpool, tvb, offset + 3, 1, ENC_NA);
797 value = tvb_get_guint8(tvb, offset + 3);
798 if (value < 2 || value > 250) {
799 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_max_bitpool_out_of_range);
802 value = tvb_get_h_guint32(tvb, offset);
804 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)",
805 (value8[0] & 0x80) ? "16000 " : "",
806 (value8[0] & 0x40) ? "32000 " : "",
807 (value8[0] & 0x20) ? "44100 " : "",
808 (value8[0] & 0x10) ? "48000 " : "",
809 (value8[0] & 0xF0) ? "" : "not set ",
810 (value8[0] & 0x08) ? "Mono " : "",
811 (value8[0] & 0x04) ? "DualChannel " : "",
812 (value8[0] & 0x02) ? "Stereo " : "",
813 (value8[0] & 0x01) ? "JointStereo " : "",
814 (value8[0] & 0x0F) ? "" : "not set ",
815 (value8[1] & 0x80) ? "4 " : "",
816 (value8[1] & 0x40) ? "8 " : "",
817 (value8[1] & 0x20) ? "12 " : "",
818 (value8[1] & 0x10) ? "16 " : "",
819 (value8[1] & 0xF0) ? "" : "not set ",
820 (value8[1] & 0x08) ? "4 " : "",
821 (value8[1] & 0x04) ? "8 " : "",
822 (value8[1] & 0x0C) ? "" : "not set ",
823 (value8[1] & 0x02) ? "SNR " : "",
824 (value8[1] & 0x01) ? "Loudness " : "",
825 (value8[1] & 0x03) ? "" : "not set ",
829 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)",
830 (value8[0] & 0x80) ? "16000 " : "",
831 (value8[0] & 0x40) ? "32000 " : "",
832 (value8[0] & 0x20) ? "44100 " : "",
833 (value8[0] & 0x10) ? "48000 " : "",
834 (value8[0] & 0xF0) ? "" : "not set ",
835 (value8[0] & 0x08) ? "Mono " : "",
836 (value8[0] & 0x04) ? "DualChannel " : "",
837 (value8[0] & 0x02) ? "Stereo " : "",
838 (value8[0] & 0x01) ? "JointStereo " : "",
839 (value8[0] & 0x0F) ? "" : "not set ",
840 (value8[1] & 0x80) ? "4 " : "",
841 (value8[1] & 0x40) ? "8 " : "",
842 (value8[1] & 0x20) ? "12 " : "",
843 (value8[1] & 0x10) ? "16 " : "",
844 (value8[1] & 0xF0) ? "" : "not set ",
845 (value8[1] & 0x08) ? "4 " : "",
846 (value8[1] & 0x04) ? "8 " : "",
847 (value8[1] & 0x0C) ? "" : "not set ",
848 (value8[1] & 0x02) ? "SNR " : "",
849 (value8[1] & 0x01) ? "Loudness " : "",
850 (value8[1] & 0x03) ? "" : "not set ",
854 col_append_fstr(pinfo->cinfo, COL_INFO, " (none)");
855 proto_item_append_text(service_item, " (none)");
859 case CODEC_MPEG12_AUDIO:
860 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_1, tvb, offset, 1, ENC_NA);
861 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_2, tvb, offset, 1, ENC_NA);
862 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_3, tvb, offset, 1, ENC_NA);
863 proto_tree_add_item(tree, hf_btavdtp_mpeg12_crc_protection, tvb, offset, 1, ENC_NA);
864 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_mono, tvb, offset, 1, ENC_NA);
865 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
866 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_stereo, tvb, offset, 1, ENC_NA);
867 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
869 proto_tree_add_item(tree, hf_btavdtp_mpeg12_rfa, tvb, offset + 1, 1, ENC_NA);
870 proto_tree_add_item(tree, hf_btavdtp_mpeg12_mpf_2, tvb, offset + 1, 1, ENC_NA);
871 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
872 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
873 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
874 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
875 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
876 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_48000, tvb, offset + 1, 1, ENC_NA);
878 proto_tree_add_item(tree, hf_btavdtp_mpeg12_vbr_supported, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
879 proto_tree_add_item(tree, hf_btavdtp_mpeg12_bit_rate, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
881 case CODEC_MPEG24_AAC:
882 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc, tvb, offset, 1, ENC_NA);
883 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc, tvb, offset, 1, ENC_NA);
884 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp, tvb, offset, 1, ENC_NA);
885 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable, tvb, offset, 1, ENC_NA);
886 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_rfa, tvb, offset, 1, ENC_NA);
888 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_8000, tvb, offset + 1, 1, ENC_NA);
889 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_11025, tvb, offset + 1, 1, ENC_NA);
890 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_12000, tvb, offset + 1, 1, ENC_NA);
891 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
892 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
893 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
894 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
895 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
897 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_48000, tvb, offset + 2, 1, ENC_NA);
898 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_64000, tvb, offset + 2, 1, ENC_NA);
899 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_88200, tvb, offset + 2, 1, ENC_NA);
900 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_96000, tvb, offset + 2, 1, ENC_NA);
901 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_1, tvb, offset + 2, 1, ENC_NA);
902 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_2, tvb, offset + 2, 1, ENC_NA);
903 proto_tree_add_item(tree, hf_btavdtp_mpeg24_rfa, tvb, offset + 2, 1, ENC_NA);
905 proto_tree_add_item(tree, hf_btavdtp_mpeg24_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
906 proto_tree_add_item(tree, hf_btavdtp_mpeg24_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
909 proto_tree_add_item(tree, hf_btavdtp_atrac_version, tvb, offset, 1, ENC_NA);
910 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_single_channel, tvb, offset, 1, ENC_NA);
911 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
912 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
913 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa1, tvb, offset, 1, ENC_NA);
915 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa2, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
916 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_44100, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
917 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_48000, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
918 proto_tree_add_item(tree, hf_btavdtp_atrac_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
919 proto_tree_add_item(tree, hf_btavdtp_atrac_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
921 proto_tree_add_item(tree, hf_btavdtp_atrac_maximum_sul, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
923 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa3, tvb, offset + 6, 1, ENC_NA);
925 case CODEC_VENDOR: /* non-A2DP */
926 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
929 *vendor_id = tvb_get_letohl(tvb, offset);
932 *vendor_codec = tvb_get_letohs(tvb, offset + 4);
934 switch (tvb_get_letohl(tvb, offset)) {
935 case 0x004F: /* APT Licensing Ltd. */
936 case 0x00D7: /* Qualcomm technologies, Inc. */
937 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_apt_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
938 value = tvb_get_letohs(tvb, offset + 4);
940 if (value == CODECID_APT_X || value == CODECID_APT_X_HD) { /* APT-X or APT-X HD Codec */
941 if (value == CODECID_APT_X) {
942 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000, tvb, offset + 6, 1, ENC_NA);
943 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000, tvb, offset + 6, 1, ENC_NA);
944 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
945 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
946 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
947 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel, tvb, offset + 6, 1, ENC_NA);
948 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
949 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo, tvb, offset + 6, 1, ENC_NA);
951 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000, tvb, offset + 6, 1, ENC_NA);
952 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000, tvb, offset + 6, 1, ENC_NA);
953 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
954 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
955 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
956 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel, tvb, offset + 6, 1, ENC_NA);
957 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
958 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo, tvb, offset + 6, 1, ENC_NA);
959 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptxhd_rfa, tvb, offset + 7, 4, ENC_NA);
962 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s -",
963 val_to_str_const(value, vendor_apt_codec_vals, "unknown codec"));
964 proto_item_append_text(service_item, " (%s -",
965 val_to_str_const(value, vendor_apt_codec_vals, "unknown codec"));
967 value = tvb_get_guint8(tvb, offset + 6);
969 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s,%s%s%s%s%s)",
970 (value & 0x80) ? " 16000" : "",
971 (value & 0x40) ? " 32000" : "",
972 (value & 0x20) ? " 44100" : "",
973 (value & 0x10) ? " 48000" : "",
974 (value & 0xF0) ? "" : "not set ",
975 (value & 0x08) ? " Mono" : "",
976 (value & 0x04) ? " DualChannel" : "",
977 (value & 0x02) ? " Stereo" : "",
978 (value & 0x01) ? " JointStereo" : "",
979 (value & 0x0F) ? "" : "not set ");
981 proto_item_append_text(service_item, "%s%s%s%s%s,%s%s%s%s%s)",
982 (value & 0x80) ? " 16000" : "",
983 (value & 0x40) ? " 32000" : "",
984 (value & 0x20) ? " 44100" : "",
985 (value & 0x10) ? " 48000" : "",
986 (value & 0xF0) ? "" : "not set ",
987 (value & 0x08) ? " Mono" : "",
988 (value & 0x04) ? " DualChannel" : "",
989 (value & 0x02) ? " Stereo" : "",
990 (value & 0x01) ? " JointStereo" : "",
991 (value & 0x0F) ? "" : "not set ");
993 col_append_fstr(pinfo->cinfo, COL_INFO, " none)");
994 proto_item_append_text(service_item, " none)");
997 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1001 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1002 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1007 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1010 case MEDIA_TYPE_VIDEO:
1011 switch(media_codec_type) {
1012 case CODEC_H263_BASELINE:
1013 case CODEC_H263_PROFILE_3:
1014 case CODEC_H263_PROFILE_8:
1015 proto_tree_add_item(tree, hf_btavdtp_h263_level_10, tvb, offset, 1, ENC_NA);
1016 proto_tree_add_item(tree, hf_btavdtp_h263_level_20, tvb, offset, 1, ENC_NA);
1017 proto_tree_add_item(tree, hf_btavdtp_h263_level_30, tvb, offset, 1, ENC_NA);
1018 proto_tree_add_item(tree, hf_btavdtp_h263_level_rfa, tvb, offset, 1, ENC_NA);
1020 case CODEC_MPEG4_VSP:
1021 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_0, tvb, offset, 1, ENC_NA);
1022 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_1, tvb, offset, 1, ENC_NA);
1023 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_2, tvb, offset, 1, ENC_NA);
1024 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_3, tvb, offset, 1, ENC_NA);
1025 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_rfa, tvb, offset, 1, ENC_NA);
1027 case CODEC_VENDOR: /* non-VDP */
1028 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1029 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1030 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1033 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1037 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1047 dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo,
1048 proto_tree *tree, gint offset, gint *codec,
1049 gint *content_protection_type, guint32 *vendor_id,
1050 guint16 *vendor_codec, guint32 *configuration_offset,
1051 guint8 *configuration_length)
1053 proto_item *pitem = NULL;
1054 proto_item *ptree = NULL;
1055 proto_tree *capabilities_tree;
1056 proto_item *capabilities_item;
1057 proto_tree *service_tree = NULL;
1058 proto_item *service_item = NULL;
1059 gint service_category = 0;
1061 gint recovery_type = 0;
1062 gint maximum_recovery_window_size = 0;
1063 gint maximum_number_of_media_packet_in_parity_code = 0;
1064 gint media_type = 0;
1065 gint media_codec_type = 0;
1067 capabilities_item = proto_tree_add_item(tree, hf_btavdtp_capabilities, tvb, offset, tvb_reported_length(tvb) - offset, ENC_NA);
1068 capabilities_tree = proto_item_add_subtree(capabilities_item, ett_btavdtp_capabilities);
1074 *vendor_id = 0x003F; /* Bluetooth SIG */
1079 if (configuration_length)
1080 *configuration_length = 0;
1082 if (configuration_offset)
1083 *configuration_offset = 0;
1085 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1086 service_category = tvb_get_guint8(tvb, offset);
1087 losc = tvb_get_guint8(tvb, offset + 1);
1088 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"));
1089 service_tree = proto_item_add_subtree(service_item, ett_btavdtp_service);
1091 proto_tree_add_item(service_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1094 proto_tree_add_item(service_tree, hf_btavdtp_length_of_service_category, tvb, offset, 1, ENC_NA);
1097 switch (service_category) {
1098 case SERVICE_CATEGORY_MEDIA_TRANSPORT:
1099 case SERVICE_CATEGORY_REPORTING:
1100 case SERVICE_CATEGORY_DELAY_REPORTING:
1101 /* losc should be 0 */
1103 case SERVICE_CATEGORY_RECOVERY:
1104 recovery_type = tvb_get_guint8(tvb, offset);
1105 pitem = proto_tree_add_item(service_tree, hf_btavdtp_recovery_type, tvb, offset, 1, ENC_NA);
1106 proto_item_append_text(pitem, " (%s)", val_to_str_const(recovery_type, recovery_type_vals, "RFD"));
1110 maximum_recovery_window_size = tvb_get_guint8(tvb, offset);
1111 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1112 if (maximum_recovery_window_size == 0x00) {
1113 proto_item_append_text(pitem, " (Forbidden)");
1114 } else if (maximum_recovery_window_size >= 0x18) {
1115 proto_item_append_text(pitem, " (Undocumented)");
1120 maximum_number_of_media_packet_in_parity_code = tvb_get_guint8(tvb, offset);
1121 proto_tree_add_item(service_tree, hf_btavdtp_maximum_number_of_media_packet_in_parity_code, tvb, offset, 1, ENC_NA);
1122 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1123 if (maximum_number_of_media_packet_in_parity_code == 0x00) {
1124 proto_item_append_text(pitem, " (Forbidden)");
1125 } else if (maximum_number_of_media_packet_in_parity_code >= 0x18) {
1126 proto_item_append_text(pitem, " (Undocumented)");
1131 case SERVICE_CATEGORY_MEDIA_CODEC:
1132 if (configuration_length)
1133 *configuration_length = losc;
1134 if (configuration_offset)
1135 *configuration_offset = offset;
1137 media_type = tvb_get_guint8(tvb, offset) >> 4;
1138 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_media_type, tvb, offset, 1, ENC_NA);
1139 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_rfa , tvb, offset, 1, ENC_NA);
1143 media_codec_type = tvb_get_guint8(tvb, offset);
1145 *codec = media_codec_type;
1148 if (media_type == MEDIA_TYPE_AUDIO) {
1149 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_audio_type, tvb, offset, 1, ENC_NA);
1150 proto_item_append_text(service_item, " - Audio %s",
1151 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1152 col_append_fstr(pinfo->cinfo, COL_INFO, " - Audio %s",
1153 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1154 } else if (media_type == MEDIA_TYPE_VIDEO) {
1155 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_video_type, tvb, offset, 1, ENC_NA);
1156 proto_item_append_text(service_item, " - Video %s",
1157 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1158 col_append_fstr(pinfo->cinfo, COL_INFO, " - Video %s",
1159 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1161 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_unknown_type, tvb, offset, 1, ENC_NA);
1162 proto_item_append_text(service_item, " - Unknown 0x%02x", media_codec_type);
1163 col_append_fstr(pinfo->cinfo, COL_INFO, " - Unknown 0x%02x", media_codec_type);
1168 offset = dissect_codec(tvb, pinfo, service_item, service_tree,
1169 offset, losc, media_type, media_codec_type,
1170 vendor_id, vendor_codec);
1173 case SERVICE_CATEGORY_CONTENT_PROTECTION:
1174 proto_tree_add_item(service_tree, hf_btavdtp_content_protection_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1175 if (content_protection_type) {
1176 *content_protection_type = tvb_get_letohs(tvb, offset);
1178 proto_item_append_text(service_item, " - %s",
1179 val_to_str_const(tvb_get_letohs(tvb, offset), content_protection_type_vals, "unknown"));
1185 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1190 case SERVICE_CATEGORY_HEADER_COMPRESSION:
1191 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_backch, tvb, offset, 1, ENC_NA);
1192 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_media, tvb, offset, 1, ENC_NA);
1193 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_recovery, tvb, offset, 1, ENC_NA);
1194 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_rfa, tvb, offset, 1, ENC_NA);
1198 case SERVICE_CATEGORY_MULTIPLEXING:
1199 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_fragmentation, tvb, offset, 1, ENC_NA);
1200 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_rfa, tvb, offset, 1, ENC_NA);
1205 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Media Transport Session");
1206 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1208 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1209 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1212 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1213 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1219 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Reporting Transport Session");
1220 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1222 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1223 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1226 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1227 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1233 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Recovery Transport Session");
1234 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1236 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1237 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1240 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1241 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1247 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1253 pitem = proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1256 expert_add_info(pinfo, pitem, &ei_btavdtp_unexpected_losc_data);
1264 dissect_seid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
1265 gint seid_side, gint i_item, guint32 *sep_seid,
1266 guint32 interface_id, guint32 adapter_id, guint32 chandle,
1267 guint32 frame_number)
1270 proto_tree *seid_tree = NULL;
1271 proto_item *seid_item = NULL;
1274 seid = tvb_get_guint8(tvb, offset) >> 2;
1279 if (seid_side == SEID_ACP) {
1280 direction = pinfo->p2p_dir;
1281 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_seid_item, tvb, offset, 1,
1282 "ACP SEID [%u - %s %s]", seid,
1283 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1284 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1285 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1286 proto_tree_add_item(seid_tree, hf_btavdtp_acp_seid, tvb, offset, 1, ENC_NA);
1287 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1289 col_append_fstr(pinfo->cinfo, COL_INFO, " - ACP SEID [%u - %s %s]",
1290 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1291 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1293 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
1294 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_int_seid_item, tvb, offset, 1,
1295 "INT SEID [%u - %s %s]", seid,
1296 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1297 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1298 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1299 proto_tree_add_item(seid_tree, hf_btavdtp_int_seid, tvb, offset, 1, ENC_NA);
1300 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1302 col_append_fstr(pinfo->cinfo, COL_INFO, " - INT SEID [%u - %s %s]",
1303 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1304 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1307 proto_tree_add_item(seid_tree, hf_btavdtp_rfa_seid, tvb, offset, 1, ENC_NA);
1315 dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1318 proto_tree *btavdtp_tree = NULL;
1319 proto_tree *signal_tree = NULL;
1320 proto_item *signal_item = NULL;
1321 btl2cap_data_t *l2cap_data;
1324 gint packet_type = 0;
1325 gint message_type = 0;
1328 wmem_tree_t *subtree;
1329 wmem_tree_key_t key[8];
1330 channels_info_t *channels_info;
1331 guint32 interface_id;
1337 guint32 frame_number;
1342 gint content_protection_type = 0;
1343 guint32 configuration_offset;
1344 guint8 configuration_length;
1346 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP");
1348 direction = pinfo->p2p_dir;
1349 switch (direction) {
1351 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
1355 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
1358 col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
1362 l2cap_data = (btl2cap_data_t *) data;
1363 DISSECTOR_ASSERT(l2cap_data);
1365 interface_id = l2cap_data->interface_id;
1366 adapter_id = l2cap_data->adapter_id;
1367 chandle = l2cap_data->chandle;
1368 psm = l2cap_data->psm;
1369 cid = l2cap_data->cid;
1370 frame_number = pinfo->num;
1373 key[0].key = &interface_id;
1375 key[1].key = &adapter_id;
1377 key[2].key = &chandle;
1383 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(channels, key);
1384 channels_info = (subtree) ? (channels_info_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1385 if (!(channels_info &&
1386 ((*channels_info->adapter_disconnect_in_frame >= pinfo->num &&
1387 *channels_info->hci_disconnect_in_frame >= pinfo->num &&
1388 *channels_info->l2cap_disconnect_in_frame >= pinfo->num &&
1389 channels_info->disconnect_in_frame >= pinfo->num) ||
1390 (*channels_info->adapter_disconnect_in_frame == 0 ||
1391 *channels_info->hci_disconnect_in_frame == 0 ||
1392 *channels_info->l2cap_disconnect_in_frame == 0 ||
1393 channels_info->disconnect_in_frame == 0)))) {
1395 channels_info = (channels_info_t *) wmem_new (wmem_file_scope(), channels_info_t);
1396 channels_info->control_local_cid = l2cap_data->local_cid;
1397 channels_info->control_remote_cid = l2cap_data->remote_cid;
1398 channels_info->media_local_cid = BTL2CAP_UNKNOWN_CID;
1399 channels_info->media_remote_cid = BTL2CAP_UNKNOWN_CID;
1400 channels_info->disconnect_in_frame = max_disconnect_in_frame;
1401 channels_info->l2cap_disconnect_in_frame = l2cap_data->disconnect_in_frame;
1402 channels_info->hci_disconnect_in_frame = l2cap_data->hci_disconnect_in_frame;
1403 channels_info->adapter_disconnect_in_frame = l2cap_data->adapter_disconnect_in_frame;
1404 channels_info->sep = NULL;
1406 if (!pinfo->fd->flags.visited || (
1407 *channels_info->adapter_disconnect_in_frame == 0 ||
1408 *channels_info->hci_disconnect_in_frame == 0 ||
1409 *channels_info->l2cap_disconnect_in_frame == 0 ||
1410 channels_info->disconnect_in_frame == 0)) {
1412 key[4].key = &frame_number;
1416 channels_info->stream_numbers = wmem_tree_new(wmem_file_scope());
1418 if (*channels_info->adapter_disconnect_in_frame > 0 &&
1419 *channels_info->hci_disconnect_in_frame > 0 &&
1420 *channels_info->l2cap_disconnect_in_frame > 0 &&
1421 channels_info->disconnect_in_frame > 0) {
1422 wmem_tree_insert32_array(channels, key, channels_info);
1425 channels_info->stream_numbers = NULL;
1429 if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1430 l2cap_data->remote_cid == channels_info->control_remote_cid) &&
1431 (channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID ||
1432 (l2cap_data->local_cid == channels_info->media_local_cid &&
1433 l2cap_data->remote_cid == channels_info->media_remote_cid))) {
1435 if (!pinfo->fd->flags.visited && channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID) {
1436 channels_info->media_local_cid = l2cap_data->local_cid;
1437 channels_info->media_remote_cid = l2cap_data->remote_cid;
1441 if (!channels_info->sep) {
1442 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1443 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1445 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1446 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1448 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream ACP SEID [%u - %s %s]",
1449 channels_info->sep->seid, get_sep_media_type(
1450 interface_id, adapter_id, chandle, direction,
1451 channels_info->sep->seid,
1453 get_sep_type(interface_id, adapter_id, chandle, direction,
1454 channels_info->sep->seid,
1457 if (channels_info->sep->media_type == MEDIA_TYPE_AUDIO) {
1458 sep_data_t sep_data;
1459 media_stream_number_value_t *media_stream_number_value;
1460 media_packet_info_t *previous_media_packet_info;
1461 media_packet_info_t *current_media_packet_info;
1462 nstime_t first_abs_ts;
1463 gdouble cumulative_frame_duration;
1464 gdouble avrcp_song_position = -1.0;
1465 btavrcp_song_position_data_t *song_position_data;
1467 sep_data.codec = channels_info->sep->codec;
1468 sep_data.vendor_id = channels_info->sep->vendor_id;
1469 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1470 sep_data.acp_seid = channels_info->sep->seid;
1471 sep_data.int_seid = channels_info->sep->int_seid;
1472 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1473 sep_data.stream_start_in_frame = 0;
1474 sep_data.stream_end_in_frame = 0;
1475 sep_data.configuration_length = channels_info->sep->configuration_length;
1476 sep_data.configuration = channels_info->sep->configuration;
1478 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1479 if (media_stream_number_value) {
1480 sep_data.stream_number = media_stream_number_value->stream_number;
1481 if (media_stream_number_value->stream_start_in_frame == 0)
1482 media_stream_number_value->stream_start_in_frame = pinfo->num;
1484 if (!pinfo->fd->flags.visited)
1485 media_stream_number_value->stream_end_in_frame = pinfo->num;
1487 sep_data.stream_start_in_frame = media_stream_number_value->stream_start_in_frame;
1488 sep_data.stream_end_in_frame = media_stream_number_value->stream_end_in_frame;
1490 sep_data.stream_number = 1;
1494 key[0].key = &interface_id;
1496 key[1].key = &adapter_id;
1500 key[4].key = &direction;
1507 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(btavrcp_song_positions, key);
1508 song_position_data = (subtree) ? (btavrcp_song_position_data_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1509 if (song_position_data && (song_position_data->used_in_frame == 0 ||
1510 song_position_data->used_in_frame == frame_number)) {
1511 avrcp_song_position = song_position_data->song_position;
1512 if (!pinfo->fd->flags.visited)
1513 song_position_data->used_in_frame = frame_number;
1517 key[2].key = &chandle;
1519 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1520 previous_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32_le(subtree, frame_number - 1) : NULL;
1521 if (previous_media_packet_info && previous_media_packet_info->stream_number == sep_data.stream_number ) {
1522 sep_data.previous_media_packet_info = previous_media_packet_info;
1523 first_abs_ts = previous_media_packet_info->first_abs_ts;
1524 cumulative_frame_duration = previous_media_packet_info->cumulative_frame_duration;
1525 if (avrcp_song_position == -1.0)
1526 avrcp_song_position = previous_media_packet_info->avrcp_song_position;
1528 previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1530 if (avrcp_song_position == -1.0)
1531 avrcp_song_position = 0.0;
1532 first_abs_ts = pinfo->abs_ts;
1533 cumulative_frame_duration = 0.0;
1534 sep_data.previous_media_packet_info = (media_packet_info_t *) wmem_new(wmem_epan_scope(), media_packet_info_t);
1535 sep_data.previous_media_packet_info->abs_ts = pinfo->abs_ts;
1536 sep_data.previous_media_packet_info->first_abs_ts = first_abs_ts;
1537 sep_data.previous_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1538 sep_data.previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1539 sep_data.previous_media_packet_info->stream_number = sep_data.stream_number;
1542 if (!pinfo->fd->flags.visited) {
1544 key[5].key = &frame_number;
1548 if (avrcp_song_position == -1.0)
1549 avrcp_song_position = 0.0;
1551 current_media_packet_info = wmem_new(wmem_file_scope(), media_packet_info_t);
1552 current_media_packet_info->abs_ts = pinfo->abs_ts;
1553 current_media_packet_info->first_abs_ts = first_abs_ts;
1554 current_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1555 current_media_packet_info->avrcp_song_position = avrcp_song_position;
1556 current_media_packet_info->stream_number = sep_data.stream_number;
1558 wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info);
1564 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1565 current_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32(subtree, frame_number) : NULL;
1566 if (current_media_packet_info)
1567 sep_data.current_media_packet_info = current_media_packet_info;
1569 sep_data.current_media_packet_info = NULL;
1571 next_tvb = tvb_new_subset_remaining(tvb, offset);
1572 call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data);
1573 } else if (channels_info->sep->media_type == MEDIA_TYPE_VIDEO) {
1574 sep_data_t sep_data;
1575 media_stream_number_value_t *media_stream_number_value;
1577 sep_data.codec = channels_info->sep->codec;
1578 sep_data.vendor_id = channels_info->sep->vendor_id;
1579 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1580 sep_data.acp_seid = channels_info->sep->seid;
1581 sep_data.int_seid = channels_info->sep->int_seid;
1582 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1583 sep_data.stream_start_in_frame = 0;
1584 sep_data.stream_end_in_frame = 0;
1585 sep_data.configuration_length = channels_info->sep->configuration_length;
1586 sep_data.configuration = channels_info->sep->configuration;
1588 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1589 if (media_stream_number_value) {
1590 sep_data.stream_number = media_stream_number_value->stream_number;
1592 sep_data.stream_number = 1;
1595 next_tvb = tvb_new_subset_remaining(tvb, offset);
1596 call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data);
1598 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1599 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1601 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1602 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1606 return tvb_reported_length(tvb);
1607 } else if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1608 l2cap_data->remote_cid == channels_info->control_remote_cid)) {
1609 /* Unknown Stream Channel */
1610 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1611 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1613 col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown channel stream on cid=0x%04x", l2cap_data->cid);
1614 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1615 return tvb_reported_length(tvb);
1618 /* Signaling Channel */
1619 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1620 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1622 /* AVDTP signaling*/
1623 message_type = (tvb_get_guint8(tvb, offset) & AVDTP_MESSAGE_TYPE_MASK);
1624 packet_type = (tvb_get_guint8(tvb, offset) & AVDTP_PACKET_TYPE_MASK) >> 2;
1626 signal_item = proto_tree_add_item(btavdtp_tree, hf_btavdtp_signal, tvb, offset,
1627 (packet_type == PACKET_TYPE_START) ? 3 : 2, ENC_NA);
1628 signal_tree = proto_item_add_subtree(signal_item, ett_btavdtp_sep);
1630 proto_tree_add_item(signal_tree, hf_btavdtp_transaction, tvb, offset, 1, ENC_NA);
1631 proto_tree_add_item(signal_tree, hf_btavdtp_packet_type, tvb, offset, 1, ENC_NA);
1632 proto_tree_add_item(signal_tree, hf_btavdtp_message_type, tvb, offset, 1, ENC_NA);
1634 if (packet_type == PACKET_TYPE_START) {
1636 proto_tree_add_item(signal_tree, hf_btavdtp_number_of_signal_packets, tvb, offset, 1, ENC_NA);
1639 if (packet_type == PACKET_TYPE_CONTINUE || packet_type == PACKET_TYPE_END) goto LABEL_data;
1642 proto_tree_add_item(signal_tree, hf_btavdtp_rfa0, tvb, offset, 1, ENC_NA);
1643 proto_tree_add_item(signal_tree, hf_btavdtp_signal_id, tvb, offset, 1, ENC_NA);
1645 signal_id = tvb_get_guint8(tvb, offset) & AVDTP_SIGNAL_ID_MASK;
1646 proto_item_append_text(signal_item, ": %s (%s)",
1647 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"),
1648 val_to_str_const(message_type, message_type_vals, "Unknown message type"));
1650 col_append_fstr(pinfo->cinfo, COL_INFO, "%s - %s",
1651 val_to_str_const(message_type, message_type_vals, "Unknown message type"),
1652 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"));
1655 if (message_type != MESSAGE_TYPE_GENERAL_REJECT) switch (signal_id) {
1656 case SIGNAL_ID_DISCOVER:
1657 if (message_type == MESSAGE_TYPE_COMMAND) break;
1658 if (message_type == MESSAGE_TYPE_REJECT) {
1659 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1663 offset = dissect_sep(tvb, pinfo, btavdtp_tree, offset,
1664 interface_id, adapter_id, chandle);
1666 case SIGNAL_ID_GET_CAPABILITIES:
1667 case SIGNAL_ID_GET_ALL_CAPABILITIES:
1668 if (message_type == MESSAGE_TYPE_COMMAND) {
1669 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1670 SEID_ACP, 0, NULL, interface_id,
1671 adapter_id, chandle, frame_number);
1674 if (message_type == MESSAGE_TYPE_REJECT) {
1675 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1679 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1681 case SIGNAL_ID_SET_CONFIGURATION:
1682 if (message_type == MESSAGE_TYPE_COMMAND) {
1685 guint16 vendor_codec;
1686 guint32 reverse_direction;
1688 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1689 SEID_ACP, 0, &seid, interface_id,
1690 adapter_id, chandle, frame_number);
1691 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1692 SEID_INT, 0, &int_seid, interface_id,
1693 adapter_id, chandle, frame_number);
1694 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1695 &codec, &content_protection_type, &vendor_id,
1696 &vendor_codec, &configuration_offset, &configuration_length);
1698 if (!pinfo->fd->flags.visited) {
1700 key[0].key = &interface_id;
1702 key[1].key = &adapter_id;
1704 key[2].key = &chandle;
1706 key[3].key = &direction;
1712 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1713 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1716 sep->vendor_id = vendor_id;
1717 sep->vendor_codec = vendor_codec;
1718 sep->content_protection_type = content_protection_type;
1719 sep->int_seid = int_seid;
1720 if (configuration_length > 0) {
1721 sep->configuration_length = configuration_length;
1722 sep->configuration = (guint8 *) tvb_memdup(wmem_file_scope(),
1723 tvb, configuration_offset, configuration_length);
1726 if (direction == P2P_DIR_SENT)
1727 reverse_direction = P2P_DIR_RECV;
1728 else if (direction == P2P_DIR_RECV)
1729 reverse_direction = P2P_DIR_SENT;
1731 reverse_direction = P2P_DIR_UNKNOWN;
1734 key[3].key = &reverse_direction;
1736 key[4].key = &int_seid;
1738 key[5].key = &frame_number;
1742 wmem_tree_insert32_array(sep_list, key, sep);
1749 if (message_type == MESSAGE_TYPE_REJECT) {
1750 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1753 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1758 case SIGNAL_ID_GET_CONFIGURATION:
1759 if (message_type == MESSAGE_TYPE_COMMAND) {
1760 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1761 SEID_ACP, 0, NULL, interface_id,
1762 adapter_id, chandle, frame_number);
1765 if (message_type == MESSAGE_TYPE_REJECT) {
1766 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1770 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1772 case SIGNAL_ID_RECONFIGURE:
1773 if (message_type == MESSAGE_TYPE_COMMAND) {
1775 guint16 vendor_codec;
1777 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1778 SEID_ACP, 0, &seid, interface_id,
1779 adapter_id, chandle, frame_number);
1780 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1781 &codec, &content_protection_type, &vendor_id,
1782 &vendor_codec, &configuration_offset, &configuration_length);
1784 if (!pinfo->fd->flags.visited) {
1786 key[0].key = &interface_id;
1788 key[1].key = &adapter_id;
1790 key[2].key = &chandle;
1792 key[3].key = &direction;
1798 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1799 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1802 sep->vendor_id = vendor_id;
1803 sep->vendor_codec = vendor_codec;
1804 sep->content_protection_type = content_protection_type;
1805 if (configuration_length > 0) {
1806 sep->configuration_length = configuration_length;
1807 sep->configuration = (guint8 *) tvb_memdup(wmem_file_scope(),
1808 tvb, configuration_offset, configuration_length);
1815 if (message_type == MESSAGE_TYPE_REJECT) {
1816 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1819 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1824 case SIGNAL_ID_OPEN:
1825 if (message_type == MESSAGE_TYPE_COMMAND) {
1826 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1827 SEID_ACP, 0, &seid, interface_id,
1828 adapter_id, chandle, frame_number);
1830 if (!pinfo->fd->flags.visited) {
1832 key[0].key = &interface_id;
1834 key[1].key = &adapter_id;
1836 key[2].key = &chandle;
1838 key[3].key = &direction;
1844 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1845 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1847 sep->state = SEP_STATE_OPEN;
1850 key[3].key = &frame_number;
1854 wmem_tree_insert32_array(sep_open, key, sep);
1859 if (message_type == MESSAGE_TYPE_REJECT) {
1860 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1864 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->flags.visited) {
1867 key[0].key = &interface_id;
1869 key[1].key = &adapter_id;
1871 key[2].key = &chandle;
1875 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_open, key);
1876 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1877 if (sep && sep->state == SEP_STATE_OPEN) {
1878 sep->state = SEP_STATE_IN_USE;
1879 channels_info->sep = sep;
1883 case SIGNAL_ID_START:
1884 if (message_type == MESSAGE_TYPE_COMMAND) {
1886 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1887 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1888 SEID_ACP, i_sep, NULL,
1889 interface_id, adapter_id, chandle, frame_number);
1894 if (message_type == MESSAGE_TYPE_REJECT) {
1895 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1897 interface_id, adapter_id, chandle, frame_number);
1898 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1903 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->flags.visited) {
1904 media_stream_number_value_t *media_stream_number_value;
1905 guint32 stream_number = 0;
1907 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1908 #if RTP_PLAYER_WORKAROUND == TRUE
1910 media_stream_number_value_t *file_scope_stream_number_value;
1912 if (media_stream_number_value) {
1913 stream_number = media_stream_number_value->stream_number;
1915 file_scope_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(file_scope_stream_number, frame_number - 1);
1916 if (file_scope_stream_number_value)
1917 stream_number = file_scope_stream_number_value->stream_number + 1;
1922 file_scope_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
1923 file_scope_stream_number_value->stream_number = stream_number;
1924 wmem_tree_insert32(file_scope_stream_number, frame_number, file_scope_stream_number_value);
1927 if (media_stream_number_value)
1928 stream_number = media_stream_number_value->stream_number;
1933 media_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
1934 media_stream_number_value->stream_number = stream_number + 1;
1935 media_stream_number_value->stream_start_in_frame = 0;
1936 media_stream_number_value->stream_end_in_frame = 0;
1938 wmem_tree_insert32(channels_info->stream_numbers, frame_number, media_stream_number_value);
1941 case SIGNAL_ID_CLOSE:
1942 if (message_type == MESSAGE_TYPE_COMMAND) {
1943 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1944 SEID_ACP, 0, NULL, interface_id,
1945 adapter_id, chandle, frame_number);
1948 if (message_type == MESSAGE_TYPE_REJECT) {
1949 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1953 if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
1954 channels_info->disconnect_in_frame > pinfo->num) {
1955 channels_info->disconnect_in_frame = pinfo->num;
1958 case SIGNAL_ID_SUSPEND:
1959 if (message_type == MESSAGE_TYPE_COMMAND) {
1961 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1962 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1963 SEID_ACP, i_sep, NULL,
1964 interface_id, adapter_id, chandle, frame_number);
1969 if (message_type == MESSAGE_TYPE_REJECT) {
1970 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1971 SEID_ACP, 0, NULL, interface_id,
1972 adapter_id, chandle, frame_number);
1973 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1978 case SIGNAL_ID_ABORT:
1979 if (message_type == MESSAGE_TYPE_COMMAND) {
1980 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1981 SEID_ACP, 0, NULL, interface_id,
1982 adapter_id, chandle, frame_number);
1985 if (message_type == MESSAGE_TYPE_REJECT) {
1986 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1990 if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
1991 channels_info->disconnect_in_frame > pinfo->num) {
1992 channels_info->disconnect_in_frame = pinfo->num;
1995 case SIGNAL_ID_SECURITY_CONTROL:
1996 if (message_type == MESSAGE_TYPE_COMMAND) {
1997 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1998 SEID_ACP, 0, NULL, interface_id,
1999 adapter_id, chandle, frame_number);
2000 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2001 offset += tvb_reported_length_remaining(tvb, offset);
2004 if (message_type == MESSAGE_TYPE_REJECT) {
2005 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2010 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2011 offset += tvb_reported_length_remaining(tvb, offset);
2013 case SIGNAL_ID_DELAY_REPORT:
2014 if (message_type == MESSAGE_TYPE_COMMAND) {
2016 delay = tvb_get_ntohs(tvb, offset + 1);
2017 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u.%u ms)", delay/10, delay%10);
2018 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2020 interface_id, adapter_id, chandle, frame_number);
2021 pitem = proto_tree_add_item(btavdtp_tree, hf_btavdtp_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
2022 proto_item_append_text(pitem, " (1/10 ms)");
2026 if (message_type == MESSAGE_TYPE_REJECT) {
2027 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2036 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2037 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2045 proto_register_btavdtp(void)
2049 static hf_register_info hf[] = {
2050 { &hf_btavdtp_signal,
2051 { "Signal", "btavdtp.signal",
2052 FT_NONE, BASE_NONE, NULL, 0x00,
2055 { &hf_btavdtp_message_type,
2056 { "Message Type", "btavdtp.message_type",
2057 FT_UINT8, BASE_HEX, VALS(message_type_vals), AVDTP_MESSAGE_TYPE_MASK,
2060 { &hf_btavdtp_packet_type,
2061 { "Packet Type", "btavdtp.packet_type",
2062 FT_UINT8, BASE_HEX, VALS(packet_type_vals), AVDTP_PACKET_TYPE_MASK,
2065 { &hf_btavdtp_transaction,
2066 { "Transaction", "btavdtp.transaction",
2067 FT_UINT8, BASE_HEX, NULL, AVDTP_TRANSACTION_MASK,
2070 { &hf_btavdtp_signal_id,
2071 { "Signal", "btavdtp.signal_id",
2072 FT_UINT8, BASE_HEX, VALS(signal_id_vals), AVDTP_SIGNAL_ID_MASK,
2076 { "RFA", "btavdtp.rfa0",
2077 FT_UINT8, BASE_HEX, NULL, AVDTP_RFA0_MASK,
2080 { &hf_btavdtp_number_of_signal_packets,
2081 { "Number of signal packets", "btavdtp.num_signal_packets",
2082 FT_UINT8, BASE_DEC, NULL, 0,
2085 { &hf_btavdtp_error_code,
2086 { "Error Code", "btavdtp.error_code",
2087 FT_UINT8, BASE_HEX, VALS(error_code_vals), 0x00,
2090 { &hf_btavdtp_sep_seid,
2091 { "SEID", "btavdtp.sep_seid",
2092 FT_UINT8, BASE_DEC, NULL, 0xFC,
2095 { &hf_btavdtp_sep_inuse,
2096 { "In Use", "btavdtp.sep_inuse",
2097 FT_UINT8, BASE_HEX, VALS(true_false), 0x02,
2100 { &hf_btavdtp_sep_rfa0,
2101 { "RFA0", "btavdtp.sep_rfa0",
2102 FT_UINT8, BASE_HEX, NULL, 0x01,
2105 { &hf_btavdtp_sep_media_type,
2106 { "Media Type", "btavdtp.sep_media_type",
2107 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2110 { &hf_btavdtp_sep_type,
2111 { "Type", "btavdtp.sep_type",
2112 FT_UINT8, BASE_HEX, VALS(sep_type_vals), 0x08,
2115 { &hf_btavdtp_sep_rfa1,
2116 { "RFA1", "btavdtp.sep_rfa1",
2117 FT_UINT8, BASE_HEX, NULL, 0x07,
2120 { &hf_btavdtp_acp_sep,
2121 { "ACP SEP", "btavdtp.acp_sep",
2122 FT_NONE, BASE_NONE, NULL, 0x00,
2125 { &hf_btavdtp_acp_seid_item,
2126 { "ACP SEID", "btavdtp.acp_seid_item",
2127 FT_NONE, BASE_NONE, NULL, 0x00,
2130 { &hf_btavdtp_int_seid_item,
2131 { "INT SEID", "btavdtp.int_seid_item",
2132 FT_NONE, BASE_NONE, NULL, 0x00,
2135 { &hf_btavdtp_acp_seid,
2136 { "ACP SEID", "btavdtp.acp_seid",
2137 FT_UINT8, BASE_DEC, NULL, 0xFC,
2140 { &hf_btavdtp_int_seid,
2141 { "INT SEID", "btavdtp.int_seid",
2142 FT_UINT8, BASE_DEC, NULL, 0xFC,
2145 { &hf_btavdtp_rfa_seid,
2146 { "RFA", "btavdtp.rfa_seid",
2147 FT_UINT8, BASE_HEX, NULL, 0x03,
2150 { &hf_btavdtp_service_category,
2151 { "Service Category", "btavdtp.service_category",
2152 FT_UINT8, BASE_HEX, VALS(service_category_vals), 0x00,
2155 { &hf_btavdtp_length_of_service_category,
2156 { "Length of Service Category", "btavdtp.length_of_service_category",
2157 FT_UINT8, BASE_HEX, NULL, 0x00,
2160 { &hf_btavdtp_delay,
2161 { "Delay", "btavdtp.delay",
2162 FT_UINT16, BASE_DEC, NULL, 0x00,
2165 { &hf_btavdtp_recovery_type,
2166 { "Service Category", "btavdtp.recovery_type",
2167 FT_UINT8, BASE_HEX, VALS(recovery_type_vals), 0x00,
2170 { &hf_btavdtp_maximum_recovery_window_size,
2171 { "Service Category", "btavdtp.maximum_recovery_window_size",
2172 FT_UINT8, BASE_HEX, NULL, 0x00,
2175 { &hf_btavdtp_maximum_number_of_media_packet_in_parity_code,
2176 { "Service Category", "btavdtp.maximum_number_of_media_packet_in_parity_code",
2177 FT_UINT8, BASE_HEX, NULL, 0x00,
2180 { &hf_btavdtp_multiplexing_fragmentation,
2181 { "Fragmentation", "btavdtp.multiplexing_fragmentation",
2182 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2185 { &hf_btavdtp_multiplexing_rfa,
2186 { "RFA", "btavdtp.multiplexing_rfa",
2187 FT_UINT8, BASE_HEX, NULL, 0x7F,
2190 { &hf_btavdtp_multiplexing_tsid,
2191 { "TSID", "btavdtp.multiplexing_tsid",
2192 FT_UINT8, BASE_HEX, VALS(multiplexing_tsid_vals), 0xF8,
2195 { &hf_btavdtp_multiplexing_tcid,
2196 { "TCID", "btavdtp.multiplexing_tcid",
2197 FT_UINT8, BASE_HEX, VALS(multiplexing_tcid_vals), 0xF8,
2200 { &hf_btavdtp_multiplexing_entry_rfa,
2201 { "RFA", "btavdtp.multiplexing_entry_rfa",
2202 FT_UINT8, BASE_HEX, NULL, 0x07,
2205 { &hf_btavdtp_header_compression_backch,
2206 { "BackCh", "btavdtp.header_compression_backch",
2207 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2210 { &hf_btavdtp_header_compression_media,
2211 { "Media", "btavdtp.header_compression_media",
2212 FT_UINT8, BASE_HEX, VALS(true_false), 0x40,
2215 { &hf_btavdtp_header_compression_recovery,
2216 { "Recovery", "btavdtp.header_compression_recovery",
2217 FT_UINT8, BASE_HEX, VALS(true_false), 0x20,
2220 { &hf_btavdtp_header_compression_rfa,
2221 { "RFA", "btavdtp.header_compression_rfa",
2222 FT_UINT8, BASE_HEX, NULL, 0x1f,
2225 { &hf_btavdtp_content_protection_type,
2226 { "Type", "btavdtp.content_protection_type",
2227 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
2230 { &hf_btavdtp_media_codec_media_type,
2231 { "Media Type", "btavdtp.media_codec_media_type",
2232 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2235 { &hf_btavdtp_media_codec_rfa,
2236 { "RFA", "btavdtp.media_codec_rfa",
2237 FT_UINT8, BASE_HEX, NULL, 0x0F,
2240 { &hf_btavdtp_media_codec_audio_type,
2241 { "Media Codec Audio Type", "btavdtp.media_codec_audio_type",
2242 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
2245 { &hf_btavdtp_media_codec_video_type,
2246 { "Media Codec Video Type", "btavdtp.media_codec_video_type",
2247 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
2250 { &hf_btavdtp_media_codec_unknown_type,
2251 { "Media Codec Unknown Type", "btavdtp.media_codec_unknown_type",
2252 FT_UINT8, BASE_HEX, NULL, 0x00,
2255 { &hf_btavdtp_sbc_sampling_frequency_16000,
2256 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2257 FT_BOOLEAN, 8, NULL, 0x80,
2260 { &hf_btavdtp_sbc_sampling_frequency_32000,
2261 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2262 FT_BOOLEAN, 8, NULL, 0x40,
2265 { &hf_btavdtp_sbc_sampling_frequency_44100,
2266 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2267 FT_BOOLEAN, 8, NULL, 0x20,
2270 { &hf_btavdtp_sbc_sampling_frequency_48000,
2271 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2272 FT_BOOLEAN, 8, NULL, 0x10,
2275 { &hf_btavdtp_sbc_channel_mode_mono,
2276 { "Channel Mode Mono", "btavdtp.codec.sbc.channel_mode.mono",
2277 FT_BOOLEAN, 8, NULL, 0x08,
2280 { &hf_btavdtp_sbc_channel_mode_dual_channel,
2281 { "Channel Mode Dual Channel", "btavdtp.codec.sbc.channel_mode.dual_channel",
2282 FT_BOOLEAN, 8, NULL, 0x04,
2285 { &hf_btavdtp_sbc_channel_mode_stereo,
2286 { "Channel Mode Stereo", "btavdtp.codec.sbc.channel_mode.stereo",
2287 FT_BOOLEAN, 8, NULL, 0x02,
2290 { &hf_btavdtp_sbc_channel_mode_joint_stereo,
2291 { "Channel Mode Joint Stereo", "btavdtp.codec.sbc.channel_mode.joint_stereo",
2292 FT_BOOLEAN, 8, NULL, 0x01,
2295 { &hf_btavdtp_sbc_block_4,
2296 { "Block Length 4", "btavdtp.codec.sbc.block.4",
2297 FT_BOOLEAN, 8, NULL, 0x80,
2300 { &hf_btavdtp_sbc_block_8,
2301 { "Block Length 8", "btavdtp.codec.sbc.block.8",
2302 FT_BOOLEAN, 8, NULL, 0x40,
2305 { &hf_btavdtp_sbc_block_12,
2306 { "Block Length 12", "btavdtp.codec.sbc.block.12",
2307 FT_BOOLEAN, 8, NULL, 0x20,
2310 { &hf_btavdtp_sbc_block_16,
2311 { "Block Length 16", "btavdtp.codec.sbc.block.16",
2312 FT_BOOLEAN, 8, NULL, 0x10,
2315 { &hf_btavdtp_sbc_subbands_4,
2316 { "Subbands 4", "btavdtp.codec.sbc.subbands.4",
2317 FT_BOOLEAN, 8, NULL, 0x08,
2320 { &hf_btavdtp_sbc_subbands_8,
2321 { "Subbands 8", "btavdtp.codec.sbc.subbands.8",
2322 FT_BOOLEAN, 8, NULL, 0x04,
2325 { &hf_btavdtp_sbc_allocation_method_snr,
2326 { "Allocation Method SNR", "btavdtp.codec.sbc.allocation_method.snr",
2327 FT_BOOLEAN, 8, NULL, 0x02,
2330 { &hf_btavdtp_sbc_allocation_method_loudness,
2331 { "Allocation Method Loudness", "btavdtp.codec.sbc.allocation_method.loudness",
2332 FT_BOOLEAN, 8, NULL, 0x01,
2335 { &hf_btavdtp_sbc_min_bitpool,
2336 { "Minimum Bitpool", "btavdtp.codec.sbc.minimum_bitpool",
2337 FT_UINT8, BASE_DEC, NULL, 0x00,
2340 { &hf_btavdtp_sbc_max_bitpool,
2341 { "Maximum Bitpool", "btavdtp.codec.sbc.maximum_bitpool",
2342 FT_UINT8, BASE_DEC, NULL, 0x00,
2345 { &hf_btavdtp_mpeg12_layer_1,
2346 { "MP1", "btavdtp.codec.mpeg12.layer_1",
2347 FT_BOOLEAN, 8, NULL, 0x80,
2348 "MPEG Layer 1", HFILL }
2350 { &hf_btavdtp_mpeg12_layer_2,
2351 { "MP2", "btavdtp.codec.mpeg12.layer_2",
2352 FT_BOOLEAN, 8, NULL, 0x40,
2353 "MPEG Layer 2", HFILL }
2355 { &hf_btavdtp_mpeg12_layer_3,
2356 { "MP3", "btavdtp.codec.mpeg12.layer_3",
2357 FT_BOOLEAN, 8, NULL, 0x20,
2358 "MPEG Layer 3", HFILL }
2360 { &hf_btavdtp_mpeg12_crc_protection,
2361 { "CRC Protection", "btavdtp.codec.mpeg12.crc_protection",
2362 FT_BOOLEAN, 8, NULL, 0x10,
2365 { &hf_btavdtp_mpeg12_channel_mode_mono,
2366 { "Channel Mode Mono", "btavdtp.codec.mpeg12.channel_mode.mono",
2367 FT_BOOLEAN, 8, NULL, 0x08,
2370 { &hf_btavdtp_mpeg12_channel_mode_dual_channel,
2371 { "Channel Mode Dual Channel", "btavdtp.codec.mpeg12.channel_mode.dual_channel",
2372 FT_BOOLEAN, 8, NULL, 0x04,
2375 { &hf_btavdtp_mpeg12_channel_mode_stereo,
2376 { "Channel Mode Stereo", "btavdtp.codec.mpeg12.channel_mode.stereo",
2377 FT_BOOLEAN, 8, NULL, 0x02,
2380 { &hf_btavdtp_mpeg12_channel_mode_joint_stereo,
2381 { "Channel Mode Joint Stereo", "btavdtp.codec.mpeg12.channel_mode.joint_stereo",
2382 FT_BOOLEAN, 8, NULL, 0x01,
2385 { &hf_btavdtp_mpeg12_rfa,
2386 { "RFA", "btavdtp.codec.mpeg12.rfa",
2387 FT_BOOLEAN, 8, NULL, 0x80,
2390 { &hf_btavdtp_mpeg12_mpf_2,
2391 { "Media Payload Format 2", "btavdtp.codec.mpeg12.mpf_2",
2392 FT_BOOLEAN, 8, NULL, 0x40,
2395 { &hf_btavdtp_mpeg12_sampling_frequency_16000,
2396 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2397 FT_BOOLEAN, 8, NULL, 0x20,
2400 { &hf_btavdtp_mpeg12_sampling_frequency_22050,
2401 { "Sampling Frequency 22050 Hz", "btavdtp.codec.sbc.sampling_frequency.22050",
2402 FT_BOOLEAN, 8, NULL, 0x10,
2405 { &hf_btavdtp_mpeg12_sampling_frequency_24000,
2406 { "Sampling Frequency 24000 Hz", "btavdtp.codec.sbc.sampling_frequency.24000",
2407 FT_BOOLEAN, 8, NULL, 0x08,
2410 { &hf_btavdtp_mpeg12_sampling_frequency_32000,
2411 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2412 FT_BOOLEAN, 8, NULL, 0x04,
2415 { &hf_btavdtp_mpeg12_sampling_frequency_44100,
2416 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2417 FT_BOOLEAN, 8, NULL, 0x02,
2420 { &hf_btavdtp_mpeg12_sampling_frequency_48000,
2421 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2422 FT_BOOLEAN, 8, NULL, 0x01,
2425 { &hf_btavdtp_mpeg12_vbr_supported,
2426 { "VBR Supported", "btavdtp.codec.mpeg12.vbr",
2427 FT_BOOLEAN, 16, NULL, 0x8000,
2430 { &hf_btavdtp_mpeg12_bit_rate,
2431 { "Bit Rate", "btavdtp.codec.mpeg12.bit_rate",
2432 FT_UINT16, BASE_HEX, NULL, 0x7FFF,
2435 { &hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc,
2436 { "MPEG2 AAC LC", "btavdtp.codec.mpeg24.object_type.mpeg2_aac_lc",
2437 FT_BOOLEAN, 8, NULL, 0x80,
2440 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc,
2441 { "MPEG4 AAC LC", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_lc",
2442 FT_BOOLEAN, 8, NULL, 0x40,
2445 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp,
2446 { "MPEG4 AAC LTP", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_ltp",
2447 FT_BOOLEAN, 8, NULL, 0x20,
2450 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable,
2451 { "MPEG4 AAC Scalable", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_scalable",
2452 FT_BOOLEAN, 8, NULL, 0x10,
2455 { &hf_btavdtp_mpeg24_object_type_rfa,
2456 { "RFA", "btavdtp.codec.mpeg24.object_type.rfa",
2457 FT_UINT8, BASE_HEX, NULL, 0x0F,
2460 { &hf_btavdtp_mpeg24_sampling_frequency_8000,
2461 { "Sampling Frequency 8000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.8000",
2462 FT_BOOLEAN, 8, NULL, 0x80,
2465 { &hf_btavdtp_mpeg24_sampling_frequency_11025,
2466 { "Sampling Frequency 11025 Hz", "btavdtp.codec.mpeg24.sampling_frequency.11025",
2467 FT_BOOLEAN, 8, NULL, 0x40,
2470 { &hf_btavdtp_mpeg24_sampling_frequency_12000,
2471 { "Sampling Frequency 12000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.12000",
2472 FT_BOOLEAN, 8, NULL, 0x20,
2475 { &hf_btavdtp_mpeg24_sampling_frequency_16000,
2476 { "Sampling Frequency 16000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.16000",
2477 FT_BOOLEAN, 8, NULL, 0x10,
2480 { &hf_btavdtp_mpeg24_sampling_frequency_22050,
2481 { "Sampling Frequency 22050 Hz", "btavdtp.codec.mpeg24.sampling_frequency.22050",
2482 FT_BOOLEAN, 8, NULL, 0x08,
2485 { &hf_btavdtp_mpeg24_sampling_frequency_24000,
2486 { "Sampling Frequency 24000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.24000",
2487 FT_BOOLEAN, 8, NULL, 0x04,
2490 { &hf_btavdtp_mpeg24_sampling_frequency_32000,
2491 { "Sampling Frequency 32000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.32000",
2492 FT_BOOLEAN, 8, NULL, 0x02,
2495 { &hf_btavdtp_mpeg24_sampling_frequency_44100,
2496 { "Sampling Frequency 44100 Hz", "btavdtp.codec.mpeg24.sampling_frequency.44100",
2497 FT_BOOLEAN, 8, NULL, 0x01,
2500 { &hf_btavdtp_mpeg24_sampling_frequency_48000,
2501 { "Sampling Frequency 48000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.48000",
2502 FT_BOOLEAN, 8, NULL, 0x80,
2505 { &hf_btavdtp_mpeg24_sampling_frequency_64000,
2506 { "Sampling Frequency 64000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.64000",
2507 FT_BOOLEAN, 8, NULL, 0x40,
2510 { &hf_btavdtp_mpeg24_sampling_frequency_88200,
2511 { "Sampling Frequency 88200 Hz", "btavdtp.codec.mpeg24.sampling_frequency.88200",
2512 FT_BOOLEAN, 8, NULL, 0x20,
2515 { &hf_btavdtp_mpeg24_sampling_frequency_96000,
2516 { "Sampling Frequency 96000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.96000",
2517 FT_BOOLEAN, 8, NULL, 0x10,
2520 { &hf_btavdtp_mpeg24_channels_1,
2521 { "Channels 1", "btavdtp.codec.mpeg24.channels.1",
2522 FT_BOOLEAN, 8, NULL, 0x08,
2525 { &hf_btavdtp_mpeg24_channels_2,
2526 { "Channels 2", "btavdtp.codec.mpeg24.channels.2",
2527 FT_BOOLEAN, 8, NULL, 0x04,
2530 { &hf_btavdtp_mpeg24_rfa,
2531 { "RFA", "btavdtp.codec.mpeg24.rfa",
2532 FT_UINT8, BASE_HEX, NULL, 0x03,
2535 { &hf_btavdtp_mpeg24_vbr_supported,
2536 { "VBR Supported", "btavdtp.codec.mpeg24.vbr",
2537 FT_BOOLEAN, 24, NULL, 0x800000,
2540 { &hf_btavdtp_mpeg24_bit_rate,
2541 { "Bit Rate", "btavdtp.codec.mpeg24.bit_rate",
2542 FT_UINT24, BASE_HEX, NULL, 0x7FFFFF,
2545 { &hf_btavdtp_atrac_version,
2546 { "Version", "btavdtp.codec.atrac.version",
2547 FT_UINT8, BASE_DEC, NULL, 0xE0,
2550 { &hf_btavdtp_atrac_channel_mode_single_channel,
2551 { "Channel Mode Single Channel", "btavdtp.codec.atrac.channel_mode.single_channel",
2552 FT_BOOLEAN, 8, NULL, 0x10,
2555 { &hf_btavdtp_atrac_channel_mode_dual_channel,
2556 { "Channel Mode Dual Channel", "btavdtp.codec.atrac.channel_mode.dual_channel",
2557 FT_BOOLEAN, 8, NULL, 0x08,
2560 { &hf_btavdtp_atrac_channel_mode_joint_stereo,
2561 { "Channel Mode Joint Stereo", "btavdtp.codec.atrac.channel_mode.joint_stereo",
2562 FT_BOOLEAN, 8, NULL, 0x04,
2565 { &hf_btavdtp_atrac_rfa1,
2566 { "RFA", "btavdtp.codec.atrac.rfa1",
2567 FT_UINT8, BASE_HEX, NULL, 0x03,
2570 { &hf_btavdtp_atrac_rfa2,
2571 { "RFA", "btavdtp.codec.atrac.rfa2",
2572 FT_UINT24, BASE_HEX, NULL, 0xC00000,
2575 { &hf_btavdtp_atrac_sampling_frequency_44100,
2576 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2577 FT_BOOLEAN, 24, NULL, 0x200000,
2580 { &hf_btavdtp_atrac_sampling_frequency_48000,
2581 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2582 FT_BOOLEAN, 24, NULL, 0x100000,
2585 { &hf_btavdtp_atrac_vbr_supported,
2586 { "VBR Supported", "btavdtp.codec.atrac.vbr",
2587 FT_BOOLEAN, 24, NULL, 0x080000,
2590 { &hf_btavdtp_atrac_bit_rate,
2591 { "Bit Rate", "btavdtp.codec.atrac.bit_rate",
2592 FT_UINT24, BASE_HEX, NULL, 0x07FFFF,
2595 { &hf_btavdtp_atrac_maximum_sul,
2596 { "Maximum SUL", "btavdtp.codec.atrac.maximum_sul",
2597 FT_UINT8, BASE_DEC, NULL, 0x00,
2598 "Sound Unit Length (SUL) is one of the parameters that determine bit rate of the audio stream.", HFILL }
2600 { &hf_btavdtp_atrac_rfa3,
2601 { "RFA", "btavdtp.codec.atrac.rfa3",
2602 FT_UINT8, BASE_HEX, NULL, 0x00,
2605 { &hf_btavdtp_h263_level_10,
2606 { "H264 Level 10", "btavdtp.codec.h264.level.10",
2607 FT_BOOLEAN, 8, NULL, 0x80,
2610 { &hf_btavdtp_h263_level_20,
2611 { "H264 Level 20", "btavdtp.codec.h264.level.20",
2612 FT_BOOLEAN, 8, NULL, 0x40,
2615 { &hf_btavdtp_h263_level_30,
2616 { "H264 Level 30", "btavdtp.codec.h264.level.30",
2617 FT_BOOLEAN, 8, NULL, 0x20,
2620 { &hf_btavdtp_h263_level_rfa,
2621 { "H264 Level RFA", "btavdtp.codec.h264.level.rfa",
2622 FT_UINT8, BASE_HEX, NULL, 0x1F,
2625 { &hf_btavdtp_mpeg4_level_0,
2626 { "MPEG Level 0", "btavdtp.codec.mpeg4.level.0",
2627 FT_BOOLEAN, 8, NULL, 0x80,
2630 { &hf_btavdtp_mpeg4_level_1,
2631 { "MPEG Level 1", "btavdtp.codec.mpeg4.level.1",
2632 FT_BOOLEAN, 8, NULL, 0x40,
2635 { &hf_btavdtp_mpeg4_level_2,
2636 { "MPEG Level 2", "btavdtp.codec.mpeg4.level.2",
2637 FT_BOOLEAN, 8, NULL, 0x20,
2640 { &hf_btavdtp_mpeg4_level_3,
2641 { "MPEG4 Level 3", "btavdtp.codec.mpeg4.level.3",
2642 FT_BOOLEAN, 8, NULL, 0x10,
2645 { &hf_btavdtp_mpeg4_level_rfa,
2646 { "MPEG4 Level RFA", "btavdtp.codec.mpeg4.level.rfa",
2647 FT_UINT8, BASE_HEX, NULL, 0x0F,
2650 { &hf_btavdtp_vendor_id,
2651 { "Vendor ID", "btavdtp.codec.vendor.vendor_id",
2652 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
2655 { &hf_btavdtp_vendor_specific_codec_id,
2656 { "Codec", "btavdtp.codec.vendor.codec_id",
2657 FT_UINT16, BASE_HEX, NULL, 0x00,
2660 { &hf_btavdtp_vendor_specific_value,
2661 { "Value", "btavdtp.codec.vendor.value",
2662 FT_NONE, BASE_NONE, NULL, 0x00,
2665 { &hf_btavdtp_vendor_specific_apt_codec_id,
2666 { "Codec", "btavdtp.codec.vendor.codec_id",
2667 FT_UINT16, BASE_HEX, VALS(vendor_apt_codec_vals), 0x00,
2670 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000,
2671 { "Sampling Frequency 16000 Hz", "btavdtp.codec.aptx.sampling_frequency.16000",
2672 FT_BOOLEAN, 8, NULL, 0x80,
2675 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000,
2676 { "Sampling Frequency 32000 Hz", "btavdtp.codec.aptx.sampling_frequency.32000",
2677 FT_BOOLEAN, 8, NULL, 0x40,
2680 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100,
2681 { "Sampling Frequency 44100 Hz", "btavdtp.codec.aptx.sampling_frequency.44100",
2682 FT_BOOLEAN, 8, NULL, 0x20,
2685 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000,
2686 { "Sampling Frequency 48000 Hz", "btavdtp.codec.aptx.sampling_frequency.48000",
2687 FT_BOOLEAN, 8, NULL, 0x10,
2690 { &hf_btavdtp_vendor_specific_aptx_channel_mode_mono,
2691 { "Channel Mode Mono", "btavdtp.codec.aptx.channel_mode.mono",
2692 FT_BOOLEAN, 8, NULL, 0x08,
2695 { &hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel,
2696 { "Channel Mode Dual Channel", "btavdtp.codec.aptx.channel_mode.dual_channel",
2697 FT_BOOLEAN, 8, NULL, 0x04,
2700 { &hf_btavdtp_vendor_specific_aptx_channel_mode_stereo,
2701 { "Channel Mode Stereo", "btavdtp.codec.aptx.channel_mode.stereo",
2702 FT_BOOLEAN, 8, NULL, 0x02,
2705 { &hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo,
2706 { "Channel Mode Joint Stereo", "btavdtp.codec.aptx.channel_mode.joint_stereo",
2707 FT_BOOLEAN, 8, NULL, 0x01,
2710 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_16000,
2711 { "Sampling Frequency 16000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.16000",
2712 FT_BOOLEAN, 8, NULL, 0x80,
2715 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_32000,
2716 { "Sampling Frequency 32000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.32000",
2717 FT_BOOLEAN, 8, NULL, 0x40,
2720 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_44100,
2721 { "Sampling Frequency 44100 Hz", "btavdtp.codec.aptxhd.sampling_frequency.44100",
2722 FT_BOOLEAN, 8, NULL, 0x20,
2725 { &hf_btavdtp_vendor_specific_aptxhd_sampling_frequency_48000,
2726 { "Sampling Frequency 48000 Hz", "btavdtp.codec.aptxhd.sampling_frequency.48000",
2727 FT_BOOLEAN, 8, NULL, 0x10,
2730 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_mono,
2731 { "Channel Mode Mono", "btavdtp.codec.aptxhd.channel_mode.mono",
2732 FT_BOOLEAN, 8, NULL, 0x08,
2735 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_dual_channel,
2736 { "Channel Mode Dual Channel", "btavdtp.codec.aptxhd.channel_mode.dual_channel",
2737 FT_BOOLEAN, 8, NULL, 0x04,
2740 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_stereo,
2741 { "Channel Mode Stereo", "btavdtp.codec.aptxhd.channel_mode.stereo",
2742 FT_BOOLEAN, 8, NULL, 0x02,
2745 { &hf_btavdtp_vendor_specific_aptxhd_channel_mode_joint_stereo,
2746 { "Channel Mode Joint Stereo", "btavdtp.codec.aptxhd.channel_mode.joint_stereo",
2747 FT_BOOLEAN, 8, NULL, 0x01,
2750 { &hf_btavdtp_vendor_specific_aptxhd_rfa,
2751 { "RFA", "btavdtp.codec.aptxhd.rfa",
2752 FT_UINT32, BASE_HEX, NULL, 0x0,
2755 { &hf_btavdtp_capabilities,
2756 { "Capabilities", "btavdtp.capabilities",
2757 FT_NONE, BASE_NONE, NULL, 0x0,
2760 { &hf_btavdtp_service,
2761 { "Service", "btavdtp.service",
2762 FT_NONE, BASE_NONE, NULL, 0x0,
2765 { &hf_btavdtp_service_multiplexing_entry,
2766 { "Entry", "btavdtp.service_multiplexing_entry",
2767 FT_NONE, BASE_NONE, NULL, 0x0,
2771 { "Data", "btavdtp.data",
2772 FT_NONE, BASE_NONE, NULL, 0x0,
2777 static gint *ett[] = {
2780 &ett_btavdtp_capabilities,
2781 &ett_btavdtp_service,
2784 proto_btavdtp = proto_register_protocol("Bluetooth AVDTP Protocol", "BT AVDTP", "btavdtp");
2785 btavdtp_handle = register_dissector("btavdtp", dissect_btavdtp, proto_btavdtp);
2787 proto_register_field_array(proto_btavdtp, hf, array_length(hf));
2788 proto_register_subtree_array(ett, array_length(ett));
2790 module = prefs_register_protocol_subtree("Bluetooth", proto_btavdtp, NULL);
2791 prefs_register_static_text_preference(module, "avdtp.version",
2792 "Bluetooth Protocol AVDTP version: 1.3",
2793 "Version of protocol supported by this dissector.");
2795 channels = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2796 sep_list = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2797 sep_open = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2798 media_packet_times = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2799 #if RTP_PLAYER_WORKAROUND == TRUE
2800 file_scope_stream_number = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2805 proto_reg_handoff_btavdtp(void)
2807 dissector_add_string("bluetooth.uuid", "19", btavdtp_handle);
2809 dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_AVDTP, btavdtp_handle);
2811 dissector_add_for_decode_as("btl2cap.cid", btavdtp_handle);
2816 dissect_aptx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2818 proto_item *aptx_item;
2819 proto_tree *aptx_tree;
2821 bta2dp_codec_info_t *info;
2822 gdouble cumulative_frame_duration = 0;
2824 info = (bta2dp_codec_info_t *) data;
2826 col_set_str(pinfo->cinfo, COL_PROTOCOL, "aptX");
2828 switch (pinfo->p2p_dir) {
2831 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
2835 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
2838 case P2P_DIR_UNKNOWN:
2839 col_clear(pinfo->cinfo, COL_INFO);
2843 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
2848 col_append_fstr(pinfo->cinfo, COL_INFO, "aptX");
2850 aptx_item = proto_tree_add_item(tree, proto_aptx, tvb, 0, -1, ENC_NA);
2851 aptx_tree = proto_item_add_subtree(aptx_item, ett_aptx);
2853 proto_tree_add_item(aptx_tree, hf_aptx_data, tvb, 0, -1, ENC_NA);
2855 if (info && info->configuration && info->configuration_length >= 9) {
2856 gboolean fail = FALSE;
2857 gdouble expected_speed_data;
2858 gdouble frame_duration;
2859 gdouble frame_length = 2 * 2 * 4;
2860 gint number_of_channels;
2864 switch (info->configuration[8] >> 4) {
2882 return tvb_reported_length(tvb);
2884 switch (info->configuration[8] & 0x0F) {
2888 number_of_channels = 2;
2891 number_of_channels = 1;
2898 return tvb_reported_length(tvb);
2902 expected_speed_data = frequency * (sample_bits / 8.0) * number_of_channels;
2903 frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0);
2905 cumulative_frame_duration = (tvb_reported_length(tvb) / 4.0) * frame_duration;
2907 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_frame_duration, tvb, 0, 0, cumulative_frame_duration);
2908 PROTO_ITEM_SET_GENERATED(pitem);
2910 if (info && info->previous_media_packet_info && info->current_media_packet_info) {
2913 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->abs_ts);
2914 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time, tvb, 0, 0, nstime_to_msec(&delta));
2915 PROTO_ITEM_SET_GENERATED(pitem);
2917 pitem = proto_tree_add_double(aptx_tree, hf_aptx_avrcp_song_position, tvb, 0, 0, info->previous_media_packet_info->avrcp_song_position);
2918 PROTO_ITEM_SET_GENERATED(pitem);
2920 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->first_abs_ts);
2921 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time_from_the_beginning, tvb, 0, 0, nstime_to_msec(&delta));
2922 PROTO_ITEM_SET_GENERATED(pitem);
2924 if (!pinfo->fd->flags.visited)
2925 info->current_media_packet_info->cumulative_frame_duration += cumulative_frame_duration;
2927 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_duration, tvb, 0, 0, info->previous_media_packet_info->cumulative_frame_duration);
2928 PROTO_ITEM_SET_GENERATED(pitem);
2930 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));
2931 PROTO_ITEM_SET_GENERATED(pitem);
2935 return tvb_reported_length(tvb);
2939 proto_register_aptx(void)
2941 static hf_register_info hf[] = {
2943 { "Data", "aptx.data",
2944 FT_BYTES, BASE_NONE, NULL, 0x00,
2947 { &hf_aptx_cumulative_frame_duration,
2948 { "Cumulative Frame Duration", "aptx.cumulative_frame_duration",
2949 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2952 { &hf_aptx_delta_time,
2953 { "Delta time", "aptx.delta_time",
2954 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2957 { &hf_aptx_avrcp_song_position,
2958 { "AVRCP Song Position", "aptx.avrcp_song_position",
2959 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2962 { &hf_aptx_delta_time_from_the_beginning,
2963 { "Delta time from the beginning", "aptx.delta_time_from_the_beginning",
2964 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2967 { &hf_aptx_cumulative_duration,
2968 { "Cumulative Music Duration", "aptx.cumulative_music_duration",
2969 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2973 { "Diff", "aptx.diff",
2974 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2979 static gint *ett[] = {
2983 proto_aptx = proto_register_protocol("aptX Codec", "aptX", "aptx");
2984 proto_register_field_array(proto_aptx, hf, array_length(hf));
2985 proto_register_subtree_array(ett, array_length(ett));
2987 aptx_handle = register_dissector("aptx", dissect_aptx, proto_aptx);
2992 dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2995 proto_tree *bta2dp_tree;
2998 dissector_handle_t codec_dissector = NULL;
2999 bta2dp_codec_info_t bta2dp_codec_info;
3000 sep_data_t sep_data;
3001 gboolean no_avdtp_session;
3003 no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
3004 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3006 sep_data.codec = CODEC_SBC;
3007 sep_data.content_protection_type = 0;
3008 sep_data.acp_seid = 0;
3009 sep_data.int_seid = 0;
3010 sep_data.previous_media_packet_info = NULL;
3011 sep_data.current_media_packet_info = NULL;
3012 sep_data.stream_start_in_frame = 0;
3013 sep_data.stream_end_in_frame = 0;
3014 sep_data.stream_number = 1;
3015 sep_data.vendor_id = 0;
3016 sep_data.vendor_codec = 0;
3017 sep_data.configuration_length = 0;
3018 sep_data.configuration = NULL;
3020 if (force_a2dp_scms_t || force_a2dp_codec != CODEC_DEFAULT) {
3021 if (force_a2dp_scms_t)
3022 sep_data.content_protection_type = 2;
3023 else if (data && !no_avdtp_session)
3024 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
3026 if (force_a2dp_codec != CODEC_DEFAULT)
3027 sep_data.codec = force_a2dp_codec;
3028 else if (data && !no_avdtp_session)
3029 sep_data.codec = ((sep_data_t *) data)->codec;
3031 if (data && !no_avdtp_session)
3032 sep_data = *((sep_data_t *) data);
3035 col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP");
3037 switch (pinfo->p2p_dir) {
3040 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3044 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3047 case P2P_DIR_UNKNOWN:
3048 col_clear(pinfo->cinfo, COL_INFO);
3052 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3057 ti = proto_tree_add_item(tree, proto_bta2dp, tvb, offset, -1, ENC_NA);
3058 col_append_fstr(pinfo->cinfo, COL_INFO, "Audio stream - %s",
3059 val_to_str_const(sep_data.codec, media_codec_audio_type_vals, "unknown codec"));
3061 bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp);
3063 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3064 PROTO_ITEM_SET_GENERATED(pitem);
3066 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_int_seid, tvb, 0, 0, sep_data.int_seid);
3067 PROTO_ITEM_SET_GENERATED(pitem);
3069 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, 0, 0, sep_data.codec);
3070 PROTO_ITEM_SET_GENERATED(pitem);
3072 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3073 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3074 PROTO_ITEM_SET_GENERATED(pitem);
3076 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3077 PROTO_ITEM_SET_GENERATED(pitem);
3079 if ((sep_data.vendor_id == 0x004F && sep_data.vendor_codec == CODECID_APT_X) ||
3080 (sep_data.vendor_id == 0x00D7 && sep_data.vendor_codec == CODECID_APT_X_HD))
3081 codec_dissector = aptx_handle;
3084 if (sep_data.content_protection_type > 0) {
3085 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3086 PROTO_ITEM_SET_GENERATED(pitem);
3089 if (sep_data.stream_start_in_frame > 0) {
3090 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3091 PROTO_ITEM_SET_GENERATED(pitem);
3094 if (sep_data.stream_end_in_frame > 0) {
3095 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3096 PROTO_ITEM_SET_GENERATED(pitem);
3099 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_number, tvb, 0, 0, sep_data.stream_number);
3100 PROTO_ITEM_SET_GENERATED(pitem);
3102 switch (sep_data.codec) {
3104 codec_dissector = sbc_handle;
3106 case CODEC_MPEG12_AUDIO:
3107 codec_dissector = mp2t_handle;
3109 case CODEC_MPEG24_AAC:
3110 codec_dissector = mpeg_audio_handle;
3113 codec_dissector = atrac_handle;
3116 case CODEC_APT_X_HD:
3117 codec_dissector = aptx_handle;
3121 bta2dp_codec_info.codec_dissector = codec_dissector;
3122 bta2dp_codec_info.configuration_length = sep_data.configuration_length;
3123 bta2dp_codec_info.configuration = sep_data.configuration;
3124 bta2dp_codec_info.content_protection_type = sep_data.content_protection_type;
3125 bta2dp_codec_info.previous_media_packet_info = sep_data.previous_media_packet_info;
3126 bta2dp_codec_info.current_media_packet_info = sep_data.current_media_packet_info;
3128 #if RTP_PLAYER_WORKAROUND == TRUE
3129 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3130 weak to recognize Bluetooth streams (key is: guint32 interface_id, guint32 adapter_id, guint32 chandle, guint32 cid, guint32 direction -> guint32 stream_number) */
3131 pinfo->srcport = sep_data.stream_number;
3132 pinfo->destport = sep_data.stream_number;
3135 if (bta2dp_codec_info.content_protection_type == 0 && codec_dissector == aptx_handle) {
3136 call_dissector_with_data(aptx_handle, tvb, pinfo, tree, &bta2dp_codec_info);
3138 bluetooth_add_address(pinfo, &pinfo->net_dst, sep_data.stream_number, "BT A2DP", pinfo->num, RTP_MEDIA_AUDIO, &bta2dp_codec_info);
3139 call_dissector(rtp_handle, tvb, pinfo, tree);
3141 offset += tvb_reported_length_remaining(tvb, offset);
3147 proto_register_bta2dp(void)
3151 static hf_register_info hf[] = {
3152 { &hf_bta2dp_acp_seid,
3153 { "ACP SEID", "bta2dp.acp_seid",
3154 FT_UINT8, BASE_DEC, NULL, 0x00,
3157 { &hf_bta2dp_int_seid,
3158 { "INT SEID", "bta2dp.int_seid",
3159 FT_UINT8, BASE_DEC, NULL, 0x00,
3163 { "Codec", "bta2dp.codec",
3164 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
3167 { &hf_bta2dp_vendor_id,
3168 { "Vendor ID", "bta2dp.codec.vendor.vendor_id",
3169 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3172 { &hf_bta2dp_vendor_codec_id,
3173 { "Vendor Codec", "bta2dp.codec.vendor.codec_id",
3174 FT_UINT16, BASE_HEX, NULL, 0x00,
3177 { &hf_bta2dp_content_protection,
3178 { "Content Protection", "bta2dp.content_protection",
3179 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3182 { &hf_bta2dp_stream_start_in_frame,
3183 { "Stream Start in Frame", "bta2dp.stream_start_in_frame",
3184 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3187 { &hf_bta2dp_stream_end_in_frame,
3188 { "Stream End in Frame", "bta2dp.stream_end_in_frame",
3189 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3192 { &hf_bta2dp_stream_number,
3193 { "Stream Number", "bta2dp.stream_number",
3194 FT_UINT32, BASE_DEC, NULL, 0x00,
3199 static gint *ett[] = {
3203 proto_bta2dp = proto_register_protocol("Bluetooth A2DP Profile", "BT A2DP", "bta2dp");
3204 proto_register_field_array(proto_bta2dp, hf, array_length(hf));
3205 proto_register_subtree_array(ett, array_length(ett));
3207 bta2dp_handle = register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp);
3209 module = prefs_register_protocol_subtree("Bluetooth", proto_bta2dp, NULL);
3210 prefs_register_static_text_preference(module, "a2dp.version",
3211 "Bluetooth Profile A2DP version: 1.3",
3212 "Version of profile supported by this dissector.");
3214 prefs_register_bool_preference(module, "a2dp.content_protection.scms_t",
3215 "Force SCMS-T decoding",
3216 "Force decoding stream as A2DP with Content Protection SCMS-T ",
3217 &force_a2dp_scms_t);
3219 prefs_register_enum_preference(module, "a2dp.codec",
3221 "Force decoding stream as A2DP with specified codec",
3222 &force_a2dp_codec, pref_a2dp_codec, FALSE);
3226 proto_reg_handoff_bta2dp(void)
3228 sbc_handle = find_dissector_add_dependency("sbc", proto_bta2dp);
3229 mp2t_handle = find_dissector_add_dependency("mp2t", proto_bta2dp);
3230 mpeg_audio_handle = find_dissector_add_dependency("mpeg-audio", proto_bta2dp);
3231 /* TODO: ATRAC dissector does not exist yet */
3232 atrac_handle = find_dissector_add_dependency("atrac", proto_bta2dp);
3234 rtp_handle = find_dissector_add_dependency("rtp", proto_bta2dp);
3236 dissector_add_string("bluetooth.uuid", "110a", bta2dp_handle);
3237 dissector_add_string("bluetooth.uuid", "110b", bta2dp_handle);
3238 dissector_add_string("bluetooth.uuid", "110d", bta2dp_handle);
3240 dissector_add_for_decode_as("btl2cap.cid", bta2dp_handle);
3244 dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3247 proto_tree *btvdp_tree;
3250 dissector_handle_t codec_dissector = NULL;
3251 btvdp_codec_info_t btvdp_codec_info;
3252 sep_data_t sep_data;
3253 gboolean no_avdtp_session;
3255 no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
3256 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3258 sep_data.codec = CODEC_H263_BASELINE;
3259 sep_data.content_protection_type = 0;
3260 sep_data.acp_seid = 0;
3261 sep_data.int_seid = 0;
3262 sep_data.previous_media_packet_info = NULL;
3263 sep_data.current_media_packet_info = NULL;
3264 sep_data.stream_start_in_frame = 0;
3265 sep_data.stream_end_in_frame = 0;
3266 sep_data.stream_number = 1;
3267 sep_data.vendor_id = 0;
3268 sep_data.vendor_codec = 0;
3269 sep_data.configuration_length = 0;
3270 sep_data.configuration = NULL;
3272 if (force_vdp_scms_t || force_vdp_codec) {
3273 if (force_vdp_scms_t)
3274 sep_data.content_protection_type = 2;
3275 else if (data && !no_avdtp_session)
3276 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
3278 if (force_vdp_codec)
3279 sep_data.codec = force_vdp_codec;
3280 else if (data && !no_avdtp_session)
3281 sep_data.codec = ((sep_data_t *) data)->codec;
3283 if (data && !no_avdtp_session)
3284 sep_data = *((sep_data_t *) data);
3287 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP");
3289 switch (pinfo->p2p_dir) {
3292 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3296 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3299 case P2P_DIR_UNKNOWN:
3300 col_clear(pinfo->cinfo, COL_INFO);
3304 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3309 ti = proto_tree_add_item(tree, proto_btvdp, tvb, offset, -1, ENC_NA);
3310 col_append_fstr(pinfo->cinfo, COL_INFO, "Video stream - %s",
3311 val_to_str_const(sep_data.codec, media_codec_video_type_vals, "unknown codec"));
3313 btvdp_tree = proto_item_add_subtree(ti, ett_btvdp);
3315 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3316 PROTO_ITEM_SET_GENERATED(pitem);
3318 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_int_seid, tvb, 0, 0, sep_data.int_seid);
3319 PROTO_ITEM_SET_GENERATED(pitem);
3321 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, 0, 0, sep_data.codec);
3322 PROTO_ITEM_SET_GENERATED(pitem);
3324 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3325 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3326 PROTO_ITEM_SET_GENERATED(pitem);
3328 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3329 PROTO_ITEM_SET_GENERATED(pitem);
3332 if (sep_data.content_protection_type > 0) {
3333 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3334 PROTO_ITEM_SET_GENERATED(pitem);
3337 if (sep_data.stream_start_in_frame > 0) {
3338 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3339 PROTO_ITEM_SET_GENERATED(pitem);
3342 if (sep_data.stream_end_in_frame > 0) {
3343 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3344 PROTO_ITEM_SET_GENERATED(pitem);
3347 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_number, tvb, 0, 0, sep_data.stream_number);
3348 PROTO_ITEM_SET_GENERATED(pitem);
3350 switch (sep_data.codec) {
3351 case CODEC_H263_BASELINE:
3352 case CODEC_H263_PROFILE_3:
3353 case CODEC_H263_PROFILE_8:
3354 codec_dissector = h263_handle;
3356 case CODEC_MPEG4_VSP:
3357 codec_dissector = mp4v_es_handle;
3361 btvdp_codec_info.codec_dissector = codec_dissector;
3362 btvdp_codec_info.content_protection_type = sep_data.content_protection_type;
3364 #if RTP_PLAYER_WORKAROUND == TRUE
3365 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3366 weak to recognize Bluetooth streams (key is: guint32 interface_id, guint32 adapter_id, guint32 chandle, guint32 cid, guint32 direction -> guint32 stream_number) */
3367 pinfo->srcport = sep_data.stream_number;
3368 pinfo->destport = sep_data.stream_number;
3371 bluetooth_add_address(pinfo, &pinfo->net_dst, 0, "BT VDP", pinfo->num, RTP_MEDIA_VIDEO, &btvdp_codec_info);
3372 call_dissector(rtp_handle, tvb, pinfo, tree);
3373 offset += tvb_reported_length_remaining(tvb, offset);
3379 proto_register_btvdp(void)
3382 expert_module_t* expert_btavdtp;
3384 static hf_register_info hf[] = {
3385 { &hf_btvdp_acp_seid,
3386 { "ACP SEID", "btvdp.acp_seid",
3387 FT_UINT8, BASE_DEC, NULL, 0x00,
3390 { &hf_btvdp_int_seid,
3391 { "INT SEID", "btvdp.int_seid",
3392 FT_UINT8, BASE_DEC, NULL, 0x00,
3396 { "Codec", "btvdp.codec",
3397 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
3400 { &hf_btvdp_vendor_id,
3401 { "Vendor ID", "btvdp.codec.vendor.vendor_id",
3402 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3405 { &hf_btvdp_vendor_codec_id,
3406 { "Vendor Codec", "btvdp.codec.vendor.codec_id",
3407 FT_UINT16, BASE_HEX, NULL, 0x00,
3410 { &hf_btvdp_content_protection,
3411 { "Content Protection", "btvdp.content_protection",
3412 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3415 { &hf_btvdp_stream_start_in_frame,
3416 { "Stream Start in Frame", "btvdp.stream_start_in_frame",
3417 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3420 { &hf_btvdp_stream_end_in_frame,
3421 { "Stream End in Frame", "btvdp.stream_end_in_frame",
3422 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3425 { &hf_btvdp_stream_number,
3426 { "Stream Number", "btvdp.stream_number",
3427 FT_UINT32, BASE_DEC, NULL, 0x00,
3432 static gint *ett[] = {
3436 static ei_register_info ei[] = {
3437 { &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 }},
3438 { &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 }},
3439 { &ei_btavdtp_unexpected_losc_data, { "btavdtp.unexpected_losc_data", PI_PROTOCOL, PI_WARN, "Unexpected losc data", EXPFILL }},
3442 proto_btvdp = proto_register_protocol("Bluetooth VDP Profile", "BT VDP", "btvdp");
3443 btvdp_handle = register_dissector("btvdp", dissect_btvdp, proto_btvdp);
3444 proto_register_field_array(proto_btvdp, hf, array_length(hf));
3445 proto_register_subtree_array(ett, array_length(ett));
3446 expert_btavdtp = expert_register_protocol(proto_btvdp);
3447 expert_register_field_array(expert_btavdtp, ei, array_length(ei));
3449 module = prefs_register_protocol_subtree("Bluetooth", proto_btvdp, NULL);
3450 prefs_register_static_text_preference(module, "vdp.version",
3451 "Bluetooth Profile VDP version: 1.1",
3452 "Version of profile supported by this dissector.");
3454 prefs_register_bool_preference(module, "vdp.content_protection.scms_t",
3455 "Force SCMS-T decoding",
3456 "Force decoding stream as VDP with Content Protection SCMS-T ",
3459 prefs_register_enum_preference(module, "vdp.codec",
3461 "Force decoding stream as VDP with specified codec",
3462 &force_vdp_codec, pref_vdp_codec, FALSE);
3466 proto_reg_handoff_btvdp(void)
3468 h263_handle = find_dissector_add_dependency("h263", proto_btvdp);
3469 mp4v_es_handle = find_dissector_add_dependency("mp4v-es", proto_btvdp);
3471 rtp_handle = find_dissector_add_dependency("rtp", proto_btvdp);
3473 dissector_add_string("bluetooth.uuid", "1303", btvdp_handle);
3474 dissector_add_string("bluetooth.uuid", "1304", btvdp_handle);
3475 dissector_add_string("bluetooth.uuid", "1305", btvdp_handle);
3477 dissector_add_for_decode_as("btl2cap.cid", btvdp_handle);
3483 dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3485 proto_item *main_item;
3486 proto_tree *main_tree;
3489 main_item = proto_tree_add_item(tree, proto_bta2dp_cph_scms_t, tvb, offset, 1, ENC_NA);
3490 main_tree = proto_item_add_subtree(main_item, ett_bta2dp_cph_scms_t);
3492 proto_tree_add_item(main_tree, hf_bta2dp_reserved , tvb, offset, 1, ENC_NA);
3493 proto_tree_add_item(main_tree, hf_bta2dp_cp_bit, tvb, offset, 1, ENC_NA);
3494 proto_tree_add_item(main_tree, hf_bta2dp_l_bit , tvb, offset, 1, ENC_NA);
3501 proto_register_bta2dp_content_protection_header_scms_t(void)
3503 static hf_register_info hf[] = {
3505 { "L-bit", "bta2dp.content_protection_header.scms_t.l_bit",
3506 FT_BOOLEAN, 8, NULL, 0x01,
3509 { &hf_bta2dp_cp_bit,
3510 { "Cp-bit", "bta2dp.content_protection_header.scms_t.cp_bit",
3511 FT_BOOLEAN, 8, NULL, 0x02,
3514 { &hf_bta2dp_reserved,
3515 { "Reserved", "bta2dp.content_protection_header.scms_t.reserved",
3516 FT_BOOLEAN, 8, NULL, 0xFC,
3521 static gint *ett[] = {
3522 &ett_bta2dp_cph_scms_t
3525 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");
3526 proto_register_field_array(proto_bta2dp_cph_scms_t, hf, array_length(hf));
3527 proto_register_subtree_array(ett, array_length(ett));
3529 register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t);
3533 dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3535 proto_item *main_item;
3536 proto_tree *main_tree;
3539 main_item = proto_tree_add_item(tree, proto_btvdp_cph_scms_t, tvb, offset, 1, ENC_NA);
3540 main_tree = proto_item_add_subtree(main_item, ett_btvdp_cph_scms_t);
3542 proto_tree_add_item(main_tree, hf_btvdp_reserved , tvb, offset, 1, ENC_NA);
3543 proto_tree_add_item(main_tree, hf_btvdp_cp_bit, tvb, offset, 1, ENC_NA);
3544 proto_tree_add_item(main_tree, hf_btvdp_l_bit , tvb, offset, 1, ENC_NA);
3551 proto_register_btvdp_content_protection_header_scms_t(void)
3553 static hf_register_info hf[] = {
3555 { "L-bit", "btvdp.content_protection_header.scms_t.l_bit",
3556 FT_BOOLEAN, 8, NULL, 0x01,
3560 { "Cp-bit", "btvdp.content_protection_header.scms_t.cp_bit",
3561 FT_BOOLEAN, 8, NULL, 0x02,
3564 { &hf_btvdp_reserved,
3565 { "Reserved", "btvdp.content_protection_header.scms_t.reserved",
3566 FT_BOOLEAN, 8, NULL, 0xFC,
3571 static gint *ett[] = {
3572 &ett_btvdp_cph_scms_t
3575 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");
3576 proto_register_field_array(proto_btvdp_cph_scms_t, hf, array_length(hf));
3577 proto_register_subtree_array(ett, array_length(ett));
3579 register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t);
3583 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3588 * indent-tabs-mode: nil
3591 * vi: set shiftwidth=4 tabstop=8 expandtab:
3592 * :indentSize=4:tabSize=8:noTabs=true: