c393512e3bf3be7b24027f0a0373113946d016e6
[gd/wireshark/.git] / epan / dissectors / packet-btavdtp.c
1 /* packet-btavdtp.c
2  * Routines for Bluetooth AVDTP dissection
3  *
4  * Copyright 2012, Michal Labedzki for Tieto Corporation
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "config.h"
14
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18
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"
25
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
31
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
36
37 #define PACKET_TYPE_SINGLE            0x00
38 #define PACKET_TYPE_START             0x01
39 #define PACKET_TYPE_CONTINUE          0x02
40 #define PACKET_TYPE_END               0x03
41
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
55
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
64
65 #define MEDIA_TYPE_AUDIO   0x00
66 #define MEDIA_TYPE_VIDEO   0x01
67
68 #define SEID_ACP     0x00
69 #define SEID_INT     0x01
70
71 #define STREAM_TYPE_MEDIA   0x00
72 #define STREAM_TYPE_SIGNAL  0x01
73
74 #define CODEC_DEFAULT         0xFFFF
75 #define CODEC_SBC             0x00
76 #define CODEC_MPEG12_AUDIO    0x01
77 #define CODEC_MPEG24_AAC      0x02
78 #define CODEC_ATRAC           0x04
79 #define CODEC_APT_X           0xFF01
80 #define CODEC_APT_X_HD        0xFF24
81
82 #define CODECID_APT_X         0x0001
83 #define CODECID_APT_X_HD      0x0024
84
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
89
90 #define CODEC_VENDOR          0xFF
91
92 #define HEADER_SIZE  2
93 #define SEP_MAX     64
94 #define SEP_SIZE     2
95
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...)
108         etc. like
109         guint8  stram_endpoint_number
110         guint32 stream_number (to separate multiple streams for RTP Player)
111
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.
116         */
117 #define RTP_PLAYER_WORKAROUND TRUE
118
119 #if RTP_PLAYER_WORKAROUND == TRUE
120     wmem_tree_t *file_scope_stream_number = NULL;
121 #endif
122 /* ========================================================== */
123
124 static int proto_btavdtp = -1;
125
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;
271
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;
276
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;
280
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;
285
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;
290
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;
296
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;
309
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;
314
315 static gboolean  force_a2dp_scms_t = FALSE;
316 static gint      force_a2dp_codec = CODEC_DEFAULT;
317
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 },
326     { NULL, NULL, 0 }
327 };
328
329
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;
335
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;
348
349 static dissector_handle_t h263_handle;
350 static dissector_handle_t mp4v_es_handle;
351
352 static gboolean  force_vdp_scms_t = FALSE;
353 static gint      force_vdp_codec = CODEC_H263_BASELINE;
354
355 static const enum_val_t pref_vdp_codec[] = {
356     { "h263",    "H263",      CODEC_H263_BASELINE },
357     { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP },
358     { NULL, NULL, 0 }
359 };
360
361 /* APT-X Codec */
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;
372
373
374 static const value_string message_type_vals[] = {
375     { 0x00,  "Command" },
376     { 0x01,  "GeneralReject" },
377     { 0x02,  "ResponseAccept" },
378     { 0x03,  "ResponseReject" },
379     { 0, NULL }
380 };
381
382 static const value_string packet_type_vals[] = {
383     { 0x00,  "Single" },
384     { 0x01,  "Start" },
385     { 0x02,  "Continue" },
386     { 0x03,  "End" },
387     { 0, NULL }
388 };
389
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" },
397     { 0x06, "Open" },
398     { 0x07, "Start" },
399     { 0x08, "Close" },
400     { 0x09, "Suspend" },
401     { 0x0A, "Abort" },
402     { 0x0B, "SecurityControl" },
403     { 0x0C, "GetAllCapabilities" },
404     { 0x0D, "DelayReport" },
405     { 0, NULL }
406 };
407
408 static const value_string media_type_vals[] = {
409     { 0x00,  "Audio" },
410     { 0x01,  "Video" },
411     { 0x02,  "Multimedia" },
412     { 0, NULL }
413 };
414
415 static const value_string sep_type_vals[] = {
416     { 0x00,  "Source" },
417     { 0x01,  "Sink" },
418     { 0, NULL }
419 };
420
421 static const value_string true_false[] = {
422     { 0x00,  "False" },
423     { 0x01,  "True" },
424     { 0, NULL }
425 };
426
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" },
449     /* GAVDTP */
450     { 0x80,  "The Service Category Stated is Invalid" },
451     { 0x81,  "Lack of Resource New Stream Context" },
452     /* A2DP */
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" },
486     { 0, NULL }
487 };
488
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" },
498     { 0, NULL }
499 };
500
501 static const value_string recovery_type_vals[] = {
502     { 0x00,  "Forbidden" },
503     { 0x01,  "RFC2733" },
504     { 0, NULL }
505 };
506
507 static const value_string multiplexing_tsid_vals[] = {
508     { 0x00,  "Used for TSID query" },
509     { 0x1F,  "RFD" },
510     { 0, NULL }
511 };
512
513 static const value_string multiplexing_tcid_vals[] = {
514     { 0x00,  "Used for TCID query" },
515     { 0x1F,  "RFD" },
516     { 0, NULL }
517 };
518
519 static const value_string media_codec_audio_type_vals[] = {
520     { 0x00,  "SBC" },
521     { 0x01,  "MPEG-1,2 Audio" },
522     { 0x02,  "MPEG-2,4 AAC" },
523     { 0x04,  "ATRAC family" },
524     { 0xFF,  "non-A2DP" },
525     { 0, NULL }
526 };
527
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" },
533     { 0xFF,  "non-VDP" },
534     { 0, NULL }
535 };
536
537 static const value_string content_protection_type_vals[] = {
538     { 0x01,  "DTCP" },
539     { 0x02,  "SCMS-T" },
540     { 0, NULL }
541 };
542
543 static const value_string vendor_apt_codec_vals[] = {
544     { CODECID_APT_X,     "aptX" },
545     { CODECID_APT_X_HD,  "aptX HD" },
546     { 0, NULL }
547 };
548
549 enum sep_state {
550     SEP_STATE_FREE,
551     SEP_STATE_OPEN,
552     SEP_STATE_IN_USE
553 };
554
555 typedef struct _sep_entry_t {
556     guint8         seid;
557     guint8         type;
558     guint8         media_type;
559     guint8         int_seid;
560     gint           codec;
561     guint32        vendor_id;
562     guint16        vendor_codec;
563     guint8         configuration_length;
564     guint8        *configuration;
565     gint           content_protection_type;
566
567     enum sep_state state;
568 } sep_entry_t;
569
570 typedef struct _sep_data_t {
571     gint      codec;
572     guint32   vendor_id;
573     guint16   vendor_codec;
574     guint8    configuration_length;
575     guint8   *configuration;
576     guint8    acp_seid;
577     guint8    int_seid;
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;
584 } sep_data_t;
585
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;
591
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;
602     sep_entry_t  *sep;
603 } channels_info_t;
604
605
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);
615
616
617 static const char *
618 get_sep_type(guint32 interface_id,
619     guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
620 {
621     wmem_tree_key_t   key[6];
622     wmem_tree_t      *subtree;
623     sep_entry_t      *sep;
624
625     key[0].length = 1;
626     key[0].key    = &interface_id;
627     key[1].length = 1;
628     key[1].key    = &adapter_id;
629     key[2].length = 1;
630     key[2].key    = &chandle;
631     key[3].length = 1;
632     key[3].key    = &direction;
633     key[4].length = 1;
634     key[4].key    = &seid;
635     key[5].length = 0;
636     key[5].key    = NULL;
637
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;
640     if (sep) {
641         return val_to_str_const(sep->type, sep_type_vals, "unknown");
642     }
643
644     return "unknown";
645 }
646
647 static const char *
648 get_sep_media_type(guint32 interface_id,
649     guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
650 {
651     wmem_tree_key_t   key[6];
652     wmem_tree_t      *subtree;
653     sep_entry_t      *sep;
654
655     key[0].length = 1;
656     key[0].key    = &interface_id;
657     key[1].length = 1;
658     key[1].key    = &adapter_id;
659     key[2].length = 1;
660     key[2].key    = &chandle;
661     key[3].length = 1;
662     key[3].key    = &direction;
663     key[4].length = 1;
664     key[4].key    = &seid;
665     key[5].length = 0;
666     key[5].key    = NULL;
667
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;
670     if (sep) {
671         return val_to_str_const(sep->media_type, media_type_vals, "unknown");
672     }
673
674     return "unknown";
675 }
676
677
678 static gint
679 dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
680     guint32 interface_id, guint32 adapter_id, guint32 chandle)
681 {
682     proto_tree       *sep_tree;
683     proto_item       *sep_item;
684     guint            i_sep  = 1;
685     guint            media_type;
686     guint            type;
687     guint            seid;
688     guint            in_use;
689     guint            items;
690     guint32          direction;
691
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
694     */
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;
700         seid = seid >> 2;
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);
707
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);
711         offset+=1;
712
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);
716
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;
721
722             key[0].length = 1;
723             key[0].key    = &interface_id;
724             key[1].length = 1;
725             key[1].key    = &adapter_id;
726             key[2].length = 1;
727             key[2].key    = &chandle;
728             key[3].length = 1;
729             key[3].key    = &direction;
730             key[4].length = 1;
731             key[4].key    = &seid;
732             key[5].length = 1;
733             key[5].key    = &frame_number;
734             key[6].length = 0;
735             key[6].key    = NULL;
736
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;
742             if (in_use) {
743                 sep_data->state = SEP_STATE_IN_USE;
744             } else {
745                 sep_data->state = SEP_STATE_FREE;
746             }
747
748             wmem_tree_insert32_array(sep_list, key, sep_data);
749         }
750
751         offset += 1;
752         i_sep += 1;
753     }
754
755     col_append_fstr(pinfo->cinfo, COL_INFO, " - items: %u", items);
756     return offset;
757 }
758
759
760 static gint
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)
763 {
764     proto_item    *pitem;
765     guint32        value;
766     guint8        *value8 = (guint8 *) &value;
767
768     switch(media_type) {
769         case MEDIA_TYPE_AUDIO:
770             switch(media_codec_type) {
771                 case CODEC_SBC:
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);
780
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);
789
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);
794                     }
795
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);
800                     }
801
802                     value = tvb_get_h_guint32(tvb, offset);
803                     if (value) {
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 ",
826                             value8[2],
827                             value8[3]);
828
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 ",
851                             value8[2],
852                             value8[3]);
853                     } else {
854                         col_append_fstr(pinfo->cinfo, COL_INFO, " (none)");
855                         proto_item_append_text(service_item, " (none)");
856                     }
857
858                     break;
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);
868
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);
877
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);
880                     break;
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);
887
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);
896
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);
904
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);
907                     break;
908                 case CODEC_ATRAC:
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);
914
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);
920
921                     proto_tree_add_item(tree, hf_btavdtp_atrac_maximum_sul, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
922
923                     proto_tree_add_item(tree, hf_btavdtp_atrac_rfa3, tvb, offset + 6, 1, ENC_NA);
924                     break;
925                 case CODEC_VENDOR: /* non-A2DP */
926                     proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
927
928                     if (vendor_id)
929                         *vendor_id = tvb_get_letohl(tvb, offset);
930
931                     if (vendor_codec)
932                         *vendor_codec = tvb_get_letohs(tvb, offset + 4);
933
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);
939
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);
950                                 } else {
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);
960                                 }
961
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"));
966
967                                 value = tvb_get_guint8(tvb, offset + 6);
968                                 if (value) {
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 ");
980
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 ");
992                                 } else {
993                                     col_append_fstr(pinfo->cinfo, COL_INFO, " none)");
994                                     proto_item_append_text(service_item, " none)");
995                                 }
996                             } else {
997                                 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
998                             }
999                             break;
1000                         default:
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);
1003                     }
1004
1005                     break;
1006                 default:
1007                     proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1008             }
1009             break;
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);
1019                     break;
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);
1026                     break;
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);
1031                     break;
1032                 default:
1033                     proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1034             }
1035             break;
1036         default:
1037             proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1038     }
1039
1040     offset += losc;
1041
1042     return offset;
1043 }
1044
1045
1046 static gint
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)
1052 {
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;
1060     gint        losc                                          = 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;
1066
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);
1069
1070     if (codec)
1071         *codec = -1;
1072
1073     if (vendor_id)
1074         *vendor_id = 0x003F; /* Bluetooth SIG */
1075
1076     if (vendor_codec)
1077         *vendor_codec = 0;
1078
1079     if (configuration_length)
1080         *configuration_length = 0;
1081
1082     if (configuration_offset)
1083         *configuration_offset = 0;
1084
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);
1090
1091         proto_tree_add_item(service_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1092         offset += 1;
1093
1094         proto_tree_add_item(service_tree, hf_btavdtp_length_of_service_category, tvb, offset, 1, ENC_NA);
1095         offset += 1;
1096
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 */
1102                 break;
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"));
1107                 offset += 1;
1108                 losc -= 1;
1109
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)");
1116                 }
1117                 offset += 1;
1118                 losc -= 1;
1119
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)");
1127                 }
1128                 offset += 1;
1129                 losc -= 1;
1130                 break;
1131             case SERVICE_CATEGORY_MEDIA_CODEC:
1132                 if (configuration_length)
1133                     *configuration_length = losc;
1134                 if (configuration_offset)
1135                     *configuration_offset = offset;
1136
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);
1140                 offset += 1;
1141                 losc -= 1;
1142
1143                 media_codec_type = tvb_get_guint8(tvb, offset);
1144                 if (codec) {
1145                     *codec = media_codec_type;
1146                 }
1147
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"));
1160                 } else {
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);
1164                 }
1165                 offset += 1;
1166                 losc -= 1;
1167
1168                 offset = dissect_codec(tvb, pinfo, service_item, service_tree,
1169                         offset, losc, media_type, media_codec_type,
1170                         vendor_id, vendor_codec);
1171                 losc = 0;
1172                 break;
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);
1177                 }
1178                 proto_item_append_text(service_item, " - %s",
1179                     val_to_str_const(tvb_get_letohs(tvb, offset), content_protection_type_vals, "unknown"));
1180
1181                 offset += 2;
1182                 losc -= 2;
1183
1184                 if (losc > 0) {
1185                     proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1186                     offset += losc;
1187                     losc = 0;
1188                 }
1189                 break;
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);
1195                 offset += 1;
1196                 losc -= 1;
1197                 break;
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);
1201                 offset += 1;
1202                 losc -= 1;
1203
1204                 if (losc >= 2) {
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);
1207
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);
1210                     offset += 1;
1211                     losc -= 1;
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);
1214                     offset += 1;
1215                     losc -= 1;
1216                 }
1217
1218                 if (losc >= 2) {
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);
1221
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);
1224                     offset += 1;
1225                     losc -= 1;
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);
1228                     offset += 1;
1229                     losc  -= 1;
1230                 }
1231
1232                 if (losc >= 2) {
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);
1235
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);
1238                     offset += 1;
1239                     losc -= 1;
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);
1242                     offset += 1;
1243                     losc -= 1;
1244                 }
1245                 break;
1246             default:
1247                 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1248                 offset += losc;
1249                 losc = 0;
1250         }
1251
1252         if (losc > 0) {
1253             pitem = proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1254             offset += losc;
1255
1256             expert_add_info(pinfo, pitem, &ei_btavdtp_unexpected_losc_data);
1257         }
1258     }
1259
1260     return offset;
1261 }
1262
1263 static gint
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)
1268 {
1269     guint32      seid;
1270     proto_tree  *seid_tree     = NULL;
1271     proto_item  *seid_item     = NULL;
1272     guint32      direction;
1273
1274     seid = tvb_get_guint8(tvb, offset) >> 2;
1275     if (sep_seid) {
1276         *sep_seid = seid;
1277     }
1278
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);
1288
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));
1292     } else {
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);
1301
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));
1305     }
1306
1307     proto_tree_add_item(seid_tree, hf_btavdtp_rfa_seid, tvb, offset, 1, ENC_NA);
1308     offset += 1;
1309
1310     return offset;
1311 }
1312
1313
1314 static gint
1315 dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1316 {
1317     proto_item       *ti;
1318     proto_tree       *btavdtp_tree       = NULL;
1319     proto_tree       *signal_tree        = NULL;
1320     proto_item       *signal_item        = NULL;
1321     btl2cap_data_t   *l2cap_data;
1322     gint             offset = 0;
1323     gint             i_sep         = 1;
1324     gint             packet_type   = 0;
1325     gint             message_type  = 0;
1326     gint             signal_id     = 0;
1327     guint            delay;
1328     wmem_tree_t      *subtree;
1329     wmem_tree_key_t  key[8];
1330     channels_info_t  *channels_info;
1331     guint32          interface_id;
1332     guint32          adapter_id;
1333     guint32          chandle;
1334     guint32          psm;
1335     guint32          direction;
1336     guint32          cid;
1337     guint32          frame_number;
1338     sep_entry_t      *sep;
1339     tvbuff_t         *next_tvb;
1340     guint32          seid;
1341     gint             codec = -1;
1342     gint             content_protection_type = 0;
1343     guint32          configuration_offset;
1344     guint8           configuration_length;
1345
1346     col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP");
1347
1348     direction = pinfo->p2p_dir;
1349     switch (direction) {
1350         case P2P_DIR_SENT:
1351             col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
1352             break;
1353
1354         case P2P_DIR_RECV:
1355             col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
1356             break;
1357         default:
1358             col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
1359             goto LABEL_data;
1360     }
1361
1362     l2cap_data = (btl2cap_data_t *) data;
1363     DISSECTOR_ASSERT(l2cap_data);
1364
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;
1371
1372     key[0].length = 1;
1373     key[0].key    = &interface_id;
1374     key[1].length = 1;
1375     key[1].key    = &adapter_id;
1376     key[2].length = 1;
1377     key[2].key    = &chandle;
1378     key[3].length = 1;
1379     key[3].key    = &psm;
1380     key[4].length = 0;
1381     key[4].key    = NULL;
1382
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)))) {
1394
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;
1405
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)) {
1411             key[4].length = 1;
1412             key[4].key    = &frame_number;
1413             key[5].length = 0;
1414             key[5].key    = NULL;
1415
1416             channels_info->stream_numbers = wmem_tree_new(wmem_file_scope());
1417
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);
1423             }
1424         } else {
1425             channels_info->stream_numbers = NULL;
1426         }
1427     }
1428
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))) {
1434
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;
1438         }
1439         /* Media Channel */
1440
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);
1444
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);
1447         } else {
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,
1452                             frame_number),
1453                     get_sep_type(interface_id, adapter_id, chandle, direction,
1454                             channels_info->sep->seid,
1455                             frame_number));
1456
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;
1466
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;
1477
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;
1483
1484                     if (!pinfo->fd->flags.visited)
1485                         media_stream_number_value->stream_end_in_frame = pinfo->num;
1486
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;
1489                 } else {
1490                     sep_data.stream_number = 1;
1491                 }
1492
1493                 key[0].length = 1;
1494                 key[0].key    = &interface_id;
1495                 key[1].length = 1;
1496                 key[1].key    = &adapter_id;
1497                 key[3].length = 1;
1498                 key[3].key    = &cid;
1499                 key[4].length = 1;
1500                 key[4].key    = &direction;
1501                 key[5].length = 0;
1502                 key[5].key    = NULL;
1503
1504                 key[2].length = 0;
1505                 key[2].key    = NULL;
1506
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;
1514                 }
1515
1516                 key[2].length = 1;
1517                 key[2].key    = &chandle;
1518
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;
1527                     else
1528                         previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1529                 } else {
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;
1540                 }
1541
1542                 if (!pinfo->fd->flags.visited) {
1543                     key[5].length = 1;
1544                     key[5].key    = &frame_number;
1545                     key[6].length = 0;
1546                     key[6].key    = NULL;
1547
1548                     if (avrcp_song_position == -1.0)
1549                         avrcp_song_position = 0.0;
1550
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;
1557
1558                     wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info);
1559                 }
1560
1561                 key[5].length = 0;
1562                 key[5].key    = NULL;
1563
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;
1568                 else
1569                     sep_data.current_media_packet_info = NULL;
1570
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;
1576
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;
1587
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;
1591                 } else {
1592                     sep_data.stream_number = 1;
1593                 }
1594
1595                 next_tvb = tvb_new_subset_remaining(tvb, offset);
1596                 call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data);
1597             } else {
1598                 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1599                 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1600
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);
1603             }
1604         }
1605
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);
1612
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);
1616     }
1617
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);
1621
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;
1625
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);
1629
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);
1633
1634     if (packet_type == PACKET_TYPE_START) {
1635         offset += 1;
1636         proto_tree_add_item(signal_tree, hf_btavdtp_number_of_signal_packets, tvb, offset, 1, ENC_NA);
1637     }
1638
1639     if (packet_type == PACKET_TYPE_CONTINUE || packet_type == PACKET_TYPE_END) goto LABEL_data;
1640
1641     offset += 1;
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);
1644
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"));
1649
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"));
1653
1654     offset += 1;
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);
1660                 offset += 1;
1661                 break;
1662             }
1663             offset = dissect_sep(tvb, pinfo, btavdtp_tree, offset,
1664                     interface_id, adapter_id, chandle);
1665             break;
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);
1672                 break;
1673             }
1674             if (message_type == MESSAGE_TYPE_REJECT) {
1675                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1676                 offset += 1;
1677                 break;
1678             }
1679             offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1680             break;
1681         case SIGNAL_ID_SET_CONFIGURATION:
1682             if (message_type == MESSAGE_TYPE_COMMAND) {
1683                 guint32  int_seid;
1684                 guint32  vendor_id;
1685                 guint16  vendor_codec;
1686                 guint32  reverse_direction;
1687
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);
1697
1698                 if (!pinfo->fd->flags.visited) {
1699                     key[0].length = 1;
1700                     key[0].key    = &interface_id;
1701                     key[1].length = 1;
1702                     key[1].key    = &adapter_id;
1703                     key[2].length = 1;
1704                     key[2].key    = &chandle;
1705                     key[3].length = 1;
1706                     key[3].key    = &direction;
1707                     key[4].length = 1;
1708                     key[4].key    = &seid;
1709                     key[5].length = 0;
1710                     key[5].key    = NULL;
1711
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;
1714                     if (sep) {
1715                         sep->codec = codec;
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);
1724                         }
1725
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;
1730                         else
1731                             reverse_direction = P2P_DIR_UNKNOWN;
1732
1733                         key[3].length = 1;
1734                         key[3].key    = &reverse_direction;
1735                         key[4].length = 1;
1736                         key[4].key    = &int_seid;
1737                         key[5].length = 1;
1738                         key[5].key    = &frame_number;
1739                         key[6].length = 0;
1740                         key[6].key    = NULL;
1741
1742                         wmem_tree_insert32_array(sep_list, key, sep);
1743                     }
1744
1745                 }
1746
1747                 break;
1748             }
1749             if (message_type == MESSAGE_TYPE_REJECT) {
1750                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1751                 offset += 1;
1752
1753                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1754                 offset += 1;
1755                 break;
1756             }
1757             break;
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);
1763                 break;
1764             }
1765             if (message_type == MESSAGE_TYPE_REJECT) {
1766                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1767                 offset += 1;
1768                 break;
1769             }
1770             offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1771             break;
1772         case SIGNAL_ID_RECONFIGURE:
1773             if (message_type == MESSAGE_TYPE_COMMAND) {
1774                 guint32  vendor_id;
1775                 guint16  vendor_codec;
1776
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);
1783
1784                 if (!pinfo->fd->flags.visited) {
1785                     key[0].length = 1;
1786                     key[0].key    = &interface_id;
1787                     key[1].length = 1;
1788                     key[1].key    = &adapter_id;
1789                     key[2].length = 1;
1790                     key[2].key    = &chandle;
1791                     key[3].length = 1;
1792                     key[3].key    = &direction;
1793                     key[4].length = 1;
1794                     key[4].key    = &seid;
1795                     key[5].length = 0;
1796                     key[5].key    = NULL;
1797
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;
1800                     if (sep) {
1801                         sep->codec = codec;
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);
1809                         }
1810                     }
1811                 }
1812
1813                 break;
1814             }
1815             if (message_type == MESSAGE_TYPE_REJECT) {
1816                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1817                 offset += 1;
1818
1819                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1820                 offset += 1;
1821                 break;
1822             }
1823             break;
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);
1829
1830                 if (!pinfo->fd->flags.visited) {
1831                     key[0].length = 1;
1832                     key[0].key    = &interface_id;
1833                     key[1].length = 1;
1834                     key[1].key    = &adapter_id;
1835                     key[2].length = 1;
1836                     key[2].key    = &chandle;
1837                     key[3].length = 1;
1838                     key[3].key    = &direction;
1839                     key[4].length = 1;
1840                     key[4].key    = &seid;
1841                     key[5].length = 0;
1842                     key[5].key    = NULL;
1843
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;
1846                     if (sep) {
1847                         sep->state = SEP_STATE_OPEN;
1848
1849                         key[3].length = 1;
1850                         key[3].key    = &frame_number;
1851                         key[4].length = 0;
1852                         key[4].key    = NULL;
1853
1854                         wmem_tree_insert32_array(sep_open, key, sep);
1855                     }
1856                 }
1857                 break;
1858             }
1859             if (message_type == MESSAGE_TYPE_REJECT) {
1860                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1861                 offset += 1;
1862                 break;
1863             }
1864             if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->flags.visited) {
1865
1866                 key[0].length = 1;
1867                 key[0].key    = &interface_id;
1868                 key[1].length = 1;
1869                 key[1].key    = &adapter_id;
1870                 key[2].length = 1;
1871                 key[2].key    = &chandle;
1872                 key[3].length = 0;
1873                 key[3].key    = NULL;
1874
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;
1880                 }
1881             }
1882             break;
1883         case SIGNAL_ID_START:
1884             if (message_type == MESSAGE_TYPE_COMMAND) {
1885                 i_sep = 1;
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);
1890                     i_sep += 1;
1891                 }
1892                 break;
1893             }
1894             if (message_type == MESSAGE_TYPE_REJECT) {
1895                 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1896                         SEID_ACP, 0, NULL,
1897                         interface_id, adapter_id, chandle, frame_number);
1898                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1899                 offset += 1;
1900                 break;
1901             }
1902
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;
1906
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
1909                 {
1910                     media_stream_number_value_t  *file_scope_stream_number_value;
1911
1912                     if (media_stream_number_value) {
1913                         stream_number = media_stream_number_value->stream_number;
1914                     } else {
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;
1918                         else
1919                             stream_number = 0;
1920                     }
1921
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);
1925                 }
1926 #else
1927                 if (media_stream_number_value)
1928                     stream_number = media_stream_number_value->stream_number;
1929                 else
1930                     stream_number = 0;
1931 #endif
1932
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;
1937
1938                 wmem_tree_insert32(channels_info->stream_numbers, frame_number, media_stream_number_value);
1939             }
1940             break;
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);
1946                 break;
1947             }
1948             if (message_type == MESSAGE_TYPE_REJECT) {
1949                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1950                 offset += 1;
1951                 break;
1952             }
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;
1956             }
1957             break;
1958         case SIGNAL_ID_SUSPEND:
1959             if (message_type == MESSAGE_TYPE_COMMAND) {
1960                 i_sep = 1;
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);
1965                     i_sep += 1;
1966                 }
1967                 break;
1968             }
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);
1974                 offset += 1;
1975                 break;
1976             }
1977             break;
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);
1983                 break;
1984             }
1985             if (message_type == MESSAGE_TYPE_REJECT) {
1986                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1987                 offset += 1;
1988                 break;
1989             }
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;
1993             }
1994             break;
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);
2002                 break;
2003             }
2004             if (message_type == MESSAGE_TYPE_REJECT) {
2005                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2006                 offset += 1;
2007                 break;
2008             }
2009
2010             proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2011             offset += tvb_reported_length_remaining(tvb, offset);
2012             break;
2013         case SIGNAL_ID_DELAY_REPORT:
2014             if (message_type == MESSAGE_TYPE_COMMAND) {
2015                 proto_item  *pitem;
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,
2019                         SEID_ACP, 0, NULL,
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)");
2023                 offset += 2;
2024                 break;
2025             }
2026             if (message_type == MESSAGE_TYPE_REJECT) {
2027                 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2028                 offset += 1;
2029                 break;
2030             }
2031             break;
2032     }
2033
2034     LABEL_data:
2035
2036     if (tvb_reported_length_remaining(tvb, offset) > 0) {
2037         proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2038     }
2039
2040     return offset;
2041 }
2042
2043
2044 void
2045 proto_register_btavdtp(void)
2046 {
2047     module_t *module;
2048
2049     static hf_register_info hf[] = {
2050         { &hf_btavdtp_signal,
2051             { "Signal",                   "btavdtp.signal",
2052             FT_NONE, BASE_NONE, NULL, 0x00,
2053             NULL, HFILL }
2054         },
2055         { &hf_btavdtp_message_type,
2056             { "Message Type",                   "btavdtp.message_type",
2057             FT_UINT8, BASE_HEX, VALS(message_type_vals), AVDTP_MESSAGE_TYPE_MASK,
2058             NULL, HFILL }
2059         },
2060         { &hf_btavdtp_packet_type,
2061             { "Packet Type",                    "btavdtp.packet_type",
2062             FT_UINT8, BASE_HEX, VALS(packet_type_vals), AVDTP_PACKET_TYPE_MASK,
2063             NULL, HFILL }
2064         },
2065         { &hf_btavdtp_transaction,
2066             { "Transaction",                    "btavdtp.transaction",
2067             FT_UINT8, BASE_HEX, NULL, AVDTP_TRANSACTION_MASK,
2068             NULL, HFILL }
2069         },
2070         { &hf_btavdtp_signal_id,
2071             { "Signal",                         "btavdtp.signal_id",
2072             FT_UINT8, BASE_HEX, VALS(signal_id_vals), AVDTP_SIGNAL_ID_MASK,
2073             NULL, HFILL }
2074         },
2075         { &hf_btavdtp_rfa0,
2076             { "RFA",                            "btavdtp.rfa0",
2077             FT_UINT8, BASE_HEX, NULL, AVDTP_RFA0_MASK,
2078             NULL, HFILL }
2079         },
2080         { &hf_btavdtp_number_of_signal_packets,
2081             { "Number of signal packets",       "btavdtp.num_signal_packets",
2082             FT_UINT8, BASE_DEC, NULL, 0,
2083             NULL, HFILL }
2084         },
2085         { &hf_btavdtp_error_code,
2086             { "Error Code",                     "btavdtp.error_code",
2087             FT_UINT8, BASE_HEX, VALS(error_code_vals), 0x00,
2088             NULL, HFILL }
2089         },
2090         { &hf_btavdtp_sep_seid,
2091             { "SEID",                           "btavdtp.sep_seid",
2092             FT_UINT8, BASE_DEC, NULL, 0xFC,
2093             NULL, HFILL }
2094         },
2095         { &hf_btavdtp_sep_inuse,
2096             { "In Use",                         "btavdtp.sep_inuse",
2097             FT_UINT8, BASE_HEX, VALS(true_false), 0x02,
2098             NULL, HFILL }
2099         },
2100         { &hf_btavdtp_sep_rfa0,
2101             { "RFA0",                           "btavdtp.sep_rfa0",
2102             FT_UINT8, BASE_HEX, NULL, 0x01,
2103             NULL, HFILL }
2104         },
2105         { &hf_btavdtp_sep_media_type,
2106             { "Media Type",                     "btavdtp.sep_media_type",
2107             FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2108             NULL, HFILL }
2109         },
2110         { &hf_btavdtp_sep_type,
2111             { "Type",                           "btavdtp.sep_type",
2112             FT_UINT8, BASE_HEX, VALS(sep_type_vals), 0x08,
2113             NULL, HFILL }
2114         },
2115         { &hf_btavdtp_sep_rfa1,
2116             { "RFA1",                           "btavdtp.sep_rfa1",
2117             FT_UINT8, BASE_HEX, NULL, 0x07,
2118             NULL, HFILL }
2119         },
2120         { &hf_btavdtp_acp_sep,
2121             { "ACP SEP",                        "btavdtp.acp_sep",
2122             FT_NONE, BASE_NONE, NULL, 0x00,
2123             NULL, HFILL }
2124         },
2125         { &hf_btavdtp_acp_seid_item,
2126             { "ACP SEID",                       "btavdtp.acp_seid_item",
2127             FT_NONE, BASE_NONE, NULL, 0x00,
2128             NULL, HFILL }
2129         },
2130         { &hf_btavdtp_int_seid_item,
2131             { "INT SEID",                       "btavdtp.int_seid_item",
2132             FT_NONE, BASE_NONE, NULL, 0x00,
2133             NULL, HFILL }
2134         },
2135         { &hf_btavdtp_acp_seid,
2136             { "ACP SEID",                       "btavdtp.acp_seid",
2137             FT_UINT8, BASE_DEC, NULL, 0xFC,
2138             NULL, HFILL }
2139         },
2140         { &hf_btavdtp_int_seid,
2141             { "INT SEID",                       "btavdtp.int_seid",
2142             FT_UINT8, BASE_DEC, NULL, 0xFC,
2143             NULL, HFILL }
2144         },
2145         { &hf_btavdtp_rfa_seid,
2146             { "RFA",                            "btavdtp.rfa_seid",
2147             FT_UINT8, BASE_HEX, NULL, 0x03,
2148             NULL, HFILL }
2149         },
2150         { &hf_btavdtp_service_category,
2151             { "Service Category",               "btavdtp.service_category",
2152             FT_UINT8, BASE_HEX, VALS(service_category_vals), 0x00,
2153             NULL, HFILL }
2154         },
2155         { &hf_btavdtp_length_of_service_category,
2156             { "Length of Service Category",     "btavdtp.length_of_service_category",
2157             FT_UINT8, BASE_HEX, NULL, 0x00,
2158             NULL, HFILL }
2159         },
2160         { &hf_btavdtp_delay,
2161             { "Delay",                          "btavdtp.delay",
2162             FT_UINT16, BASE_DEC, NULL, 0x00,
2163             NULL, HFILL }
2164         },
2165         { &hf_btavdtp_recovery_type,
2166             { "Service Category",               "btavdtp.recovery_type",
2167             FT_UINT8, BASE_HEX, VALS(recovery_type_vals), 0x00,
2168             NULL, HFILL }
2169         },
2170         { &hf_btavdtp_maximum_recovery_window_size,
2171             { "Service Category",               "btavdtp.maximum_recovery_window_size",
2172             FT_UINT8, BASE_HEX, NULL, 0x00,
2173             NULL, HFILL }
2174         },
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,
2178             NULL, HFILL }
2179         },
2180         { &hf_btavdtp_multiplexing_fragmentation,
2181             { "Fragmentation",                  "btavdtp.multiplexing_fragmentation",
2182             FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2183             NULL, HFILL }
2184         },
2185         { &hf_btavdtp_multiplexing_rfa,
2186             { "RFA",                            "btavdtp.multiplexing_rfa",
2187             FT_UINT8, BASE_HEX, NULL, 0x7F,
2188             NULL, HFILL }
2189         },
2190         { &hf_btavdtp_multiplexing_tsid,
2191             { "TSID",                           "btavdtp.multiplexing_tsid",
2192             FT_UINT8, BASE_HEX, VALS(multiplexing_tsid_vals), 0xF8,
2193             NULL, HFILL }
2194         },
2195         { &hf_btavdtp_multiplexing_tcid,
2196             { "TCID",                           "btavdtp.multiplexing_tcid",
2197             FT_UINT8, BASE_HEX, VALS(multiplexing_tcid_vals), 0xF8,
2198             NULL, HFILL }
2199         },
2200         { &hf_btavdtp_multiplexing_entry_rfa,
2201             { "RFA",                            "btavdtp.multiplexing_entry_rfa",
2202             FT_UINT8, BASE_HEX, NULL, 0x07,
2203             NULL, HFILL }
2204         },
2205         { &hf_btavdtp_header_compression_backch,
2206             { "BackCh",                         "btavdtp.header_compression_backch",
2207             FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2208             NULL, HFILL }
2209         },
2210         { &hf_btavdtp_header_compression_media,
2211             { "Media",                          "btavdtp.header_compression_media",
2212             FT_UINT8, BASE_HEX, VALS(true_false), 0x40,
2213             NULL, HFILL }
2214         },
2215         { &hf_btavdtp_header_compression_recovery,
2216             { "Recovery",                       "btavdtp.header_compression_recovery",
2217             FT_UINT8, BASE_HEX, VALS(true_false), 0x20,
2218             NULL, HFILL }
2219         },
2220         { &hf_btavdtp_header_compression_rfa,
2221             { "RFA",                            "btavdtp.header_compression_rfa",
2222             FT_UINT8, BASE_HEX, NULL, 0x1f,
2223             NULL, HFILL }
2224         },
2225         { &hf_btavdtp_content_protection_type,
2226             { "Type",                           "btavdtp.content_protection_type",
2227             FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
2228             NULL, HFILL }
2229         },
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,
2233             NULL, HFILL }
2234         },
2235         { &hf_btavdtp_media_codec_rfa,
2236             { "RFA",                            "btavdtp.media_codec_rfa",
2237             FT_UINT8, BASE_HEX, NULL, 0x0F,
2238             NULL, HFILL }
2239         },
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,
2243             NULL, HFILL }
2244         },
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,
2248             NULL, HFILL }
2249         },
2250         { &hf_btavdtp_media_codec_unknown_type,
2251             { "Media Codec Unknown Type",       "btavdtp.media_codec_unknown_type",
2252             FT_UINT8, BASE_HEX, NULL, 0x00,
2253             NULL, HFILL }
2254         },
2255         { &hf_btavdtp_sbc_sampling_frequency_16000,
2256             { "Sampling Frequency 16000 Hz",    "btavdtp.codec.sbc.sampling_frequency.16000",
2257             FT_BOOLEAN, 8, NULL, 0x80,
2258             NULL, HFILL }
2259         },
2260         { &hf_btavdtp_sbc_sampling_frequency_32000,
2261             { "Sampling Frequency 32000 Hz",    "btavdtp.codec.sbc.sampling_frequency.32000",
2262             FT_BOOLEAN, 8, NULL, 0x40,
2263             NULL, HFILL }
2264         },
2265         { &hf_btavdtp_sbc_sampling_frequency_44100,
2266             { "Sampling Frequency 44100 Hz",    "btavdtp.codec.sbc.sampling_frequency.44100",
2267             FT_BOOLEAN, 8, NULL, 0x20,
2268             NULL, HFILL }
2269         },
2270         { &hf_btavdtp_sbc_sampling_frequency_48000,
2271             { "Sampling Frequency 48000 Hz",    "btavdtp.codec.sbc.sampling_frequency.48000",
2272             FT_BOOLEAN, 8, NULL, 0x10,
2273             NULL, HFILL }
2274         },
2275         { &hf_btavdtp_sbc_channel_mode_mono,
2276             { "Channel Mode Mono",              "btavdtp.codec.sbc.channel_mode.mono",
2277             FT_BOOLEAN, 8, NULL, 0x08,
2278             NULL, HFILL }
2279         },
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,
2283             NULL, HFILL }
2284         },
2285         { &hf_btavdtp_sbc_channel_mode_stereo,
2286             { "Channel Mode Stereo",            "btavdtp.codec.sbc.channel_mode.stereo",
2287             FT_BOOLEAN, 8, NULL, 0x02,
2288             NULL, HFILL }
2289         },
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,
2293             NULL, HFILL }
2294         },
2295         { &hf_btavdtp_sbc_block_4,
2296             { "Block Length 4",                 "btavdtp.codec.sbc.block.4",
2297             FT_BOOLEAN, 8, NULL, 0x80,
2298             NULL, HFILL }
2299         },
2300         { &hf_btavdtp_sbc_block_8,
2301             { "Block Length 8",                 "btavdtp.codec.sbc.block.8",
2302             FT_BOOLEAN, 8, NULL, 0x40,
2303             NULL, HFILL }
2304         },
2305         { &hf_btavdtp_sbc_block_12,
2306             { "Block Length 12",                "btavdtp.codec.sbc.block.12",
2307             FT_BOOLEAN, 8, NULL, 0x20,
2308             NULL, HFILL }
2309         },
2310         { &hf_btavdtp_sbc_block_16,
2311             { "Block Length 16",                "btavdtp.codec.sbc.block.16",
2312             FT_BOOLEAN, 8, NULL, 0x10,
2313             NULL, HFILL }
2314         },
2315         { &hf_btavdtp_sbc_subbands_4,
2316             { "Subbands 4",                     "btavdtp.codec.sbc.subbands.4",
2317             FT_BOOLEAN, 8, NULL, 0x08,
2318             NULL, HFILL }
2319         },
2320         { &hf_btavdtp_sbc_subbands_8,
2321             { "Subbands 8",                     "btavdtp.codec.sbc.subbands.8",
2322             FT_BOOLEAN, 8, NULL, 0x04,
2323             NULL, HFILL }
2324         },
2325         { &hf_btavdtp_sbc_allocation_method_snr,
2326             { "Allocation Method SNR",          "btavdtp.codec.sbc.allocation_method.snr",
2327             FT_BOOLEAN, 8, NULL, 0x02,
2328             NULL, HFILL }
2329         },
2330         { &hf_btavdtp_sbc_allocation_method_loudness,
2331             { "Allocation Method Loudness",     "btavdtp.codec.sbc.allocation_method.loudness",
2332             FT_BOOLEAN, 8, NULL, 0x01,
2333             NULL, HFILL }
2334         },
2335         { &hf_btavdtp_sbc_min_bitpool,
2336             { "Minimum Bitpool",                "btavdtp.codec.sbc.minimum_bitpool",
2337             FT_UINT8, BASE_DEC, NULL, 0x00,
2338             NULL, HFILL }
2339         },
2340         { &hf_btavdtp_sbc_max_bitpool,
2341             { "Maximum Bitpool",                "btavdtp.codec.sbc.maximum_bitpool",
2342             FT_UINT8, BASE_DEC, NULL, 0x00,
2343             NULL, HFILL }
2344         },
2345         { &hf_btavdtp_mpeg12_layer_1,
2346             { "MP1",                            "btavdtp.codec.mpeg12.layer_1",
2347             FT_BOOLEAN, 8, NULL, 0x80,
2348             "MPEG Layer 1", HFILL }
2349         },
2350         { &hf_btavdtp_mpeg12_layer_2,
2351             { "MP2",                            "btavdtp.codec.mpeg12.layer_2",
2352             FT_BOOLEAN, 8, NULL, 0x40,
2353             "MPEG Layer 2", HFILL }
2354         },
2355         { &hf_btavdtp_mpeg12_layer_3,
2356             { "MP3",                            "btavdtp.codec.mpeg12.layer_3",
2357             FT_BOOLEAN, 8, NULL, 0x20,
2358             "MPEG Layer 3", HFILL }
2359         },
2360         { &hf_btavdtp_mpeg12_crc_protection,
2361             { "CRC Protection",                 "btavdtp.codec.mpeg12.crc_protection",
2362             FT_BOOLEAN, 8, NULL, 0x10,
2363             NULL, HFILL }
2364         },
2365         { &hf_btavdtp_mpeg12_channel_mode_mono,
2366             { "Channel Mode Mono",              "btavdtp.codec.mpeg12.channel_mode.mono",
2367             FT_BOOLEAN, 8, NULL, 0x08,
2368             NULL, HFILL }
2369         },
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,
2373             NULL, HFILL }
2374         },
2375         { &hf_btavdtp_mpeg12_channel_mode_stereo,
2376             { "Channel Mode Stereo",            "btavdtp.codec.mpeg12.channel_mode.stereo",
2377             FT_BOOLEAN, 8, NULL, 0x02,
2378             NULL, HFILL }
2379         },
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,
2383             NULL, HFILL }
2384         },
2385         { &hf_btavdtp_mpeg12_rfa,
2386             { "RFA",                            "btavdtp.codec.mpeg12.rfa",
2387             FT_BOOLEAN, 8, NULL, 0x80,
2388             NULL, HFILL }
2389         },
2390         { &hf_btavdtp_mpeg12_mpf_2,
2391             { "Media Payload Format 2",         "btavdtp.codec.mpeg12.mpf_2",
2392             FT_BOOLEAN, 8, NULL, 0x40,
2393             NULL, HFILL }
2394         },
2395         { &hf_btavdtp_mpeg12_sampling_frequency_16000,
2396             { "Sampling Frequency 16000 Hz",    "btavdtp.codec.sbc.sampling_frequency.16000",
2397             FT_BOOLEAN, 8, NULL, 0x20,
2398             NULL, HFILL }
2399         },
2400         { &hf_btavdtp_mpeg12_sampling_frequency_22050,
2401             { "Sampling Frequency 22050 Hz",    "btavdtp.codec.sbc.sampling_frequency.22050",
2402             FT_BOOLEAN, 8, NULL, 0x10,
2403             NULL, HFILL }
2404         },
2405         { &hf_btavdtp_mpeg12_sampling_frequency_24000,
2406             { "Sampling Frequency 24000 Hz",    "btavdtp.codec.sbc.sampling_frequency.24000",
2407             FT_BOOLEAN, 8, NULL, 0x08,
2408             NULL, HFILL }
2409         },
2410         { &hf_btavdtp_mpeg12_sampling_frequency_32000,
2411             { "Sampling Frequency 32000 Hz",    "btavdtp.codec.sbc.sampling_frequency.32000",
2412             FT_BOOLEAN, 8, NULL, 0x04,
2413             NULL, HFILL }
2414         },
2415         { &hf_btavdtp_mpeg12_sampling_frequency_44100,
2416             { "Sampling Frequency 44100 Hz",    "btavdtp.codec.sbc.sampling_frequency.44100",
2417             FT_BOOLEAN, 8, NULL, 0x02,
2418             NULL, HFILL }
2419         },
2420         { &hf_btavdtp_mpeg12_sampling_frequency_48000,
2421             { "Sampling Frequency 48000 Hz",    "btavdtp.codec.sbc.sampling_frequency.48000",
2422             FT_BOOLEAN, 8, NULL, 0x01,
2423             NULL, HFILL }
2424         },
2425         { &hf_btavdtp_mpeg12_vbr_supported,
2426             { "VBR Supported",                  "btavdtp.codec.mpeg12.vbr",
2427             FT_BOOLEAN, 16, NULL, 0x8000,
2428             NULL, HFILL }
2429         },
2430         { &hf_btavdtp_mpeg12_bit_rate,
2431             { "Bit Rate",                       "btavdtp.codec.mpeg12.bit_rate",
2432             FT_UINT16, BASE_HEX, NULL, 0x7FFF,
2433             NULL, HFILL }
2434         },
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,
2438             NULL, HFILL }
2439         },
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,
2443             NULL, HFILL }
2444         },
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,
2448             NULL, HFILL }
2449         },
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,
2453             NULL, HFILL }
2454         },
2455         { &hf_btavdtp_mpeg24_object_type_rfa,
2456             { "RFA",                            "btavdtp.codec.mpeg24.object_type.rfa",
2457             FT_UINT8, BASE_HEX, NULL, 0x0F,
2458             NULL, HFILL }
2459         },
2460         { &hf_btavdtp_mpeg24_sampling_frequency_8000,
2461             { "Sampling Frequency 8000 Hz",     "btavdtp.codec.mpeg24.sampling_frequency.8000",
2462             FT_BOOLEAN, 8, NULL, 0x80,
2463             NULL, HFILL }
2464         },
2465         { &hf_btavdtp_mpeg24_sampling_frequency_11025,
2466             { "Sampling Frequency 11025 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.11025",
2467             FT_BOOLEAN, 8, NULL, 0x40,
2468             NULL, HFILL }
2469         },
2470         { &hf_btavdtp_mpeg24_sampling_frequency_12000,
2471             { "Sampling Frequency 12000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.12000",
2472             FT_BOOLEAN, 8, NULL, 0x20,
2473             NULL, HFILL }
2474         },
2475         { &hf_btavdtp_mpeg24_sampling_frequency_16000,
2476             { "Sampling Frequency 16000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.16000",
2477             FT_BOOLEAN, 8, NULL, 0x10,
2478             NULL, HFILL }
2479         },
2480         { &hf_btavdtp_mpeg24_sampling_frequency_22050,
2481             { "Sampling Frequency 22050 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.22050",
2482             FT_BOOLEAN, 8, NULL, 0x08,
2483             NULL, HFILL }
2484         },
2485         { &hf_btavdtp_mpeg24_sampling_frequency_24000,
2486             { "Sampling Frequency 24000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.24000",
2487             FT_BOOLEAN, 8, NULL, 0x04,
2488             NULL, HFILL }
2489         },
2490         { &hf_btavdtp_mpeg24_sampling_frequency_32000,
2491             { "Sampling Frequency 32000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.32000",
2492             FT_BOOLEAN, 8, NULL, 0x02,
2493             NULL, HFILL }
2494         },
2495         { &hf_btavdtp_mpeg24_sampling_frequency_44100,
2496             { "Sampling Frequency 44100 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.44100",
2497             FT_BOOLEAN, 8, NULL, 0x01,
2498             NULL, HFILL }
2499         },
2500         { &hf_btavdtp_mpeg24_sampling_frequency_48000,
2501             { "Sampling Frequency 48000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.48000",
2502             FT_BOOLEAN, 8, NULL, 0x80,
2503             NULL, HFILL }
2504         },
2505         { &hf_btavdtp_mpeg24_sampling_frequency_64000,
2506             { "Sampling Frequency 64000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.64000",
2507             FT_BOOLEAN, 8, NULL, 0x40,
2508             NULL, HFILL }
2509         },
2510         { &hf_btavdtp_mpeg24_sampling_frequency_88200,
2511             { "Sampling Frequency 88200 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.88200",
2512             FT_BOOLEAN, 8, NULL, 0x20,
2513             NULL, HFILL }
2514         },
2515         { &hf_btavdtp_mpeg24_sampling_frequency_96000,
2516             { "Sampling Frequency 96000 Hz",    "btavdtp.codec.mpeg24.sampling_frequency.96000",
2517             FT_BOOLEAN, 8, NULL, 0x10,
2518             NULL, HFILL }
2519         },
2520         { &hf_btavdtp_mpeg24_channels_1,
2521             { "Channels 1",                     "btavdtp.codec.mpeg24.channels.1",
2522             FT_BOOLEAN, 8, NULL, 0x08,
2523             NULL, HFILL }
2524         },
2525         { &hf_btavdtp_mpeg24_channels_2,
2526             { "Channels 2",                     "btavdtp.codec.mpeg24.channels.2",
2527             FT_BOOLEAN, 8, NULL, 0x04,
2528             NULL, HFILL }
2529         },
2530         { &hf_btavdtp_mpeg24_rfa,
2531             { "RFA",                            "btavdtp.codec.mpeg24.rfa",
2532             FT_UINT8, BASE_HEX, NULL, 0x03,
2533             NULL, HFILL }
2534         },
2535         { &hf_btavdtp_mpeg24_vbr_supported,
2536             { "VBR Supported",                  "btavdtp.codec.mpeg24.vbr",
2537             FT_BOOLEAN, 24, NULL, 0x800000,
2538             NULL, HFILL }
2539         },
2540         { &hf_btavdtp_mpeg24_bit_rate,
2541             { "Bit Rate",                       "btavdtp.codec.mpeg24.bit_rate",
2542             FT_UINT24, BASE_HEX, NULL, 0x7FFFFF,
2543             NULL, HFILL }
2544         },
2545         { &hf_btavdtp_atrac_version,
2546             { "Version",                        "btavdtp.codec.atrac.version",
2547             FT_UINT8, BASE_DEC, NULL, 0xE0,
2548             NULL, HFILL }
2549         },
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,
2553             NULL, HFILL }
2554         },
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,
2558             NULL, HFILL }
2559         },
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,
2563             NULL, HFILL }
2564         },
2565         { &hf_btavdtp_atrac_rfa1,
2566             { "RFA",                            "btavdtp.codec.atrac.rfa1",
2567             FT_UINT8, BASE_HEX, NULL, 0x03,
2568             NULL, HFILL }
2569         },
2570         { &hf_btavdtp_atrac_rfa2,
2571             { "RFA",                            "btavdtp.codec.atrac.rfa2",
2572             FT_UINT24, BASE_HEX, NULL, 0xC00000,
2573             NULL, HFILL }
2574         },
2575         { &hf_btavdtp_atrac_sampling_frequency_44100,
2576             { "Sampling Frequency 44100 Hz",    "btavdtp.codec.sbc.sampling_frequency.44100",
2577             FT_BOOLEAN, 24, NULL, 0x200000,
2578             NULL, HFILL }
2579         },
2580         { &hf_btavdtp_atrac_sampling_frequency_48000,
2581             { "Sampling Frequency 48000 Hz",    "btavdtp.codec.sbc.sampling_frequency.48000",
2582             FT_BOOLEAN, 24, NULL, 0x100000,
2583             NULL, HFILL }
2584         },
2585         { &hf_btavdtp_atrac_vbr_supported,
2586             { "VBR Supported",                  "btavdtp.codec.atrac.vbr",
2587             FT_BOOLEAN, 24, NULL, 0x080000,
2588             NULL, HFILL }
2589         },
2590         { &hf_btavdtp_atrac_bit_rate,
2591             { "Bit Rate",                       "btavdtp.codec.atrac.bit_rate",
2592             FT_UINT24, BASE_HEX, NULL, 0x07FFFF,
2593             NULL, HFILL }
2594         },
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 }
2599         },
2600         { &hf_btavdtp_atrac_rfa3,
2601             { "RFA",                            "btavdtp.codec.atrac.rfa3",
2602             FT_UINT8, BASE_HEX, NULL, 0x00,
2603             NULL, HFILL }
2604         },
2605         { &hf_btavdtp_h263_level_10,
2606             { "H264 Level 10",                  "btavdtp.codec.h264.level.10",
2607             FT_BOOLEAN, 8, NULL, 0x80,
2608             NULL, HFILL }
2609         },
2610         { &hf_btavdtp_h263_level_20,
2611             { "H264 Level 20",                  "btavdtp.codec.h264.level.20",
2612             FT_BOOLEAN, 8, NULL, 0x40,
2613             NULL, HFILL }
2614         },
2615         { &hf_btavdtp_h263_level_30,
2616             { "H264 Level 30",                  "btavdtp.codec.h264.level.30",
2617             FT_BOOLEAN, 8, NULL, 0x20,
2618             NULL, HFILL }
2619         },
2620         { &hf_btavdtp_h263_level_rfa,
2621             { "H264 Level RFA",                 "btavdtp.codec.h264.level.rfa",
2622             FT_UINT8, BASE_HEX, NULL, 0x1F,
2623             NULL, HFILL }
2624         },
2625         { &hf_btavdtp_mpeg4_level_0,
2626             { "MPEG Level 0",                   "btavdtp.codec.mpeg4.level.0",
2627             FT_BOOLEAN, 8, NULL, 0x80,
2628             NULL, HFILL }
2629         },
2630         { &hf_btavdtp_mpeg4_level_1,
2631             { "MPEG Level 1",                   "btavdtp.codec.mpeg4.level.1",
2632             FT_BOOLEAN, 8, NULL, 0x40,
2633             NULL, HFILL }
2634         },
2635         { &hf_btavdtp_mpeg4_level_2,
2636             { "MPEG Level 2",                   "btavdtp.codec.mpeg4.level.2",
2637             FT_BOOLEAN, 8, NULL, 0x20,
2638             NULL, HFILL }
2639         },
2640         { &hf_btavdtp_mpeg4_level_3,
2641             { "MPEG4 Level 3",                  "btavdtp.codec.mpeg4.level.3",
2642             FT_BOOLEAN, 8, NULL, 0x10,
2643             NULL, HFILL }
2644         },
2645         { &hf_btavdtp_mpeg4_level_rfa,
2646             { "MPEG4 Level RFA",                "btavdtp.codec.mpeg4.level.rfa",
2647             FT_UINT8, BASE_HEX, NULL, 0x0F,
2648             NULL, HFILL }
2649         },
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,
2653             NULL, HFILL }
2654         },
2655         { &hf_btavdtp_vendor_specific_codec_id,
2656             { "Codec",                          "btavdtp.codec.vendor.codec_id",
2657             FT_UINT16, BASE_HEX, NULL, 0x00,
2658             NULL, HFILL }
2659         },
2660         { &hf_btavdtp_vendor_specific_value,
2661             { "Value",                          "btavdtp.codec.vendor.value",
2662             FT_NONE, BASE_NONE, NULL, 0x00,
2663             NULL, HFILL }
2664         },
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,
2668             NULL, HFILL }
2669         },
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,
2673             NULL, HFILL }
2674         },
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,
2678             NULL, HFILL }
2679         },
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,
2683             NULL, HFILL }
2684         },
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,
2688             NULL, HFILL }
2689         },
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,
2693             NULL, HFILL }
2694         },
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,
2698             NULL, HFILL }
2699         },
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,
2703             NULL, HFILL }
2704         },
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,
2708             NULL, HFILL }
2709         },
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,
2713             NULL, HFILL }
2714         },
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,
2718             NULL, HFILL }
2719         },
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,
2723             NULL, HFILL }
2724         },
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,
2728             NULL, HFILL }
2729         },
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,
2733             NULL, HFILL }
2734         },
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,
2738             NULL, HFILL }
2739         },
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,
2743             NULL, HFILL }
2744         },
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,
2748             NULL, HFILL }
2749         },
2750         { &hf_btavdtp_vendor_specific_aptxhd_rfa,
2751             { "RFA",                            "btavdtp.codec.aptxhd.rfa",
2752             FT_UINT32, BASE_HEX, NULL, 0x0,
2753             NULL, HFILL }
2754         },
2755         { &hf_btavdtp_capabilities,
2756             { "Capabilities",                   "btavdtp.capabilities",
2757             FT_NONE, BASE_NONE, NULL, 0x0,
2758             NULL, HFILL }
2759         },
2760         { &hf_btavdtp_service,
2761             { "Service",                        "btavdtp.service",
2762             FT_NONE, BASE_NONE, NULL, 0x0,
2763             NULL, HFILL }
2764         },
2765         { &hf_btavdtp_service_multiplexing_entry,
2766             { "Entry",                          "btavdtp.service_multiplexing_entry",
2767             FT_NONE, BASE_NONE, NULL, 0x0,
2768             NULL, HFILL }
2769         },
2770         { &hf_btavdtp_data,
2771             { "Data",                           "btavdtp.data",
2772             FT_NONE, BASE_NONE, NULL, 0x0,
2773             NULL, HFILL }
2774         }
2775     };
2776
2777     static gint *ett[] = {
2778         &ett_btavdtp,
2779         &ett_btavdtp_sep,
2780         &ett_btavdtp_capabilities,
2781         &ett_btavdtp_service,
2782     };
2783
2784     proto_btavdtp = proto_register_protocol("Bluetooth AVDTP Protocol", "BT AVDTP", "btavdtp");
2785     btavdtp_handle = register_dissector("btavdtp", dissect_btavdtp, proto_btavdtp);
2786
2787     proto_register_field_array(proto_btavdtp, hf, array_length(hf));
2788     proto_register_subtree_array(ett, array_length(ett));
2789
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.");
2794
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());
2801 #endif
2802 }
2803
2804 void
2805 proto_reg_handoff_btavdtp(void)
2806 {
2807     dissector_add_string("bluetooth.uuid", "19", btavdtp_handle);
2808
2809     dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_AVDTP, btavdtp_handle);
2810
2811     dissector_add_for_decode_as("btl2cap.cid", btavdtp_handle);
2812 }
2813
2814
2815 static gint
2816 dissect_aptx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2817 {
2818     proto_item          *aptx_item;
2819     proto_tree          *aptx_tree;
2820     proto_item          *pitem;
2821     bta2dp_codec_info_t *info;
2822     gdouble              cumulative_frame_duration = 0;
2823
2824     info = (bta2dp_codec_info_t *) data;
2825
2826     col_set_str(pinfo->cinfo, COL_PROTOCOL, "aptX");
2827
2828     switch (pinfo->p2p_dir) {
2829
2830     case P2P_DIR_SENT:
2831         col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
2832         break;
2833
2834     case P2P_DIR_RECV:
2835         col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
2836         break;
2837
2838     case P2P_DIR_UNKNOWN:
2839         col_clear(pinfo->cinfo, COL_INFO);
2840         break;
2841
2842     default:
2843         col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
2844             pinfo->p2p_dir);
2845         break;
2846     }
2847
2848     col_append_fstr(pinfo->cinfo, COL_INFO, "aptX");
2849
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);
2852
2853     proto_tree_add_item(aptx_tree, hf_aptx_data, tvb, 0, -1, ENC_NA);
2854
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;
2861         gint frequency;
2862         gint sample_bits;
2863
2864         switch (info->configuration[8] >> 4) {
2865         case 0x01:
2866             frequency = 48000;
2867             break;
2868         case 0x02:
2869             frequency = 44100;
2870             break;
2871         case 0x04:
2872             frequency = 32000;
2873             break;
2874         case 0x08:
2875             frequency = 16000;
2876             break;
2877         default:
2878             fail = TRUE;
2879         }
2880
2881         if (fail)
2882             return tvb_reported_length(tvb);
2883
2884         switch (info->configuration[8] & 0x0F) {
2885         case 0x01:
2886         case 0x02:
2887         case 0x04:
2888             number_of_channels = 2;
2889             break;
2890         case 0x08:
2891             number_of_channels = 1;
2892             break;
2893         default:
2894             fail = TRUE;
2895         }
2896
2897         if (fail)
2898             return tvb_reported_length(tvb);
2899
2900         sample_bits = 16;
2901
2902         expected_speed_data = frequency * (sample_bits / 8.0) * number_of_channels;
2903         frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0);
2904
2905         cumulative_frame_duration = (tvb_reported_length(tvb) / 4.0) * frame_duration;
2906
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);
2909
2910         if (info && info->previous_media_packet_info && info->current_media_packet_info) {
2911             nstime_t  delta;
2912
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);
2916
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);
2919
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);
2923
2924             if (!pinfo->fd->flags.visited)
2925                 info->current_media_packet_info->cumulative_frame_duration += cumulative_frame_duration;
2926
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);
2929
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);
2932         }
2933     }
2934
2935     return tvb_reported_length(tvb);
2936 }
2937
2938 void
2939 proto_register_aptx(void)
2940 {
2941     static hf_register_info hf[] = {
2942         { &hf_aptx_data,
2943             { "Data",                            "aptx.data",
2944             FT_BYTES, BASE_NONE, NULL, 0x00,
2945             NULL, HFILL }
2946         },
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,
2950             NULL, HFILL }
2951         },
2952         { &hf_aptx_delta_time,
2953             { "Delta time",                      "aptx.delta_time",
2954             FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2955             NULL, HFILL }
2956         },
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,
2960             NULL, HFILL }
2961         },
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,
2965             NULL, HFILL }
2966         },
2967         { &hf_aptx_cumulative_duration,
2968             { "Cumulative Music Duration",      "aptx.cumulative_music_duration",
2969             FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2970             NULL, HFILL }
2971         },
2972         { &hf_aptx_diff,
2973             { "Diff",                            "aptx.diff",
2974             FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, &units_milliseconds, 0x00,
2975             NULL, HFILL }
2976         },
2977     };
2978
2979     static gint *ett[] = {
2980         &ett_aptx
2981     };
2982
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));
2986
2987     aptx_handle = register_dissector("aptx", dissect_aptx, proto_aptx);
2988 }
2989
2990
2991 static gint
2992 dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2993 {
2994     proto_item          *ti;
2995     proto_tree          *bta2dp_tree;
2996     proto_item          *pitem;
2997     gint                 offset = 0;
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;
3002
3003     no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
3004                 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3005
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;
3019
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;
3025
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;
3030     } else {
3031         if (data && !no_avdtp_session)
3032             sep_data = *((sep_data_t *) data);
3033     }
3034
3035     col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP");
3036
3037     switch (pinfo->p2p_dir) {
3038
3039     case P2P_DIR_SENT:
3040         col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3041         break;
3042
3043     case P2P_DIR_RECV:
3044         col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3045         break;
3046
3047     case P2P_DIR_UNKNOWN:
3048         col_clear(pinfo->cinfo, COL_INFO);
3049         break;
3050
3051     default:
3052         col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3053             pinfo->p2p_dir);
3054         break;
3055     }
3056
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"));
3060
3061     bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp);
3062
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);
3065
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);
3068
3069     pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, 0, 0, sep_data.codec);
3070     PROTO_ITEM_SET_GENERATED(pitem);
3071
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);
3075
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);
3078
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;
3082     }
3083
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);
3087     }
3088
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);
3092     }
3093
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);
3097     }
3098
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);
3101
3102     switch (sep_data.codec) {
3103         case CODEC_SBC:
3104             codec_dissector = sbc_handle;
3105             break;
3106          case CODEC_MPEG12_AUDIO:
3107             codec_dissector = mp2t_handle;
3108             break;
3109         case CODEC_MPEG24_AAC:
3110             codec_dissector = mpeg_audio_handle;
3111             break;
3112         case CODEC_ATRAC:
3113             codec_dissector = atrac_handle;
3114             break;
3115         case CODEC_APT_X:
3116         case CODEC_APT_X_HD:
3117             codec_dissector = aptx_handle;
3118             break;
3119     }
3120
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;
3127
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;
3133 #endif
3134
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);
3137     } else {
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);
3140     }
3141     offset += tvb_reported_length_remaining(tvb, offset);
3142
3143     return offset;
3144 }
3145
3146 void
3147 proto_register_bta2dp(void)
3148 {
3149     module_t *module;
3150
3151     static hf_register_info hf[] = {
3152         { &hf_bta2dp_acp_seid,
3153             { "ACP SEID",                        "bta2dp.acp_seid",
3154             FT_UINT8, BASE_DEC, NULL, 0x00,
3155             NULL, HFILL }
3156         },
3157         { &hf_bta2dp_int_seid,
3158             { "INT SEID",                        "bta2dp.int_seid",
3159             FT_UINT8, BASE_DEC, NULL, 0x00,
3160             NULL, HFILL }
3161         },
3162         { &hf_bta2dp_codec,
3163             { "Codec",                           "bta2dp.codec",
3164             FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
3165             NULL, HFILL }
3166         },
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,
3170             NULL, HFILL }
3171         },
3172         { &hf_bta2dp_vendor_codec_id,
3173             { "Vendor Codec",                    "bta2dp.codec.vendor.codec_id",
3174             FT_UINT16, BASE_HEX, NULL, 0x00,
3175             NULL, HFILL }
3176         },
3177         { &hf_bta2dp_content_protection,
3178             { "Content Protection",              "bta2dp.content_protection",
3179             FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3180             NULL, HFILL }
3181         },
3182         { &hf_bta2dp_stream_start_in_frame,
3183             { "Stream Start in Frame",           "bta2dp.stream_start_in_frame",
3184             FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3185             NULL, HFILL }
3186         },
3187         { &hf_bta2dp_stream_end_in_frame,
3188             { "Stream End in Frame",           "bta2dp.stream_end_in_frame",
3189             FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3190             NULL, HFILL }
3191         },
3192         { &hf_bta2dp_stream_number,
3193             { "Stream Number",                   "bta2dp.stream_number",
3194             FT_UINT32, BASE_DEC, NULL, 0x00,
3195             NULL, HFILL }
3196         }
3197     };
3198
3199     static gint *ett[] = {
3200         &ett_bta2dp
3201     };
3202
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));
3206
3207     bta2dp_handle = register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp);
3208
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.");
3213
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);
3218
3219     prefs_register_enum_preference(module, "a2dp.codec",
3220             "Force codec",
3221             "Force decoding stream as A2DP with specified codec",
3222             &force_a2dp_codec, pref_a2dp_codec, FALSE);
3223 }
3224
3225 void
3226 proto_reg_handoff_bta2dp(void)
3227 {
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);
3233
3234     rtp_handle   = find_dissector_add_dependency("rtp", proto_bta2dp);
3235
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);
3239
3240     dissector_add_for_decode_as("btl2cap.cid", bta2dp_handle);
3241 }
3242
3243 static gint
3244 dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3245 {
3246     proto_item          *ti;
3247     proto_tree          *btvdp_tree;
3248     proto_item          *pitem;
3249     gint                 offset = 0;
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;
3254
3255     no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
3256                 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3257
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;
3271
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;
3277
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;
3282     } else {
3283         if (data  && !no_avdtp_session)
3284             sep_data = *((sep_data_t *) data);
3285     }
3286
3287     col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP");
3288
3289     switch (pinfo->p2p_dir) {
3290
3291     case P2P_DIR_SENT:
3292         col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3293         break;
3294
3295     case P2P_DIR_RECV:
3296         col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3297         break;
3298
3299     case P2P_DIR_UNKNOWN:
3300         col_clear(pinfo->cinfo, COL_INFO);
3301         break;
3302
3303     default:
3304         col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3305             pinfo->p2p_dir);
3306         break;
3307     }
3308
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"));
3312
3313     btvdp_tree = proto_item_add_subtree(ti, ett_btvdp);
3314
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);
3317
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);
3320
3321     pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, 0, 0, sep_data.codec);
3322     PROTO_ITEM_SET_GENERATED(pitem);
3323
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);
3327
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);
3330     }
3331
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);
3335     }
3336
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);
3340     }
3341
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);
3345     }
3346
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);
3349
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;
3355             break;
3356         case CODEC_MPEG4_VSP:
3357             codec_dissector = mp4v_es_handle;
3358             break;
3359     }
3360
3361     btvdp_codec_info.codec_dissector = codec_dissector;
3362     btvdp_codec_info.content_protection_type = sep_data.content_protection_type;
3363
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;
3369 #endif
3370
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);
3374
3375     return offset;
3376 }
3377
3378 void
3379 proto_register_btvdp(void)
3380 {
3381     module_t *module;
3382     expert_module_t* expert_btavdtp;
3383
3384     static hf_register_info hf[] = {
3385         { &hf_btvdp_acp_seid,
3386             { "ACP SEID",                        "btvdp.acp_seid",
3387             FT_UINT8, BASE_DEC, NULL, 0x00,
3388             NULL, HFILL }
3389         },
3390         { &hf_btvdp_int_seid,
3391             { "INT SEID",                        "btvdp.int_seid",
3392             FT_UINT8, BASE_DEC, NULL, 0x00,
3393             NULL, HFILL }
3394         },
3395         { &hf_btvdp_codec,
3396             { "Codec",                           "btvdp.codec",
3397             FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
3398             NULL, HFILL }
3399         },
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,
3403             NULL, HFILL }
3404         },
3405         { &hf_btvdp_vendor_codec_id,
3406             { "Vendor Codec",                    "btvdp.codec.vendor.codec_id",
3407             FT_UINT16, BASE_HEX, NULL, 0x00,
3408             NULL, HFILL }
3409         },
3410         { &hf_btvdp_content_protection,
3411             { "Content Protection",              "btvdp.content_protection",
3412             FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3413             NULL, HFILL }
3414         },
3415         { &hf_btvdp_stream_start_in_frame,
3416             { "Stream Start in Frame",           "btvdp.stream_start_in_frame",
3417             FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3418             NULL, HFILL }
3419         },
3420         { &hf_btvdp_stream_end_in_frame,
3421             { "Stream End in Frame",             "btvdp.stream_end_in_frame",
3422             FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3423             NULL, HFILL }
3424         },
3425         { &hf_btvdp_stream_number,
3426             { "Stream Number",                   "btvdp.stream_number",
3427             FT_UINT32, BASE_DEC, NULL, 0x00,
3428             NULL, HFILL }
3429         },
3430     };
3431
3432     static gint *ett[] = {
3433         &ett_btvdp
3434     };
3435
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 }},
3440     };
3441
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));
3448
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.");
3453
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 ",
3457             &force_vdp_scms_t);
3458
3459     prefs_register_enum_preference(module, "vdp.codec",
3460             "Force codec",
3461             "Force decoding stream as VDP with specified codec",
3462             &force_vdp_codec, pref_vdp_codec, FALSE);
3463 }
3464
3465 void
3466 proto_reg_handoff_btvdp(void)
3467 {
3468     h263_handle = find_dissector_add_dependency("h263", proto_btvdp);
3469     mp4v_es_handle = find_dissector_add_dependency("mp4v-es", proto_btvdp);
3470
3471     rtp_handle   = find_dissector_add_dependency("rtp", proto_btvdp);
3472
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);
3476
3477     dissector_add_for_decode_as("btl2cap.cid", btvdp_handle);
3478 }
3479
3480
3481
3482 static gint
3483 dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3484 {
3485     proto_item  *main_item;
3486     proto_tree  *main_tree;
3487     gint         offset = 0;
3488
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);
3491
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);
3495     offset += 1;
3496
3497     return offset;
3498 }
3499
3500 void
3501 proto_register_bta2dp_content_protection_header_scms_t(void)
3502 {
3503     static hf_register_info hf[] = {
3504         { &hf_bta2dp_l_bit,
3505             { "L-bit",                           "bta2dp.content_protection_header.scms_t.l_bit",
3506             FT_BOOLEAN, 8, NULL, 0x01,
3507             NULL, HFILL }
3508         },
3509         { &hf_bta2dp_cp_bit,
3510             { "Cp-bit",                          "bta2dp.content_protection_header.scms_t.cp_bit",
3511             FT_BOOLEAN, 8, NULL, 0x02,
3512             NULL, HFILL }
3513         },
3514         { &hf_bta2dp_reserved,
3515             { "Reserved",                        "bta2dp.content_protection_header.scms_t.reserved",
3516             FT_BOOLEAN, 8, NULL, 0xFC,
3517             NULL, HFILL }
3518         }
3519     };
3520
3521     static gint *ett[] = {
3522         &ett_bta2dp_cph_scms_t
3523     };
3524
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));
3528
3529     register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t);
3530 }
3531
3532 static gint
3533 dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3534 {
3535     proto_item  *main_item;
3536     proto_tree  *main_tree;
3537     gint         offset = 0;
3538
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);
3541
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);
3545     offset += 1;
3546
3547     return offset;
3548 }
3549
3550 void
3551 proto_register_btvdp_content_protection_header_scms_t(void)
3552 {
3553     static hf_register_info hf[] = {
3554         { &hf_btvdp_l_bit,
3555             { "L-bit",                           "btvdp.content_protection_header.scms_t.l_bit",
3556             FT_BOOLEAN, 8, NULL, 0x01,
3557             NULL, HFILL }
3558         },
3559         { &hf_btvdp_cp_bit,
3560             { "Cp-bit",                          "btvdp.content_protection_header.scms_t.cp_bit",
3561             FT_BOOLEAN, 8, NULL, 0x02,
3562             NULL, HFILL }
3563         },
3564         { &hf_btvdp_reserved,
3565             { "Reserved",                        "btvdp.content_protection_header.scms_t.reserved",
3566             FT_BOOLEAN, 8, NULL, 0xFC,
3567             NULL, HFILL }
3568         }
3569     };
3570
3571     static gint *ett[] = {
3572         &ett_btvdp_cph_scms_t
3573     };
3574
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));
3578
3579     register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t);
3580 }
3581
3582 /*
3583  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3584  *
3585  * Local variables:
3586  * c-basic-offset: 4
3587  * tab-width: 8
3588  * indent-tabs-mode: nil
3589  * End:
3590  *
3591  * vi: set shiftwidth=4 tabstop=8 expandtab:
3592  * :indentSize=4:tabSize=8:noTabs=true:
3593  */