2 * Routines for Bluetooth AVDTP dissection
4 * Copyright 2012, Michal Labedzki for Tieto Corporation
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <epan/packet.h>
28 #include <epan/expert.h>
29 #include <epan/prefs.h>
31 #include "packet-bluetooth.h"
32 #include "packet-btl2cap.h"
33 #include "packet-btsdp.h"
34 #include "packet-btavdtp.h"
35 #include "packet-btavrcp.h"
36 #include "packet-rtp.h"
38 #define AVDTP_MESSAGE_TYPE_MASK 0x03
39 #define AVDTP_PACKET_TYPE_MASK 0x0C
40 #define AVDTP_TRANSACTION_MASK 0xF0
41 #define AVDTP_SIGNAL_ID_MASK 0x3F
42 #define AVDTP_RFA0_MASK 0xC0
44 #define MESSAGE_TYPE_COMMAND 0x00
45 #define MESSAGE_TYPE_GENERAL_REJECT 0x01
46 #define MESSAGE_TYPE_ACCEPT 0x02
47 #define MESSAGE_TYPE_REJECT 0x03
49 #define PACKET_TYPE_SINGLE 0x00
50 #define PACKET_TYPE_START 0x01
51 #define PACKET_TYPE_CONTINUE 0x02
52 #define PACKET_TYPE_END 0x03
54 #define SIGNAL_ID_DISCOVER 0x01
55 #define SIGNAL_ID_GET_CAPABILITIES 0x02
56 #define SIGNAL_ID_SET_CONFIGURATION 0x03
57 #define SIGNAL_ID_GET_CONFIGURATION 0x04
58 #define SIGNAL_ID_RECONFIGURE 0x05
59 #define SIGNAL_ID_OPEN 0x06
60 #define SIGNAL_ID_START 0x07
61 #define SIGNAL_ID_CLOSE 0x08
62 #define SIGNAL_ID_SUSPEND 0x09
63 #define SIGNAL_ID_ABORT 0x0A
64 #define SIGNAL_ID_SECURITY_CONTROL 0x0B
65 #define SIGNAL_ID_GET_ALL_CAPABILITIES 0x0C
66 #define SIGNAL_ID_DELAY_REPORT 0x0D
68 #define SERVICE_CATEGORY_MEDIA_TRANSPORT 0x01
69 #define SERVICE_CATEGORY_REPORTING 0x02
70 #define SERVICE_CATEGORY_RECOVERY 0x03
71 #define SERVICE_CATEGORY_CONTENT_PROTECTION 0x04
72 #define SERVICE_CATEGORY_HEADER_COMPRESSION 0x05
73 #define SERVICE_CATEGORY_MULTIPLEXING 0x06
74 #define SERVICE_CATEGORY_MEDIA_CODEC 0x07
75 #define SERVICE_CATEGORY_DELAY_REPORTING 0x08
77 #define MEDIA_TYPE_AUDIO 0x00
78 #define MEDIA_TYPE_VIDEO 0x01
83 #define STREAM_TYPE_MEDIA 0x00
84 #define STREAM_TYPE_SIGNAL 0x01
86 #define CODEC_DEFAULT 0xFFFF
87 #define CODEC_SBC 0x00
88 #define CODEC_MPEG12_AUDIO 0x01
89 #define CODEC_MPEG24_AAC 0x02
90 #define CODEC_ATRAC 0x04
91 #define CODEC_APT_X 0xFF01
93 #define CODEC_H263_BASELINE 0x01
94 #define CODEC_MPEG4_VSP 0x02
95 #define CODEC_H263_PROFILE_3 0x03
96 #define CODEC_H263_PROFILE_8 0x04
98 #define CODEC_VENDOR 0xFF
100 #define HEADER_SIZE 2
104 /* ========================================================== */
105 /* Story: RTP Player, conversation (probably reassemble too) use address:port as
106 "key" to separate devices/streams. In Bluetooth World it is not enough to
107 separate devices/streams. Example key:
108 guint32 interface_id (aka frame.interface_id)
109 guint32 adapter_id (interface like "bluetooth-monitor" or USB provide
110 more than one device over interface, so we must
111 separate information provided by each one)
112 guint16 hci_chandle (aka "connection handle" use to separate connections to devices)
113 guint16 l2cap_psm (like hci_chandle but over l2cap layer, need hci_chandle info because
114 the same PSM can be used over chandles)
115 guint8 rfcomm_channel (like l2cap_psm, but over RFCOMM layer...)
117 guint8 stram_endpoint_number
118 guint32 stream_number (to separate multiple streams for RTP Player)
120 So keys can be various (length or type) and "ports" are not enough to sore
121 all needed information. If one day that changed then all RTP_PLAYER_WORKAROUND
122 block can be removed. This workaround use global number of streams (aka stream ID)
123 to be used as port number in RTP Player to separate streams.
125 #define RTP_PLAYER_WORKAROUND TRUE
127 #if RTP_PLAYER_WORKAROUND == TRUE
128 wmem_tree_t *file_scope_stream_number = NULL;
130 /* ========================================================== */
132 static int proto_btavdtp = -1;
134 static int hf_btavdtp_data = -1;
135 static int hf_btavdtp_message_type = -1;
136 static int hf_btavdtp_packet_type = -1;
137 static int hf_btavdtp_transaction = -1;
138 static int hf_btavdtp_signal = -1;
139 static int hf_btavdtp_signal_id = -1;
140 static int hf_btavdtp_rfa0 = -1;
141 static int hf_btavdtp_number_of_signal_packets = -1;
142 static int hf_btavdtp_sep_seid = -1;
143 static int hf_btavdtp_sep_inuse = -1;
144 static int hf_btavdtp_sep_rfa0 = -1;
145 static int hf_btavdtp_sep_media_type = -1;
146 static int hf_btavdtp_sep_type = -1;
147 static int hf_btavdtp_sep_rfa1 = -1;
148 static int hf_btavdtp_error_code = -1;
149 static int hf_btavdtp_acp_sep = -1;
150 static int hf_btavdtp_acp_seid_item = -1;
151 static int hf_btavdtp_int_seid_item = -1;
152 static int hf_btavdtp_acp_seid = -1;
153 static int hf_btavdtp_int_seid = -1;
154 static int hf_btavdtp_service_category = -1;
155 static int hf_btavdtp_rfa_seid = -1;
156 static int hf_btavdtp_delay = -1;
157 static int hf_btavdtp_length_of_service_category = -1;
158 static int hf_btavdtp_recovery_type = -1;
159 static int hf_btavdtp_maximum_recovery_window_size = -1;
160 static int hf_btavdtp_maximum_number_of_media_packet_in_parity_code = -1;
161 static int hf_btavdtp_multiplexing_fragmentation = -1;
162 static int hf_btavdtp_multiplexing_rfa = -1;
163 static int hf_btavdtp_multiplexing_tsid = -1;
164 static int hf_btavdtp_multiplexing_tcid = -1;
165 static int hf_btavdtp_multiplexing_entry_rfa = -1;
166 static int hf_btavdtp_header_compression_backch = -1;
167 static int hf_btavdtp_header_compression_media = -1;
168 static int hf_btavdtp_header_compression_recovery = -1;
169 static int hf_btavdtp_header_compression_rfa = -1;
170 static int hf_btavdtp_content_protection_type = -1;
171 static int hf_btavdtp_media_codec_media_type = -1;
172 static int hf_btavdtp_media_codec_rfa = -1;
173 static int hf_btavdtp_media_codec_unknown_type = -1;
174 static int hf_btavdtp_media_codec_audio_type = -1;
175 static int hf_btavdtp_media_codec_video_type = -1;
176 static int hf_btavdtp_sbc_sampling_frequency_16000 = -1;
177 static int hf_btavdtp_sbc_sampling_frequency_32000 = -1;
178 static int hf_btavdtp_sbc_sampling_frequency_44100 = -1;
179 static int hf_btavdtp_sbc_sampling_frequency_48000 = -1;
180 static int hf_btavdtp_sbc_channel_mode_mono = -1;
181 static int hf_btavdtp_sbc_channel_mode_dual_channel = -1;
182 static int hf_btavdtp_sbc_channel_mode_stereo = -1;
183 static int hf_btavdtp_sbc_channel_mode_joint_stereo = -1;
184 static int hf_btavdtp_sbc_block_4 = -1;
185 static int hf_btavdtp_sbc_block_8 = -1;
186 static int hf_btavdtp_sbc_block_12 = -1;
187 static int hf_btavdtp_sbc_block_16 = -1;
188 static int hf_btavdtp_sbc_subbands_4 = -1;
189 static int hf_btavdtp_sbc_subbands_8 = -1;
190 static int hf_btavdtp_sbc_allocation_method_snr = -1;
191 static int hf_btavdtp_sbc_allocation_method_loudness = -1;
192 static int hf_btavdtp_sbc_min_bitpool = -1;
193 static int hf_btavdtp_sbc_max_bitpool = -1;
194 static int hf_btavdtp_mpeg12_layer_1 = -1;
195 static int hf_btavdtp_mpeg12_layer_2 = -1;
196 static int hf_btavdtp_mpeg12_layer_3 = -1;
197 static int hf_btavdtp_mpeg12_crc_protection = -1;
198 static int hf_btavdtp_mpeg12_channel_mode_mono = -1;
199 static int hf_btavdtp_mpeg12_channel_mode_dual_channel = -1;
200 static int hf_btavdtp_mpeg12_channel_mode_stereo = -1;
201 static int hf_btavdtp_mpeg12_channel_mode_joint_stereo = -1;
202 static int hf_btavdtp_mpeg12_rfa = -1;
203 static int hf_btavdtp_mpeg12_mpf_2 = -1;
204 static int hf_btavdtp_mpeg12_sampling_frequency_16000 = -1;
205 static int hf_btavdtp_mpeg12_sampling_frequency_22050 = -1;
206 static int hf_btavdtp_mpeg12_sampling_frequency_24000 = -1;
207 static int hf_btavdtp_mpeg12_sampling_frequency_32000 = -1;
208 static int hf_btavdtp_mpeg12_sampling_frequency_44100 = -1;
209 static int hf_btavdtp_mpeg12_sampling_frequency_48000 = -1;
210 static int hf_btavdtp_mpeg12_vbr_supported = -1;
211 static int hf_btavdtp_mpeg12_bit_rate = -1;
212 static int hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc = -1;
213 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc = -1;
214 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp = -1;
215 static int hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable = -1;
216 static int hf_btavdtp_mpeg24_object_type_rfa = -1;
217 static int hf_btavdtp_mpeg24_sampling_frequency_8000 = -1;
218 static int hf_btavdtp_mpeg24_sampling_frequency_11025 = -1;
219 static int hf_btavdtp_mpeg24_sampling_frequency_12000 = -1;
220 static int hf_btavdtp_mpeg24_sampling_frequency_16000 = -1;
221 static int hf_btavdtp_mpeg24_sampling_frequency_22050 = -1;
222 static int hf_btavdtp_mpeg24_sampling_frequency_24000 = -1;
223 static int hf_btavdtp_mpeg24_sampling_frequency_32000 = -1;
224 static int hf_btavdtp_mpeg24_sampling_frequency_44100 = -1;
225 static int hf_btavdtp_mpeg24_sampling_frequency_48000 = -1;
226 static int hf_btavdtp_mpeg24_sampling_frequency_64000 = -1;
227 static int hf_btavdtp_mpeg24_sampling_frequency_88200 = -1;
228 static int hf_btavdtp_mpeg24_sampling_frequency_96000 = -1;
229 static int hf_btavdtp_mpeg24_channels_1 = -1;
230 static int hf_btavdtp_mpeg24_channels_2 = -1;
231 static int hf_btavdtp_mpeg24_rfa = -1;
232 static int hf_btavdtp_mpeg24_vbr_supported = -1;
233 static int hf_btavdtp_mpeg24_bit_rate = -1;
234 static int hf_btavdtp_atrac_version = -1;
235 static int hf_btavdtp_atrac_channel_mode_single_channel = -1;
236 static int hf_btavdtp_atrac_channel_mode_dual_channel = -1;
237 static int hf_btavdtp_atrac_channel_mode_joint_stereo = -1;
238 static int hf_btavdtp_atrac_rfa1 = -1;
239 static int hf_btavdtp_atrac_rfa2 = -1;
240 static int hf_btavdtp_atrac_sampling_frequency_44100 = -1;
241 static int hf_btavdtp_atrac_sampling_frequency_48000 = -1;
242 static int hf_btavdtp_atrac_vbr_supported = -1;
243 static int hf_btavdtp_atrac_bit_rate = -1;
244 static int hf_btavdtp_atrac_maximum_sul = -1;
245 static int hf_btavdtp_atrac_rfa3 = -1;
246 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000 = -1;
247 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000 = -1;
248 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100 = -1;
249 static int hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000 = -1;
250 static int hf_btavdtp_vendor_specific_aptx_channel_mode_mono = -1;
251 static int hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel = -1;
252 static int hf_btavdtp_vendor_specific_aptx_channel_mode_stereo = -1;
253 static int hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo = -1;
254 static int hf_btavdtp_h263_level_10 = -1;
255 static int hf_btavdtp_h263_level_20 = -1;
256 static int hf_btavdtp_h263_level_30 = -1;
257 static int hf_btavdtp_h263_level_rfa = -1;
258 static int hf_btavdtp_mpeg4_level_0 = -1;
259 static int hf_btavdtp_mpeg4_level_1 = -1;
260 static int hf_btavdtp_mpeg4_level_2 = -1;
261 static int hf_btavdtp_mpeg4_level_3 = -1;
262 static int hf_btavdtp_mpeg4_level_rfa = -1;
263 static int hf_btavdtp_vendor_id = -1;
264 static int hf_btavdtp_vendor_specific_codec_id = -1;
265 static int hf_btavdtp_vendor_specific_value = -1;
266 static int hf_btavdtp_vendor_specific_apt_codec_id = -1;
267 static int hf_btavdtp_capabilities = -1;
268 static int hf_btavdtp_service = -1;
269 static int hf_btavdtp_service_multiplexing_entry = -1;
271 static gint ett_btavdtp = -1;
272 static gint ett_btavdtp_sep = -1;
273 static gint ett_btavdtp_capabilities = -1;
274 static gint ett_btavdtp_service = -1;
276 static expert_field ei_btavdtp_sbc_min_bitpool_out_of_range = EI_INIT;
277 static expert_field ei_btavdtp_sbc_max_bitpool_out_of_range = EI_INIT;
278 static expert_field ei_btavdtp_unexpected_losc_data = EI_INIT;
280 static dissector_handle_t btavdtp_handle;
281 static dissector_handle_t bta2dp_handle;
282 static dissector_handle_t btvdp_handle;
283 static dissector_handle_t rtp_handle;
285 static wmem_tree_t *channels = NULL;
286 static wmem_tree_t *sep_list = NULL;
287 static wmem_tree_t *sep_open = NULL;
288 static wmem_tree_t *media_packet_times = NULL;
290 /* A2DP declarations */
291 static gint proto_bta2dp = -1;
292 static gint ett_bta2dp = -1;
293 static gint proto_bta2dp_cph_scms_t = -1;
294 static gint ett_bta2dp_cph_scms_t = -1;
296 static int hf_bta2dp_acp_seid = -1;
297 static int hf_bta2dp_int_seid = -1;
298 static int hf_bta2dp_codec = -1;
299 static int hf_bta2dp_vendor_id = -1;
300 static int hf_bta2dp_vendor_codec_id = -1;
301 static int hf_bta2dp_content_protection = -1;
302 static int hf_bta2dp_stream_start_in_frame = -1;
303 static int hf_bta2dp_stream_end_in_frame = -1;
304 static int hf_bta2dp_stream_number = -1;
305 static int hf_bta2dp_l_bit = -1;
306 static int hf_bta2dp_cp_bit = -1;
307 static int hf_bta2dp_reserved = -1;
309 static dissector_handle_t sbc_handle;
310 static dissector_handle_t mp2t_handle;
311 static dissector_handle_t mpeg_audio_handle;
312 static dissector_handle_t atrac_handle;
314 static gboolean force_a2dp_scms_t = FALSE;
315 static gint force_a2dp_codec = CODEC_DEFAULT;
317 static const enum_val_t pref_a2dp_codec[] = {
318 { "default", "Default", CODEC_DEFAULT },
319 { "sbc", "SBC", CODEC_SBC },
320 { "mp2t", "MPEG12 AUDIO", CODEC_MPEG12_AUDIO },
321 { "mpeg-audio", "MPEG24 AAC", CODEC_MPEG24_AAC },
322 /* XXX: Not supported in Wireshark yet { "atrac", "ATRAC", CODEC_ATRAC },*/
323 { "aptx", "APT-X", CODEC_APT_X },
328 /* VDP declarations */
329 static gint proto_btvdp = -1;
330 static gint ett_btvdp = -1;
331 static gint proto_btvdp_cph_scms_t = -1;
332 static gint ett_btvdp_cph_scms_t = -1;
334 static int hf_btvdp_acp_seid = -1;
335 static int hf_btvdp_int_seid = -1;
336 static int hf_btvdp_codec = -1;
337 static int hf_btvdp_vendor_id = -1;
338 static int hf_btvdp_vendor_codec_id = -1;
339 static int hf_btvdp_content_protection = -1;
340 static int hf_btvdp_stream_start_in_frame = -1;
341 static int hf_btvdp_stream_end_in_frame = -1;
342 static int hf_btvdp_stream_number = -1;
343 static int hf_btvdp_l_bit = -1;
344 static int hf_btvdp_cp_bit = -1;
345 static int hf_btvdp_reserved = -1;
347 static dissector_handle_t h263_handle;
348 static dissector_handle_t mp4v_es_handle;
350 static gboolean force_vdp_scms_t = FALSE;
351 static gint force_vdp_codec = CODEC_H263_BASELINE;
353 static const enum_val_t pref_vdp_codec[] = {
354 { "h263", "H263", CODEC_H263_BASELINE },
355 { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP },
360 static int proto_aptx = -1;
361 static int hf_aptx_data = -1;
362 static int hf_aptx_cumulative_frame_duration = -1;
363 static int hf_aptx_delta_time = -1;
364 static int hf_aptx_avrcp_song_position = -1;
365 static int hf_aptx_delta_time_from_the_beginning = -1;
366 static int hf_aptx_cumulative_duration = -1;
367 static int hf_aptx_diff = -1;
368 static gint ett_aptx = -1;
369 static dissector_handle_t aptx_handle;
372 static const value_string message_type_vals[] = {
374 { 0x01, "GeneralReject" },
375 { 0x02, "ResponseAccept" },
376 { 0x03, "ResponseReject" },
380 static const value_string packet_type_vals[] = {
383 { 0x02, "Continue" },
388 static const value_string signal_id_vals[] = {
389 { 0x00, "Reserved" },
390 { 0x01, "Discover" },
391 { 0x02, "GetCapabilities" },
392 { 0x03, "SetConfiguration" },
393 { 0x04, "GetConfiguration" },
394 { 0x05, "Reconfigure" },
400 { 0x0B, "SecurityControl" },
401 { 0x0C, "GetAllCapabilities" },
402 { 0x0D, "DelayReport" },
406 static const value_string media_type_vals[] = {
409 { 0x02, "Multimedia" },
413 static const value_string sep_type_vals[] = {
419 static const value_string true_false[] = {
425 static const value_string error_code_vals[] = {
426 /* ACP to INT, Signal Response Header Error Codes */
427 { 0x01, "Bad Header Format" },
428 /* ACP to INT, Signal Response Payload Format Error Codes */
429 { 0x11, "Bad Length" },
430 { 0x12, "Bad ACP SEID" },
431 { 0x13, "SEP In Use" },
432 { 0x14, "SEP Not In Use" },
433 { 0x17, "Bad Service Category" },
434 { 0x18, "Bad Payload Format" },
435 { 0x19, "Not Supported Command" },
436 { 0x1A, "Invalid Capabilities" },
437 /* ACP to INT, Signal Response Transport Service Capabilities Error Codes */
438 { 0x22, "Bad Recovery Type" },
439 { 0x23, "Bad Media Transport Format" },
440 { 0x25, "Bad Recovery Format" },
441 { 0x26, "Bad Header Compression Format" },
442 { 0x27, "Bad Content Protection Format" },
443 { 0x28, "Bad Multiplexing Format" },
444 { 0x29, "Unsupported Configuration" },
445 /* ACP to INT, Procedure Error Codes */
446 { 0x31, "Bad State" },
448 { 0x80, "The Service Category Stated is Invalid" },
449 { 0x81, "Lack of Resource New Stream Context" },
451 { 0xC1, "Invalid Codec Type" },
452 { 0xC2, "Not Supported Codec Type" },
453 { 0xC3, "Invalid Sampling Frequency" },
454 { 0xC4, "Not Supported Sampling Frequency" },
455 { 0xC5, "Invalid Channel Mode" },
456 { 0xC6, "Not Supported Channel Mode" },
457 { 0xC7, "Invalid Subbands" },
458 { 0xC8, "Not Supported Subbands" },
459 { 0xC9, "Invalid Allocation Method" },
460 { 0xCA, "Not Supported Allocation Method" },
461 { 0xCB, "Invalid Minimum Bitpool Value" },
462 { 0xCC, "Not Supported Minimum Bitpool Value" },
463 { 0xCD, "Invalid Maximum Bitpool Value" },
464 { 0xCE, "Not Supported Maximum Bitpool Value" },
465 { 0xCF, "Invalid Layer" },
466 { 0xD0, "Not Supported Layer" },
467 { 0xD1, "Not Supported CRC" },
468 { 0xD2, "Not Supported MPF" },
469 { 0xD3, "Not Supported VBR" },
470 { 0xD4, "Invalid Bit Rate" },
471 { 0xD5, "Not Supported Bit Rate" },
472 { 0xD6, "Invalid Object Type" },
473 { 0xD7, "Not Supported Object Type" },
474 { 0xD8, "Invalid Channels" },
475 { 0xD9, "Not Supported Channels" },
476 { 0xDA, "Invalid Version" },
477 { 0xDB, "Not Supported Version" },
478 { 0xDC, "Not Supported Maximum SUL" },
479 { 0xDD, "Invalid Block Length" },
480 { 0xE0, "Invalid Content Protection Type" },
481 { 0xE1, "Invalid Content Protection Format" },
482 { 0xE2, "Invalid Coded Parameter" },
483 { 0xE3, "Not Supported Codec Parameter" },
487 static const value_string service_category_vals[] = {
488 { 0x01, "Media Transport" },
489 { 0x02, "Reporting" },
490 { 0x03, "Recovery" },
491 { 0x04, "Content Protection" },
492 { 0x05, "Header Compression" },
493 { 0x06, "Multiplexing" },
494 { 0x07, "Media Codec" },
495 { 0x08, "Delay Reporting" },
499 static const value_string recovery_type_vals[] = {
500 { 0x00, "Forbidden" },
505 static const value_string multiplexing_tsid_vals[] = {
506 { 0x00, "Used for TSID query" },
511 static const value_string multiplexing_tcid_vals[] = {
512 { 0x00, "Used for TCID query" },
517 static const value_string media_codec_audio_type_vals[] = {
519 { 0x01, "MPEG-1,2 Audio" },
520 { 0x02, "MPEG-2,4 AAC" },
521 { 0x04, "ATRAC family" },
522 { 0xFF, "non-A2DP" },
526 static const value_string media_codec_video_type_vals[] = {
527 { 0x01, "H.263 baseline" },
528 { 0x02, "MPEG-4 Visual Simple Profile" },
529 { 0x03, "H.263 profile 3" },
530 { 0x04, "H.263 profile 8" },
535 static const value_string content_protection_type_vals[] = {
541 static const value_string vendor_apt_codec_vals[] = {
552 typedef struct _sep_entry_t {
559 guint16 vendor_codec;
560 guint8 configuration_length;
561 guint8 *configuration;
562 gint content_protection_type;
564 enum sep_state state;
567 typedef struct _sep_data_t {
570 guint16 vendor_codec;
571 guint8 configuration_length;
572 guint8 *configuration;
575 gint content_protection_type;
576 guint32 stream_start_in_frame;
577 guint32 stream_end_in_frame;
578 guint32 stream_number;
579 media_packet_info_t *previous_media_packet_info;
580 media_packet_info_t *current_media_packet_info;
583 typedef struct _media_stream_number_value_t {
584 guint32 stream_start_in_frame;
585 guint32 stream_end_in_frame;
586 guint32 stream_number;
587 } media_stream_number_value_t;
589 typedef struct _channels_info_t {
590 guint32 control_local_cid;
591 guint32 control_remote_cid;
592 guint32 media_local_cid;
593 guint32 media_remote_cid;
594 wmem_tree_t *stream_numbers;
595 guint32 disconnect_in_frame;
596 guint32 *l2cap_disconnect_in_frame;
597 guint32 *hci_disconnect_in_frame;
598 guint32 *adapter_disconnect_in_frame;
603 void proto_register_btavdtp(void);
604 void proto_reg_handoff_btavdtp(void);
605 void proto_register_bta2dp(void);
606 void proto_reg_handoff_bta2dp(void);
607 void proto_register_bta2dp_content_protection_header_scms_t(void);
608 void proto_register_btvdp(void);
609 void proto_reg_handoff_btvdp(void);
610 void proto_register_btvdp_content_protection_header_scms_t(void);
611 void proto_register_aptx(void);
615 get_sep_type(guint32 interface_id,
616 guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
618 wmem_tree_key_t key[6];
619 wmem_tree_t *subtree;
623 key[0].key = &interface_id;
625 key[1].key = &adapter_id;
627 key[2].key = &chandle;
629 key[3].key = &direction;
635 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
636 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
638 return val_to_str_const(sep->type, sep_type_vals, "unknown");
645 get_sep_media_type(guint32 interface_id,
646 guint32 adapter_id, guint32 chandle, guint32 direction, guint32 seid, guint32 frame_number)
648 wmem_tree_key_t key[6];
649 wmem_tree_t *subtree;
653 key[0].key = &interface_id;
655 key[1].key = &adapter_id;
657 key[2].key = &chandle;
659 key[3].key = &direction;
665 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
666 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
668 return val_to_str_const(sep->media_type, media_type_vals, "unknown");
676 dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
677 guint32 interface_id, guint32 adapter_id, guint32 chandle)
679 proto_tree *sep_tree;
680 proto_item *sep_item;
689 /* Reverse direction to avoid mass reversing it, because this is only case
690 when SEP is provided in ACP role, otherwise INT frequently asking for it
692 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
693 items = tvb_reported_length_remaining(tvb, offset) / 2;
694 while (tvb_reported_length_remaining(tvb, offset) > 0) {
695 seid = tvb_get_guint8(tvb, offset);
696 in_use = seid & 0x02;
698 media_type = tvb_get_guint8(tvb, offset + 1) >> 4;
699 type = (tvb_get_guint8(tvb, offset + 1) & 0x08) >> 3;
700 sep_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_sep, tvb, offset, 2, "ACP SEP [%u - %s %s] item %u/%u",
701 seid, val_to_str_const(media_type, media_type_vals, "unknown"),
702 val_to_str_const(type, sep_type_vals, "unknown"), i_sep, items);
703 sep_tree = proto_item_add_subtree(sep_item, ett_btavdtp_sep);
705 proto_tree_add_item(sep_tree, hf_btavdtp_sep_seid , tvb, offset, 1, ENC_NA);
706 proto_tree_add_item(sep_tree, hf_btavdtp_sep_inuse, tvb, offset, 1, ENC_NA);
707 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa0 , tvb, offset, 1, ENC_NA);
710 proto_tree_add_item(sep_tree, hf_btavdtp_sep_media_type, tvb, offset, 1, ENC_NA);
711 proto_tree_add_item(sep_tree, hf_btavdtp_sep_type , tvb, offset, 1, ENC_NA);
712 proto_tree_add_item(sep_tree, hf_btavdtp_sep_rfa1 , tvb, offset, 1, ENC_NA);
714 if (!pinfo->fd->flags.visited) {
715 sep_entry_t *sep_data;
716 wmem_tree_key_t key[7];
717 guint32 frame_number = pinfo->num;
720 key[0].key = &interface_id;
722 key[1].key = &adapter_id;
724 key[2].key = &chandle;
726 key[3].key = &direction;
730 key[5].key = &frame_number;
734 sep_data = wmem_new(wmem_file_scope(), sep_entry_t);
735 sep_data->seid = seid;
736 sep_data->type = type;
737 sep_data->media_type = media_type;
738 sep_data->int_seid = 0;
739 sep_data->codec = -1;
740 sep_data->content_protection_type = 0;
742 sep_data->state = SEP_STATE_IN_USE;
744 sep_data->state = SEP_STATE_FREE;
747 wmem_tree_insert32_array(sep_list, key, sep_data);
754 col_append_fstr(pinfo->cinfo, COL_INFO, " - items: %u", items);
760 dissect_codec(tvbuff_t *tvb, packet_info *pinfo, proto_item *service_item, proto_tree *tree, gint offset,
761 guint losc, gint media_type, gint media_codec_type, guint32 *vendor_id, guint16 *vendor_codec)
765 guint8 *value8 = (guint8 *) &value;
768 case MEDIA_TYPE_AUDIO:
769 switch(media_codec_type) {
771 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_16000, tvb, offset, 1, ENC_NA);
772 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_32000, tvb, offset, 1, ENC_NA);
773 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_44100, tvb, offset, 1, ENC_NA);
774 proto_tree_add_item(tree, hf_btavdtp_sbc_sampling_frequency_48000, tvb, offset, 1, ENC_NA);
775 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_mono, tvb, offset, 1, ENC_NA);
776 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
777 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_stereo, tvb, offset, 1, ENC_NA);
778 proto_tree_add_item(tree, hf_btavdtp_sbc_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
780 proto_tree_add_item(tree, hf_btavdtp_sbc_block_4, tvb, offset + 1, 1, ENC_NA);
781 proto_tree_add_item(tree, hf_btavdtp_sbc_block_8, tvb, offset + 1, 1, ENC_NA);
782 proto_tree_add_item(tree, hf_btavdtp_sbc_block_12, tvb, offset + 1, 1, ENC_NA);
783 proto_tree_add_item(tree, hf_btavdtp_sbc_block_16, tvb, offset + 1, 1, ENC_NA);
784 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_4, tvb, offset + 1, 1, ENC_NA);
785 proto_tree_add_item(tree, hf_btavdtp_sbc_subbands_8, tvb, offset + 1, 1, ENC_NA);
786 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_snr, tvb, offset + 1, 1, ENC_NA);
787 proto_tree_add_item(tree, hf_btavdtp_sbc_allocation_method_loudness, tvb, offset + 1, 1, ENC_NA);
789 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_min_bitpool, tvb, offset + 2, 1, ENC_NA);
790 value = tvb_get_guint8(tvb, offset + 2);
791 if (value < 2 || value > 250) {
792 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_min_bitpool_out_of_range);
795 pitem = proto_tree_add_item(tree, hf_btavdtp_sbc_max_bitpool, tvb, offset + 3, 1, ENC_NA);
796 value = tvb_get_guint8(tvb, offset + 3);
797 if (value < 2 || value > 250) {
798 expert_add_info(pinfo, pitem, &ei_btavdtp_sbc_max_bitpool_out_of_range);
801 value = tvb_get_h_guint32(tvb, offset);
803 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)",
804 (value8[0] & 0x80) ? "16000 " : "",
805 (value8[0] & 0x40) ? "32000 " : "",
806 (value8[0] & 0x20) ? "44100 " : "",
807 (value8[0] & 0x10) ? "48000 " : "",
808 (value8[0] & 0xF0) ? "" : "not set ",
809 (value8[0] & 0x08) ? "Mono " : "",
810 (value8[0] & 0x04) ? "DualChannel " : "",
811 (value8[0] & 0x02) ? "Stereo " : "",
812 (value8[0] & 0x01) ? "JointStereo " : "",
813 (value8[0] & 0x0F) ? "" : "not set ",
814 (value8[1] & 0x80) ? "4 " : "",
815 (value8[1] & 0x40) ? "8 " : "",
816 (value8[1] & 0x20) ? "12 " : "",
817 (value8[1] & 0x10) ? "16 " : "",
818 (value8[1] & 0xF0) ? "" : "not set ",
819 (value8[1] & 0x08) ? "4 " : "",
820 (value8[1] & 0x04) ? "8 " : "",
821 (value8[1] & 0x0C) ? "" : "not set ",
822 (value8[1] & 0x02) ? "SNR " : "",
823 (value8[1] & 0x01) ? "Loudness " : "",
824 (value8[0] & 0x03) ? "" : "not set ",
828 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)",
829 (value8[0] & 0x80) ? "16000 " : "",
830 (value8[0] & 0x40) ? "32000 " : "",
831 (value8[0] & 0x20) ? "44100 " : "",
832 (value8[0] & 0x10) ? "48000 " : "",
833 (value8[0] & 0xF0) ? "" : "not set ",
834 (value8[0] & 0x08) ? "Mono " : "",
835 (value8[0] & 0x04) ? "DualChannel " : "",
836 (value8[0] & 0x02) ? "Stereo " : "",
837 (value8[0] & 0x01) ? "JointStereo " : "",
838 (value8[0] & 0x0F) ? "" : "not set ",
839 (value8[1] & 0x80) ? "4 " : "",
840 (value8[1] & 0x40) ? "8 " : "",
841 (value8[1] & 0x20) ? "12 " : "",
842 (value8[1] & 0x10) ? "16 " : "",
843 (value8[1] & 0xF0) ? "" : "not set ",
844 (value8[1] & 0x08) ? "4 " : "",
845 (value8[1] & 0x04) ? "8 " : "",
846 (value8[1] & 0x0C) ? "" : "not set ",
847 (value8[1] & 0x02) ? "SNR " : "",
848 (value8[1] & 0x01) ? "Loudness " : "",
849 (value8[0] & 0x03) ? "" : "not set ",
853 col_append_fstr(pinfo->cinfo, COL_INFO, " (none)");
854 proto_item_append_text(service_item, " (none)");
858 case CODEC_MPEG12_AUDIO:
859 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_1, tvb, offset, 1, ENC_NA);
860 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_2, tvb, offset, 1, ENC_NA);
861 proto_tree_add_item(tree, hf_btavdtp_mpeg12_layer_3, tvb, offset, 1, ENC_NA);
862 proto_tree_add_item(tree, hf_btavdtp_mpeg12_crc_protection, tvb, offset, 1, ENC_NA);
863 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_mono, tvb, offset, 1, ENC_NA);
864 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
865 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_stereo, tvb, offset, 1, ENC_NA);
866 proto_tree_add_item(tree, hf_btavdtp_mpeg12_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
868 proto_tree_add_item(tree, hf_btavdtp_mpeg12_rfa, tvb, offset + 1, 1, ENC_NA);
869 proto_tree_add_item(tree, hf_btavdtp_mpeg12_mpf_2, tvb, offset + 1, 1, ENC_NA);
870 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
871 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
872 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
873 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
874 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
875 proto_tree_add_item(tree, hf_btavdtp_mpeg12_sampling_frequency_48000, tvb, offset + 1, 1, ENC_NA);
877 proto_tree_add_item(tree, hf_btavdtp_mpeg12_vbr_supported, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
878 proto_tree_add_item(tree, hf_btavdtp_mpeg12_bit_rate, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
880 case CODEC_MPEG24_AAC:
881 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc, tvb, offset, 1, ENC_NA);
882 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc, tvb, offset, 1, ENC_NA);
883 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp, tvb, offset, 1, ENC_NA);
884 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable, tvb, offset, 1, ENC_NA);
885 proto_tree_add_item(tree, hf_btavdtp_mpeg24_object_type_rfa, tvb, offset, 1, ENC_NA);
887 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_8000, tvb, offset + 1, 1, ENC_NA);
888 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_11025, tvb, offset + 1, 1, ENC_NA);
889 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_12000, tvb, offset + 1, 1, ENC_NA);
890 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_16000, tvb, offset + 1, 1, ENC_NA);
891 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_22050, tvb, offset + 1, 1, ENC_NA);
892 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_24000, tvb, offset + 1, 1, ENC_NA);
893 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_32000, tvb, offset + 1, 1, ENC_NA);
894 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_44100, tvb, offset + 1, 1, ENC_NA);
896 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_48000, tvb, offset + 2, 1, ENC_NA);
897 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_64000, tvb, offset + 2, 1, ENC_NA);
898 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_88200, tvb, offset + 2, 1, ENC_NA);
899 proto_tree_add_item(tree, hf_btavdtp_mpeg24_sampling_frequency_96000, tvb, offset + 2, 1, ENC_NA);
900 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_1, tvb, offset + 2, 1, ENC_NA);
901 proto_tree_add_item(tree, hf_btavdtp_mpeg24_channels_2, tvb, offset + 2, 1, ENC_NA);
902 proto_tree_add_item(tree, hf_btavdtp_mpeg24_rfa, tvb, offset + 2, 1, ENC_NA);
904 proto_tree_add_item(tree, hf_btavdtp_mpeg24_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
905 proto_tree_add_item(tree, hf_btavdtp_mpeg24_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
908 proto_tree_add_item(tree, hf_btavdtp_atrac_version, tvb, offset, 1, ENC_NA);
909 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_single_channel, tvb, offset, 1, ENC_NA);
910 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_dual_channel, tvb, offset, 1, ENC_NA);
911 proto_tree_add_item(tree, hf_btavdtp_atrac_channel_mode_joint_stereo, tvb, offset, 1, ENC_NA);
912 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa1, tvb, offset, 1, ENC_NA);
914 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa2, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
915 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_44100, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
916 proto_tree_add_item(tree, hf_btavdtp_atrac_sampling_frequency_48000, tvb, offset + 1, 3, ENC_BIG_ENDIAN);
917 proto_tree_add_item(tree, hf_btavdtp_atrac_vbr_supported, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
918 proto_tree_add_item(tree, hf_btavdtp_atrac_bit_rate, tvb, offset + 3, 3, ENC_BIG_ENDIAN);
920 proto_tree_add_item(tree, hf_btavdtp_atrac_maximum_sul, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
922 proto_tree_add_item(tree, hf_btavdtp_atrac_rfa3, tvb, offset + 6, 1, ENC_NA);
924 case CODEC_VENDOR: /* non-A2DP */
925 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
928 *vendor_id = tvb_get_letohl(tvb, offset);
931 *vendor_codec = tvb_get_letohs(tvb, offset + 4);
933 switch (tvb_get_letohl(tvb, offset)) {
934 case 0x004F: /* APT Licensing Ltd. */
935 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_apt_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
936 value = tvb_get_letohs(tvb, offset + 4);
938 if (value == 0x0001) { /* APT-X Codec */
939 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000, tvb, offset + 6, 1, ENC_NA);
940 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000, tvb, offset + 6, 1, ENC_NA);
941 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100, tvb, offset + 6, 1, ENC_NA);
942 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000, tvb, offset + 6, 1, ENC_NA);
943 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_mono, tvb, offset + 6, 1, ENC_NA);
944 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel, tvb, offset + 6, 1, ENC_NA);
945 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_stereo, tvb, offset + 6, 1, ENC_NA);
946 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo, tvb, offset + 6, 1, ENC_NA);
948 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s -",
949 val_to_str_const(value, vendor_apt_codec_vals, "unknown codec"));
950 proto_item_append_text(service_item, " (%s -",
951 val_to_str_const(value, vendor_apt_codec_vals, "unknown codec"));
953 value = tvb_get_guint8(tvb, offset + 6);
955 col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s,%s%s%s%s%s)",
956 (value & 0x80) ? " 16000" : "",
957 (value & 0x40) ? " 32000" : "",
958 (value & 0x20) ? " 44100" : "",
959 (value & 0x10) ? " 48000" : "",
960 (value & 0xF0) ? "" : "not set ",
961 (value & 0x08) ? " Mono" : "",
962 (value & 0x04) ? " DualChannel" : "",
963 (value & 0x02) ? " Stereo" : "",
964 (value & 0x01) ? " JointStereo" : "",
965 (value & 0x0F) ? "" : "not set ");
967 proto_item_append_text(service_item, "%s%s%s%s%s,%s%s%s%s%s)",
968 (value & 0x80) ? " 16000" : "",
969 (value & 0x40) ? " 32000" : "",
970 (value & 0x20) ? " 44100" : "",
971 (value & 0x10) ? " 48000" : "",
972 (value & 0xF0) ? "" : "not set ",
973 (value & 0x08) ? " Mono" : "",
974 (value & 0x04) ? " DualChannel" : "",
975 (value & 0x02) ? " Stereo" : "",
976 (value & 0x01) ? " JointStereo" : "",
977 (value & 0x0F) ? "" : "not set ");
979 col_append_fstr(pinfo->cinfo, COL_INFO, " none)");
980 proto_item_append_text(service_item, " none)");
983 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
987 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
988 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
993 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
996 case MEDIA_TYPE_VIDEO:
997 switch(media_codec_type) {
998 case CODEC_H263_BASELINE:
999 case CODEC_H263_PROFILE_3:
1000 case CODEC_H263_PROFILE_8:
1001 proto_tree_add_item(tree, hf_btavdtp_h263_level_10, tvb, offset, 1, ENC_NA);
1002 proto_tree_add_item(tree, hf_btavdtp_h263_level_20, tvb, offset, 1, ENC_NA);
1003 proto_tree_add_item(tree, hf_btavdtp_h263_level_30, tvb, offset, 1, ENC_NA);
1004 proto_tree_add_item(tree, hf_btavdtp_h263_level_rfa, tvb, offset, 1, ENC_NA);
1006 case CODEC_MPEG4_VSP:
1007 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_0, tvb, offset, 1, ENC_NA);
1008 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_1, tvb, offset, 1, ENC_NA);
1009 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_2, tvb, offset, 1, ENC_NA);
1010 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_3, tvb, offset, 1, ENC_NA);
1011 proto_tree_add_item(tree, hf_btavdtp_mpeg4_level_rfa, tvb, offset, 1, ENC_NA);
1013 case CODEC_VENDOR: /* non-VDP */
1014 proto_tree_add_item(tree, hf_btavdtp_vendor_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1015 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_codec_id, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1016 proto_tree_add_item(tree, hf_btavdtp_vendor_specific_value, tvb, offset + 6, losc - 6, ENC_NA);
1019 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1023 proto_tree_add_item(tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1033 dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo,
1034 proto_tree *tree, gint offset, gint *codec,
1035 gint *content_protection_type, guint32 *vendor_id,
1036 guint16 *vendor_codec, guint32 *configuration_offset,
1037 guint8 *configuration_length)
1039 proto_item *pitem = NULL;
1040 proto_item *ptree = NULL;
1041 proto_tree *capabilities_tree;
1042 proto_item *capabilities_item;
1043 proto_tree *service_tree = NULL;
1044 proto_item *service_item = NULL;
1045 gint service_category = 0;
1047 gint recovery_type = 0;
1048 gint maximum_recovery_window_size = 0;
1049 gint maximum_number_of_media_packet_in_parity_code = 0;
1050 gint media_type = 0;
1051 gint media_codec_type = 0;
1053 capabilities_item = proto_tree_add_item(tree, hf_btavdtp_capabilities, tvb, offset, tvb_reported_length(tvb) - offset, ENC_NA);
1054 capabilities_tree = proto_item_add_subtree(capabilities_item, ett_btavdtp_capabilities);
1060 *vendor_id = 0x003F; /* Bluetooth SIG */
1065 if (configuration_length)
1066 *configuration_length = 0;
1068 if (configuration_offset)
1069 *configuration_offset = 0;
1071 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1072 service_category = tvb_get_guint8(tvb, offset);
1073 losc = tvb_get_guint8(tvb, offset + 1);
1074 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"));
1075 service_tree = proto_item_add_subtree(service_item, ett_btavdtp_service);
1077 proto_tree_add_item(service_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1080 proto_tree_add_item(service_tree, hf_btavdtp_length_of_service_category, tvb, offset, 1, ENC_NA);
1083 switch (service_category) {
1084 case SERVICE_CATEGORY_MEDIA_TRANSPORT:
1085 case SERVICE_CATEGORY_REPORTING:
1086 case SERVICE_CATEGORY_DELAY_REPORTING:
1087 /* losc should be 0 */
1089 case SERVICE_CATEGORY_RECOVERY:
1090 recovery_type = tvb_get_guint8(tvb, offset);
1091 pitem = proto_tree_add_item(service_tree, hf_btavdtp_recovery_type, tvb, offset, 1, ENC_NA);
1092 proto_item_append_text(pitem, " (%s)", val_to_str_const(recovery_type, recovery_type_vals, "RFD"));
1096 maximum_recovery_window_size = tvb_get_guint8(tvb, offset);
1097 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1098 if (maximum_recovery_window_size == 0x00) {
1099 proto_item_append_text(pitem, " (Forbidden)");
1100 } else if (maximum_recovery_window_size >= 0x18) {
1101 proto_item_append_text(pitem, " (Undocumented)");
1106 maximum_number_of_media_packet_in_parity_code = tvb_get_guint8(tvb, offset);
1107 proto_tree_add_item(service_tree, hf_btavdtp_maximum_number_of_media_packet_in_parity_code, tvb, offset, 1, ENC_NA);
1108 pitem = proto_tree_add_item(service_tree, hf_btavdtp_maximum_recovery_window_size, tvb, offset, 1, ENC_NA);
1109 if (maximum_number_of_media_packet_in_parity_code == 0x00) {
1110 proto_item_append_text(pitem, " (Forbidden)");
1111 } else if (maximum_number_of_media_packet_in_parity_code >= 0x18) {
1112 proto_item_append_text(pitem, " (Undocumented)");
1117 case SERVICE_CATEGORY_MEDIA_CODEC:
1118 if (configuration_length)
1119 *configuration_length = losc;
1120 if (configuration_offset)
1121 *configuration_offset = offset;
1123 media_type = tvb_get_guint8(tvb, offset) >> 4;
1124 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_media_type, tvb, offset, 1, ENC_NA);
1125 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_rfa , tvb, offset, 1, ENC_NA);
1129 media_codec_type = tvb_get_guint8(tvb, offset);
1131 *codec = media_codec_type;
1134 if (media_type == MEDIA_TYPE_AUDIO) {
1135 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_audio_type, tvb, offset, 1, ENC_NA);
1136 proto_item_append_text(service_item, " - Audio %s",
1137 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1138 col_append_fstr(pinfo->cinfo, COL_INFO, " - Audio %s",
1139 val_to_str_const(media_codec_type, media_codec_audio_type_vals, "unknown codec"));
1140 } else if (media_type == MEDIA_TYPE_VIDEO) {
1141 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_video_type, tvb, offset, 1, ENC_NA);
1142 proto_item_append_text(service_item, " - Video %s",
1143 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1144 col_append_fstr(pinfo->cinfo, COL_INFO, " - Video %s",
1145 val_to_str_const(media_codec_type, media_codec_video_type_vals, "unknown codec"));
1147 proto_tree_add_item(service_tree, hf_btavdtp_media_codec_unknown_type, tvb, offset, 1, ENC_NA);
1148 proto_item_append_text(service_item, " - Unknown 0x%02x", media_codec_type);
1149 col_append_fstr(pinfo->cinfo, COL_INFO, " - Unknown 0x%02x", media_codec_type);
1154 offset = dissect_codec(tvb, pinfo, service_item, service_tree,
1155 offset, losc, media_type, media_codec_type,
1156 vendor_id, vendor_codec);
1159 case SERVICE_CATEGORY_CONTENT_PROTECTION:
1160 proto_tree_add_item(service_tree, hf_btavdtp_content_protection_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1161 if (content_protection_type) {
1162 *content_protection_type = tvb_get_letohs(tvb, offset);
1164 proto_item_append_text(service_item, " - %s",
1165 val_to_str_const(tvb_get_letohs(tvb, offset), content_protection_type_vals, "unknown"));
1171 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1176 case SERVICE_CATEGORY_HEADER_COMPRESSION:
1177 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_backch, tvb, offset, 1, ENC_NA);
1178 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_media, tvb, offset, 1, ENC_NA);
1179 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_recovery, tvb, offset, 1, ENC_NA);
1180 proto_tree_add_item(service_tree, hf_btavdtp_header_compression_rfa, tvb, offset, 1, ENC_NA);
1184 case SERVICE_CATEGORY_MULTIPLEXING:
1185 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_fragmentation, tvb, offset, 1, ENC_NA);
1186 proto_tree_add_item(service_tree, hf_btavdtp_multiplexing_rfa, tvb, offset, 1, ENC_NA);
1191 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Media Transport Session");
1192 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1194 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1195 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1198 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1199 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1205 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Reporting Transport Session");
1206 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1208 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1209 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1212 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1213 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1219 pitem = proto_tree_add_none_format(service_tree, hf_btavdtp_service_multiplexing_entry, tvb, offset, 1 + losc, "Entry: Recovery Transport Session");
1220 ptree = proto_item_add_subtree(pitem, ett_btavdtp_service);
1222 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tsid, tvb, offset, 1, ENC_NA);
1223 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1226 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_tcid, tvb, offset, 1, ENC_NA);
1227 proto_tree_add_item(ptree, hf_btavdtp_multiplexing_entry_rfa, tvb, offset, 1, ENC_NA);
1233 proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1239 pitem = proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
1242 expert_add_info(pinfo, pitem, &ei_btavdtp_unexpected_losc_data);
1250 dissect_seid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
1251 gint seid_side, gint i_item, guint32 *sep_seid,
1252 guint32 interface_id, guint32 adapter_id, guint32 chandle,
1253 guint32 frame_number)
1256 proto_tree *seid_tree = NULL;
1257 proto_item *seid_item = NULL;
1260 seid = tvb_get_guint8(tvb, offset) >> 2;
1265 if (seid_side == SEID_ACP) {
1266 direction = pinfo->p2p_dir;
1267 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_acp_seid_item, tvb, offset, 1,
1268 "ACP SEID [%u - %s %s]", seid,
1269 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1270 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1271 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1272 proto_tree_add_item(seid_tree, hf_btavdtp_acp_seid, tvb, offset, 1, ENC_NA);
1273 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1275 col_append_fstr(pinfo->cinfo, COL_INFO, " - ACP SEID [%u - %s %s]",
1276 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1277 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1279 direction = (pinfo->p2p_dir == P2P_DIR_SENT) ? P2P_DIR_RECV : P2P_DIR_SENT;
1280 seid_item = proto_tree_add_none_format(tree, hf_btavdtp_int_seid_item, tvb, offset, 1,
1281 "INT SEID [%u - %s %s]", seid,
1282 get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1283 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1284 seid_tree = proto_item_add_subtree(seid_item, ett_btavdtp_sep);
1285 proto_tree_add_item(seid_tree, hf_btavdtp_int_seid, tvb, offset, 1, ENC_NA);
1286 if (i_item > 0) proto_item_append_text(seid_item, " item %u", i_item);
1288 col_append_fstr(pinfo->cinfo, COL_INFO, " - INT SEID [%u - %s %s]",
1289 seid, get_sep_media_type(interface_id, adapter_id, chandle, direction, seid, frame_number),
1290 get_sep_type(interface_id, adapter_id, chandle, direction, seid, frame_number));
1293 proto_tree_add_item(seid_tree, hf_btavdtp_rfa_seid, tvb, offset, 1, ENC_NA);
1301 dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1304 proto_tree *btavdtp_tree = NULL;
1305 proto_tree *signal_tree = NULL;
1306 proto_item *signal_item = NULL;
1307 btl2cap_data_t *l2cap_data;
1310 gint packet_type = 0;
1311 gint message_type = 0;
1314 wmem_tree_t *subtree;
1315 wmem_tree_key_t key[8];
1316 channels_info_t *channels_info;
1317 guint32 interface_id;
1323 guint32 frame_number;
1328 gint content_protection_type = 0;
1329 guint32 configuration_offset;
1330 guint8 configuration_length;
1332 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP");
1334 direction = pinfo->p2p_dir;
1335 switch (direction) {
1337 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
1341 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
1344 col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
1348 l2cap_data = (btl2cap_data_t *) data;
1349 DISSECTOR_ASSERT(l2cap_data);
1351 interface_id = l2cap_data->interface_id;
1352 adapter_id = l2cap_data->adapter_id;
1353 chandle = l2cap_data->chandle;
1354 psm = l2cap_data->psm;
1355 cid = l2cap_data->cid;
1356 frame_number = pinfo->num;
1359 key[0].key = &interface_id;
1361 key[1].key = &adapter_id;
1363 key[2].key = &chandle;
1369 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(channels, key);
1370 channels_info = (subtree) ? (channels_info_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1371 if (!(channels_info &&
1372 ((*channels_info->adapter_disconnect_in_frame >= pinfo->num &&
1373 *channels_info->hci_disconnect_in_frame >= pinfo->num &&
1374 *channels_info->l2cap_disconnect_in_frame >= pinfo->num &&
1375 channels_info->disconnect_in_frame >= pinfo->num) ||
1376 (*channels_info->adapter_disconnect_in_frame == 0 ||
1377 *channels_info->hci_disconnect_in_frame == 0 ||
1378 *channels_info->l2cap_disconnect_in_frame == 0 ||
1379 channels_info->disconnect_in_frame == 0)))) {
1381 channels_info = (channels_info_t *) wmem_new (wmem_file_scope(), channels_info_t);
1382 channels_info->control_local_cid = l2cap_data->local_cid;
1383 channels_info->control_remote_cid = l2cap_data->remote_cid;
1384 channels_info->media_local_cid = BTL2CAP_UNKNOWN_CID;
1385 channels_info->media_remote_cid = BTL2CAP_UNKNOWN_CID;
1386 channels_info->disconnect_in_frame = max_disconnect_in_frame;
1387 channels_info->l2cap_disconnect_in_frame = l2cap_data->disconnect_in_frame;
1388 channels_info->hci_disconnect_in_frame = l2cap_data->hci_disconnect_in_frame;
1389 channels_info->adapter_disconnect_in_frame = l2cap_data->adapter_disconnect_in_frame;
1390 channels_info->sep = NULL;
1392 if (!pinfo->fd->flags.visited || (
1393 *channels_info->adapter_disconnect_in_frame == 0 ||
1394 *channels_info->hci_disconnect_in_frame == 0 ||
1395 *channels_info->l2cap_disconnect_in_frame == 0 ||
1396 channels_info->disconnect_in_frame == 0)) {
1398 key[4].key = &frame_number;
1402 channels_info->stream_numbers = wmem_tree_new(wmem_file_scope());
1404 if (*channels_info->adapter_disconnect_in_frame > 0 &&
1405 *channels_info->hci_disconnect_in_frame > 0 &&
1406 *channels_info->l2cap_disconnect_in_frame > 0 &&
1407 channels_info->disconnect_in_frame > 0) {
1408 wmem_tree_insert32_array(channels, key, channels_info);
1411 channels_info->stream_numbers = NULL;
1415 if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1416 l2cap_data->remote_cid == channels_info->control_remote_cid) &&
1417 (channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID ||
1418 (l2cap_data->local_cid == channels_info->media_local_cid &&
1419 l2cap_data->remote_cid == channels_info->media_remote_cid))) {
1421 if (!pinfo->fd->flags.visited && channels_info->media_local_cid == BTL2CAP_UNKNOWN_CID) {
1422 channels_info->media_local_cid = l2cap_data->local_cid;
1423 channels_info->media_remote_cid = l2cap_data->remote_cid;
1427 if (!channels_info->sep) {
1428 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1429 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1431 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1432 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1434 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream ACP SEID [%u - %s %s]",
1435 channels_info->sep->seid, get_sep_media_type(
1436 interface_id, adapter_id, chandle, direction,
1437 channels_info->sep->seid,
1439 get_sep_type(interface_id, adapter_id, chandle, direction,
1440 channels_info->sep->seid,
1443 if (channels_info->sep->media_type == MEDIA_TYPE_AUDIO) {
1444 sep_data_t sep_data;
1445 media_stream_number_value_t *media_stream_number_value;
1446 media_packet_info_t *previous_media_packet_info;
1447 media_packet_info_t *current_media_packet_info;
1448 nstime_t first_abs_ts;
1449 gdouble cumulative_frame_duration;
1450 gdouble avrcp_song_position = -1.0;
1451 btavrcp_song_position_data_t *song_position_data;
1453 sep_data.codec = channels_info->sep->codec;
1454 sep_data.vendor_id = channels_info->sep->vendor_id;
1455 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1456 sep_data.acp_seid = channels_info->sep->seid;
1457 sep_data.int_seid = channels_info->sep->int_seid;
1458 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1459 sep_data.stream_start_in_frame = 0;
1460 sep_data.stream_end_in_frame = 0;
1461 sep_data.configuration_length = channels_info->sep->configuration_length;
1462 sep_data.configuration = channels_info->sep->configuration;
1464 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1465 if (media_stream_number_value) {
1466 sep_data.stream_number = media_stream_number_value->stream_number;
1467 if (media_stream_number_value->stream_start_in_frame == 0)
1468 media_stream_number_value->stream_start_in_frame = pinfo->num;
1470 if (!pinfo->fd->flags.visited)
1471 media_stream_number_value->stream_end_in_frame = pinfo->num;
1473 sep_data.stream_start_in_frame = media_stream_number_value->stream_start_in_frame;
1474 sep_data.stream_end_in_frame = media_stream_number_value->stream_end_in_frame;
1476 sep_data.stream_number = 1;
1480 key[0].key = &interface_id;
1482 key[1].key = &adapter_id;
1484 key[2].key = &chandle;
1488 key[4].key = &direction;
1495 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(btavrcp_song_positions, key);
1496 song_position_data = (subtree) ? (btavrcp_song_position_data_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1497 if (song_position_data && (song_position_data->used_in_frame == 0 ||
1498 song_position_data->used_in_frame == frame_number)) {
1499 avrcp_song_position = song_position_data->song_position;
1500 if (!pinfo->fd->flags.visited)
1501 song_position_data->used_in_frame = frame_number;
1505 key[2].key = &chandle;
1507 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1508 previous_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32_le(subtree, frame_number - 1) : NULL;
1509 if (previous_media_packet_info && previous_media_packet_info->stream_number == sep_data.stream_number ) {
1510 sep_data.previous_media_packet_info = previous_media_packet_info;
1511 first_abs_ts = previous_media_packet_info->first_abs_ts;
1512 cumulative_frame_duration = previous_media_packet_info->cumulative_frame_duration;
1513 if (avrcp_song_position == -1.0)
1514 avrcp_song_position = previous_media_packet_info->avrcp_song_position;
1516 previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1518 if (avrcp_song_position == -1.0)
1519 avrcp_song_position = 0.0;
1520 first_abs_ts = pinfo->abs_ts;
1521 cumulative_frame_duration = 0.0;
1522 sep_data.previous_media_packet_info = (media_packet_info_t *) wmem_new(wmem_epan_scope(), media_packet_info_t);
1523 sep_data.previous_media_packet_info->abs_ts = pinfo->abs_ts;
1524 sep_data.previous_media_packet_info->first_abs_ts = first_abs_ts;
1525 sep_data.previous_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1526 sep_data.previous_media_packet_info->avrcp_song_position = avrcp_song_position;
1527 sep_data.previous_media_packet_info->stream_number = sep_data.stream_number;
1530 if (!pinfo->fd->flags.visited) {
1532 key[5].key = &frame_number;
1536 if (avrcp_song_position == -1.0)
1537 avrcp_song_position = 0.0;
1539 current_media_packet_info = wmem_new(wmem_file_scope(), media_packet_info_t);
1540 current_media_packet_info->abs_ts = pinfo->abs_ts;
1541 current_media_packet_info->first_abs_ts = first_abs_ts;
1542 current_media_packet_info->cumulative_frame_duration = cumulative_frame_duration;
1543 current_media_packet_info->avrcp_song_position = avrcp_song_position;
1544 current_media_packet_info->stream_number = sep_data.stream_number;
1546 wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info);
1552 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
1553 current_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32(subtree, frame_number) : NULL;
1554 if (current_media_packet_info)
1555 sep_data.current_media_packet_info = current_media_packet_info;
1557 sep_data.current_media_packet_info = NULL;
1559 next_tvb = tvb_new_subset_remaining(tvb, offset);
1560 call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data);
1561 } else if (channels_info->sep->media_type == MEDIA_TYPE_VIDEO) {
1562 sep_data_t sep_data;
1563 media_stream_number_value_t *media_stream_number_value;
1565 sep_data.codec = channels_info->sep->codec;
1566 sep_data.vendor_id = channels_info->sep->vendor_id;
1567 sep_data.vendor_codec = channels_info->sep->vendor_codec;
1568 sep_data.acp_seid = channels_info->sep->seid;
1569 sep_data.int_seid = channels_info->sep->int_seid;
1570 sep_data.content_protection_type = channels_info->sep->content_protection_type;
1571 sep_data.stream_start_in_frame = 0;
1572 sep_data.stream_end_in_frame = 0;
1573 sep_data.configuration_length = channels_info->sep->configuration_length;
1574 sep_data.configuration = channels_info->sep->configuration;
1576 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1577 if (media_stream_number_value) {
1578 sep_data.stream_number = media_stream_number_value->stream_number;
1580 sep_data.stream_number = 1;
1583 next_tvb = tvb_new_subset_remaining(tvb, offset);
1584 call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data);
1586 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1587 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1589 col_append_fstr(pinfo->cinfo, COL_INFO, "Media stream on cid=0x%04x", l2cap_data->cid);
1590 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1594 return tvb_reported_length(tvb);
1595 } else if (!(l2cap_data->local_cid == channels_info->control_local_cid &&
1596 l2cap_data->remote_cid == channels_info->control_remote_cid)) {
1597 /* Unknown Stream Channel */
1598 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1599 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1601 col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown channel stream on cid=0x%04x", l2cap_data->cid);
1602 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1603 return tvb_reported_length(tvb);
1606 /* Signaling Channel */
1607 ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
1608 btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
1610 /* AVDTP signaling*/
1611 message_type = (tvb_get_guint8(tvb, offset) & AVDTP_MESSAGE_TYPE_MASK);
1612 packet_type = (tvb_get_guint8(tvb, offset) & AVDTP_PACKET_TYPE_MASK) >> 2;
1614 signal_item = proto_tree_add_item(btavdtp_tree, hf_btavdtp_signal, tvb, offset,
1615 (packet_type == PACKET_TYPE_START) ? 3 : 2, ENC_NA);
1616 signal_tree = proto_item_add_subtree(signal_item, ett_btavdtp_sep);
1618 proto_tree_add_item(signal_tree, hf_btavdtp_transaction, tvb, offset, 1, ENC_NA);
1619 proto_tree_add_item(signal_tree, hf_btavdtp_packet_type, tvb, offset, 1, ENC_NA);
1620 proto_tree_add_item(signal_tree, hf_btavdtp_message_type, tvb, offset, 1, ENC_NA);
1622 if (packet_type == PACKET_TYPE_START) {
1624 proto_tree_add_item(signal_tree, hf_btavdtp_number_of_signal_packets, tvb, offset, 1, ENC_NA);
1627 if (packet_type == PACKET_TYPE_CONTINUE || packet_type == PACKET_TYPE_END) goto LABEL_data;
1630 proto_tree_add_item(signal_tree, hf_btavdtp_rfa0, tvb, offset, 1, ENC_NA);
1631 proto_tree_add_item(signal_tree, hf_btavdtp_signal_id, tvb, offset, 1, ENC_NA);
1633 signal_id = tvb_get_guint8(tvb, offset) & AVDTP_SIGNAL_ID_MASK;
1634 proto_item_append_text(signal_item, ": %s (%s)",
1635 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"),
1636 val_to_str_const(message_type, message_type_vals, "Unknown message type"));
1638 col_append_fstr(pinfo->cinfo, COL_INFO, "%s - %s",
1639 val_to_str_const(message_type, message_type_vals, "Unknown message type"),
1640 val_to_str_const(signal_id, signal_id_vals, "Unknown signal"));
1643 if (message_type != MESSAGE_TYPE_GENERAL_REJECT) switch (signal_id) {
1644 case SIGNAL_ID_DISCOVER:
1645 if (message_type == MESSAGE_TYPE_COMMAND) break;
1646 if (message_type == MESSAGE_TYPE_REJECT) {
1647 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1651 offset = dissect_sep(tvb, pinfo, btavdtp_tree, offset,
1652 interface_id, adapter_id, chandle);
1654 case SIGNAL_ID_GET_CAPABILITIES:
1655 case SIGNAL_ID_GET_ALL_CAPABILITIES:
1656 if (message_type == MESSAGE_TYPE_COMMAND) {
1657 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1658 SEID_ACP, 0, NULL, interface_id,
1659 adapter_id, chandle, frame_number);
1662 if (message_type == MESSAGE_TYPE_REJECT) {
1663 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1667 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1669 case SIGNAL_ID_SET_CONFIGURATION:
1670 if (message_type == MESSAGE_TYPE_COMMAND) {
1673 guint16 vendor_codec;
1674 guint32 reverse_direction;
1676 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1677 SEID_ACP, 0, &seid, interface_id,
1678 adapter_id, chandle, frame_number);
1679 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1680 SEID_INT, 0, &int_seid, interface_id,
1681 adapter_id, chandle, frame_number);
1682 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1683 &codec, &content_protection_type, &vendor_id,
1684 &vendor_codec, &configuration_offset, &configuration_length);
1686 if (!pinfo->fd->flags.visited) {
1688 key[0].key = &interface_id;
1690 key[1].key = &adapter_id;
1692 key[2].key = &chandle;
1694 key[3].key = &direction;
1700 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1701 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1704 sep->vendor_id = vendor_id;
1705 sep->vendor_codec = vendor_codec;
1706 sep->content_protection_type = content_protection_type;
1707 sep->int_seid = int_seid;
1708 if (configuration_length > 0) {
1709 sep->configuration_length = configuration_length;
1710 sep->configuration = (guint8 *) tvb_memdup(wmem_file_scope(),
1711 tvb, configuration_offset, configuration_length);
1714 if (direction == P2P_DIR_SENT)
1715 reverse_direction = P2P_DIR_RECV;
1716 else if (direction == P2P_DIR_RECV)
1717 reverse_direction = P2P_DIR_SENT;
1719 reverse_direction = P2P_DIR_UNKNOWN;
1722 key[3].key = &reverse_direction;
1724 key[4].key = &int_seid;
1726 key[5].key = &frame_number;
1730 wmem_tree_insert32_array(sep_list, key, sep);
1737 if (message_type == MESSAGE_TYPE_REJECT) {
1738 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1741 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1746 case SIGNAL_ID_GET_CONFIGURATION:
1747 if (message_type == MESSAGE_TYPE_COMMAND) {
1748 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1749 SEID_ACP, 0, NULL, interface_id,
1750 adapter_id, chandle, frame_number);
1753 if (message_type == MESSAGE_TYPE_REJECT) {
1754 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1758 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL, NULL, NULL, NULL, NULL);
1760 case SIGNAL_ID_RECONFIGURE:
1761 if (message_type == MESSAGE_TYPE_COMMAND) {
1763 guint16 vendor_codec;
1765 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1766 SEID_ACP, 0, &seid, interface_id,
1767 adapter_id, chandle, frame_number);
1768 offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset,
1769 &codec, &content_protection_type, &vendor_id,
1770 &vendor_codec, &configuration_offset, &configuration_length);
1772 if (!pinfo->fd->flags.visited) {
1774 key[0].key = &interface_id;
1776 key[1].key = &adapter_id;
1778 key[2].key = &chandle;
1780 key[3].key = &direction;
1786 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1787 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1790 sep->vendor_id = vendor_id;
1791 sep->vendor_codec = vendor_codec;
1792 sep->content_protection_type = content_protection_type;
1793 if (configuration_length > 0) {
1794 sep->configuration_length = configuration_length;
1795 sep->configuration = (guint8 *) tvb_memdup(wmem_file_scope(),
1796 tvb, configuration_offset, configuration_length);
1803 if (message_type == MESSAGE_TYPE_REJECT) {
1804 proto_tree_add_item(btavdtp_tree, hf_btavdtp_service_category, tvb, offset, 1, ENC_NA);
1807 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1812 case SIGNAL_ID_OPEN:
1813 if (message_type == MESSAGE_TYPE_COMMAND) {
1814 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1815 SEID_ACP, 0, &seid, interface_id,
1816 adapter_id, chandle, frame_number);
1818 if (!pinfo->fd->flags.visited) {
1820 key[0].key = &interface_id;
1822 key[1].key = &adapter_id;
1824 key[2].key = &chandle;
1826 key[3].key = &direction;
1832 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_list, key);
1833 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1835 sep->state = SEP_STATE_OPEN;
1838 key[3].key = &frame_number;
1842 wmem_tree_insert32_array(sep_open, key, sep);
1847 if (message_type == MESSAGE_TYPE_REJECT) {
1848 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1852 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->flags.visited) {
1855 key[0].key = &interface_id;
1857 key[1].key = &adapter_id;
1859 key[2].key = &chandle;
1863 subtree = (wmem_tree_t *) wmem_tree_lookup32_array(sep_open, key);
1864 sep = (subtree) ? (sep_entry_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
1865 if (sep && sep->state == SEP_STATE_OPEN) {
1866 sep->state = SEP_STATE_IN_USE;
1867 channels_info->sep = sep;
1871 case SIGNAL_ID_START:
1872 if (message_type == MESSAGE_TYPE_COMMAND) {
1874 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1875 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1876 SEID_ACP, i_sep, NULL,
1877 interface_id, adapter_id, chandle, frame_number);
1882 if (message_type == MESSAGE_TYPE_REJECT) {
1883 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1885 interface_id, adapter_id, chandle, frame_number);
1886 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1891 if (message_type == MESSAGE_TYPE_ACCEPT && !pinfo->fd->flags.visited) {
1892 media_stream_number_value_t *media_stream_number_value;
1893 guint32 stream_number = 0;
1895 media_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(channels_info->stream_numbers, frame_number - 1);
1896 #if RTP_PLAYER_WORKAROUND == TRUE
1898 media_stream_number_value_t *file_scope_stream_number_value;
1900 if (media_stream_number_value) {
1901 stream_number = media_stream_number_value->stream_number;
1903 file_scope_stream_number_value = (media_stream_number_value_t *) wmem_tree_lookup32_le(file_scope_stream_number, frame_number - 1);
1904 if (file_scope_stream_number_value)
1905 stream_number = file_scope_stream_number_value->stream_number + 1;
1910 file_scope_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
1911 file_scope_stream_number_value->stream_number = stream_number;
1912 wmem_tree_insert32(file_scope_stream_number, frame_number, file_scope_stream_number_value);
1915 if (media_stream_number_value)
1916 stream_number = media_stream_number_value->stream_number;
1921 media_stream_number_value = wmem_new(wmem_file_scope(), media_stream_number_value_t);
1922 media_stream_number_value->stream_number = stream_number + 1;
1923 media_stream_number_value->stream_start_in_frame = 0;
1924 media_stream_number_value->stream_end_in_frame = 0;
1926 wmem_tree_insert32(channels_info->stream_numbers, frame_number, media_stream_number_value);
1929 case SIGNAL_ID_CLOSE:
1930 if (message_type == MESSAGE_TYPE_COMMAND) {
1931 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1932 SEID_ACP, 0, NULL, interface_id,
1933 adapter_id, chandle, frame_number);
1936 if (message_type == MESSAGE_TYPE_REJECT) {
1937 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1941 if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
1942 channels_info->disconnect_in_frame > pinfo->num) {
1943 channels_info->disconnect_in_frame = pinfo->num;
1946 case SIGNAL_ID_SUSPEND:
1947 if (message_type == MESSAGE_TYPE_COMMAND) {
1949 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1950 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1951 SEID_ACP, i_sep, NULL,
1952 interface_id, adapter_id, chandle, frame_number);
1957 if (message_type == MESSAGE_TYPE_REJECT) {
1958 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1959 SEID_ACP, 0, NULL, interface_id,
1960 adapter_id, chandle, frame_number);
1961 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1966 case SIGNAL_ID_ABORT:
1967 if (message_type == MESSAGE_TYPE_COMMAND) {
1968 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1969 SEID_ACP, 0, NULL, interface_id,
1970 adapter_id, chandle, frame_number);
1973 if (message_type == MESSAGE_TYPE_REJECT) {
1974 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1978 if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
1979 channels_info->disconnect_in_frame > pinfo->num) {
1980 channels_info->disconnect_in_frame = pinfo->num;
1983 case SIGNAL_ID_SECURITY_CONTROL:
1984 if (message_type == MESSAGE_TYPE_COMMAND) {
1985 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
1986 SEID_ACP, 0, NULL, interface_id,
1987 adapter_id, chandle, frame_number);
1988 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1989 offset += tvb_reported_length_remaining(tvb, offset);
1992 if (message_type == MESSAGE_TYPE_REJECT) {
1993 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
1998 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
1999 offset += tvb_reported_length_remaining(tvb, offset);
2001 case SIGNAL_ID_DELAY_REPORT:
2002 if (message_type == MESSAGE_TYPE_COMMAND) {
2004 delay = tvb_get_ntohs(tvb, offset + 1);
2005 col_append_fstr(pinfo->cinfo, COL_INFO, "(%u.%u ms)", delay/10, delay%10);
2006 offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset,
2008 interface_id, adapter_id, chandle, frame_number);
2009 pitem = proto_tree_add_item(btavdtp_tree, hf_btavdtp_delay, tvb, offset, 2, ENC_BIG_ENDIAN);
2010 proto_item_append_text(pitem, " (1/10 ms)");
2014 if (message_type == MESSAGE_TYPE_REJECT) {
2015 proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_NA);
2024 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2025 proto_tree_add_item(btavdtp_tree, hf_btavdtp_data, tvb, offset, -1, ENC_NA);
2033 proto_register_btavdtp(void)
2037 static hf_register_info hf[] = {
2038 { &hf_btavdtp_signal,
2039 { "Signal", "btavdtp.signal",
2040 FT_NONE, BASE_NONE, NULL, 0x00,
2043 { &hf_btavdtp_message_type,
2044 { "Message Type", "btavdtp.message_type",
2045 FT_UINT8, BASE_HEX, VALS(message_type_vals), AVDTP_MESSAGE_TYPE_MASK,
2048 { &hf_btavdtp_packet_type,
2049 { "Packet Type", "btavdtp.packet_type",
2050 FT_UINT8, BASE_HEX, VALS(packet_type_vals), AVDTP_PACKET_TYPE_MASK,
2053 { &hf_btavdtp_transaction,
2054 { "Transaction", "btavdtp.transaction",
2055 FT_UINT8, BASE_HEX, NULL, AVDTP_TRANSACTION_MASK,
2058 { &hf_btavdtp_signal_id,
2059 { "Signal", "btavdtp.signal_id",
2060 FT_UINT8, BASE_HEX, VALS(signal_id_vals), AVDTP_SIGNAL_ID_MASK,
2064 { "RFA", "btavdtp.rfa0",
2065 FT_UINT8, BASE_HEX, NULL, AVDTP_RFA0_MASK,
2068 { &hf_btavdtp_number_of_signal_packets,
2069 { "Number of signal packets", "btavdtp.num_signal_packets",
2070 FT_UINT8, BASE_DEC, NULL, 0,
2073 { &hf_btavdtp_error_code,
2074 { "Error Code", "btavdtp.error_code",
2075 FT_UINT8, BASE_HEX, VALS(error_code_vals), 0x00,
2078 { &hf_btavdtp_sep_seid,
2079 { "SEID", "btavdtp.sep_seid",
2080 FT_UINT8, BASE_DEC, NULL, 0xFC,
2083 { &hf_btavdtp_sep_inuse,
2084 { "In Use", "btavdtp.sep_inuse",
2085 FT_UINT8, BASE_HEX, VALS(true_false), 0x02,
2088 { &hf_btavdtp_sep_rfa0,
2089 { "RFA0", "btavdtp.sep_rfa0",
2090 FT_UINT8, BASE_HEX, NULL, 0x01,
2093 { &hf_btavdtp_sep_media_type,
2094 { "Media Type", "btavdtp.sep_media_type",
2095 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2098 { &hf_btavdtp_sep_type,
2099 { "Type", "btavdtp.sep_type",
2100 FT_UINT8, BASE_HEX, VALS(sep_type_vals), 0x08,
2103 { &hf_btavdtp_sep_rfa1,
2104 { "RFA1", "btavdtp.sep_rfa1",
2105 FT_UINT8, BASE_HEX, NULL, 0x07,
2108 { &hf_btavdtp_acp_sep,
2109 { "ACP SEP", "btavdtp.acp_sep",
2110 FT_NONE, BASE_NONE, NULL, 0x00,
2113 { &hf_btavdtp_acp_seid_item,
2114 { "ACP SEID", "btavdtp.acp_seid_item",
2115 FT_NONE, BASE_NONE, NULL, 0x00,
2118 { &hf_btavdtp_int_seid_item,
2119 { "INT SEID", "btavdtp.int_seid_item",
2120 FT_NONE, BASE_NONE, NULL, 0x00,
2123 { &hf_btavdtp_acp_seid,
2124 { "ACP SEID", "btavdtp.acp_seid",
2125 FT_UINT8, BASE_DEC, NULL, 0xFC,
2128 { &hf_btavdtp_int_seid,
2129 { "INT SEID", "btavdtp.int_seid",
2130 FT_UINT8, BASE_DEC, NULL, 0xFC,
2133 { &hf_btavdtp_rfa_seid,
2134 { "RFA", "btavdtp.rfa_seid",
2135 FT_UINT8, BASE_HEX, NULL, 0x03,
2138 { &hf_btavdtp_service_category,
2139 { "Service Category", "btavdtp.service_category",
2140 FT_UINT8, BASE_HEX, VALS(service_category_vals), 0x00,
2143 { &hf_btavdtp_length_of_service_category,
2144 { "Length of Service Category", "btavdtp.length_of_service_category",
2145 FT_UINT8, BASE_HEX, NULL, 0x00,
2148 { &hf_btavdtp_delay,
2149 { "Delay", "btavdtp.delay",
2150 FT_UINT16, BASE_DEC, NULL, 0x00,
2153 { &hf_btavdtp_recovery_type,
2154 { "Service Category", "btavdtp.recovery_type",
2155 FT_UINT8, BASE_HEX, VALS(recovery_type_vals), 0x00,
2158 { &hf_btavdtp_maximum_recovery_window_size,
2159 { "Service Category", "btavdtp.maximum_recovery_window_size",
2160 FT_UINT8, BASE_HEX, NULL, 0x00,
2163 { &hf_btavdtp_maximum_number_of_media_packet_in_parity_code,
2164 { "Service Category", "btavdtp.maximum_number_of_media_packet_in_parity_code",
2165 FT_UINT8, BASE_HEX, NULL, 0x00,
2168 { &hf_btavdtp_multiplexing_fragmentation,
2169 { "Fragmentation", "btavdtp.multiplexing_fragmentation",
2170 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2173 { &hf_btavdtp_multiplexing_rfa,
2174 { "RFA", "btavdtp.multiplexing_rfa",
2175 FT_UINT8, BASE_HEX, NULL, 0x7F,
2178 { &hf_btavdtp_multiplexing_tsid,
2179 { "TSID", "btavdtp.multiplexing_tsid",
2180 FT_UINT8, BASE_HEX, VALS(multiplexing_tsid_vals), 0xF8,
2183 { &hf_btavdtp_multiplexing_tcid,
2184 { "TCID", "btavdtp.multiplexing_tcid",
2185 FT_UINT8, BASE_HEX, VALS(multiplexing_tcid_vals), 0xF8,
2188 { &hf_btavdtp_multiplexing_entry_rfa,
2189 { "RFA", "btavdtp.multiplexing_entry_rfa",
2190 FT_UINT8, BASE_HEX, NULL, 0x07,
2193 { &hf_btavdtp_header_compression_backch,
2194 { "BackCh", "btavdtp.header_compression_backch",
2195 FT_UINT8, BASE_HEX, VALS(true_false), 0x80,
2198 { &hf_btavdtp_header_compression_media,
2199 { "Media", "btavdtp.header_compression_media",
2200 FT_UINT8, BASE_HEX, VALS(true_false), 0x40,
2203 { &hf_btavdtp_header_compression_recovery,
2204 { "Recovery", "btavdtp.header_compression_recovery",
2205 FT_UINT8, BASE_HEX, VALS(true_false), 0x20,
2208 { &hf_btavdtp_header_compression_rfa,
2209 { "RFA", "btavdtp.header_compression_rfa",
2210 FT_UINT8, BASE_HEX, NULL, 0x1f,
2213 { &hf_btavdtp_content_protection_type,
2214 { "Type", "btavdtp.content_protection_type",
2215 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
2218 { &hf_btavdtp_media_codec_media_type,
2219 { "Media Type", "btavdtp.media_codec_media_type",
2220 FT_UINT8, BASE_HEX, VALS(media_type_vals), 0xF0,
2223 { &hf_btavdtp_media_codec_rfa,
2224 { "RFA", "btavdtp.media_codec_rfa",
2225 FT_UINT8, BASE_HEX, NULL, 0x0F,
2228 { &hf_btavdtp_media_codec_audio_type,
2229 { "Media Codec Audio Type", "btavdtp.media_codec_audio_type",
2230 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
2233 { &hf_btavdtp_media_codec_video_type,
2234 { "Media Codec Video Type", "btavdtp.media_codec_video_type",
2235 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
2238 { &hf_btavdtp_media_codec_unknown_type,
2239 { "Media Codec Unknown Type", "btavdtp.media_codec_unknown_type",
2240 FT_UINT8, BASE_HEX, NULL, 0x00,
2243 { &hf_btavdtp_sbc_sampling_frequency_16000,
2244 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2245 FT_BOOLEAN, 8, NULL, 0x80,
2248 { &hf_btavdtp_sbc_sampling_frequency_32000,
2249 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2250 FT_BOOLEAN, 8, NULL, 0x40,
2253 { &hf_btavdtp_sbc_sampling_frequency_44100,
2254 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2255 FT_BOOLEAN, 8, NULL, 0x20,
2258 { &hf_btavdtp_sbc_sampling_frequency_48000,
2259 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2260 FT_BOOLEAN, 8, NULL, 0x10,
2263 { &hf_btavdtp_sbc_channel_mode_mono,
2264 { "Channel Mode Mono", "btavdtp.codec.sbc.channel_mode.mono",
2265 FT_BOOLEAN, 8, NULL, 0x08,
2268 { &hf_btavdtp_sbc_channel_mode_dual_channel,
2269 { "Channel Mode Dual Channel", "btavdtp.codec.sbc.channel_mode.dual_channel",
2270 FT_BOOLEAN, 8, NULL, 0x04,
2273 { &hf_btavdtp_sbc_channel_mode_stereo,
2274 { "Channel Mode Stereo", "btavdtp.codec.sbc.channel_mode.stereo",
2275 FT_BOOLEAN, 8, NULL, 0x02,
2278 { &hf_btavdtp_sbc_channel_mode_joint_stereo,
2279 { "Channel Mode Joint Stereo", "btavdtp.codec.sbc.channel_mode.joint_stereo",
2280 FT_BOOLEAN, 8, NULL, 0x01,
2283 { &hf_btavdtp_sbc_block_4,
2284 { "Block Length 4", "btavdtp.codec.sbc.block.4",
2285 FT_BOOLEAN, 8, NULL, 0x80,
2288 { &hf_btavdtp_sbc_block_8,
2289 { "Block Length 8", "btavdtp.codec.sbc.block.8",
2290 FT_BOOLEAN, 8, NULL, 0x40,
2293 { &hf_btavdtp_sbc_block_12,
2294 { "Block Length 12", "btavdtp.codec.sbc.block.12",
2295 FT_BOOLEAN, 8, NULL, 0x20,
2298 { &hf_btavdtp_sbc_block_16,
2299 { "Block Length 16", "btavdtp.codec.sbc.block.16",
2300 FT_BOOLEAN, 8, NULL, 0x10,
2303 { &hf_btavdtp_sbc_subbands_4,
2304 { "Subbands 4", "btavdtp.codec.sbc.subbands.4",
2305 FT_BOOLEAN, 8, NULL, 0x08,
2308 { &hf_btavdtp_sbc_subbands_8,
2309 { "Subbands 8", "btavdtp.codec.sbc.subbands.8",
2310 FT_BOOLEAN, 8, NULL, 0x04,
2313 { &hf_btavdtp_sbc_allocation_method_snr,
2314 { "Allocation Method SNR", "btavdtp.codec.sbc.allocation_method.snr",
2315 FT_BOOLEAN, 8, NULL, 0x02,
2318 { &hf_btavdtp_sbc_allocation_method_loudness,
2319 { "Allocation Method Loudness", "btavdtp.codec.sbc.allocation_method.loudness",
2320 FT_BOOLEAN, 8, NULL, 0x01,
2323 { &hf_btavdtp_sbc_min_bitpool,
2324 { "Minimum Bitpool", "btavdtp.codec.sbc.minimum_bitpool",
2325 FT_UINT8, BASE_DEC, NULL, 0x00,
2328 { &hf_btavdtp_sbc_max_bitpool,
2329 { "Maximum Bitpool", "btavdtp.codec.sbc.maximum_bitpool",
2330 FT_UINT8, BASE_DEC, NULL, 0x00,
2333 { &hf_btavdtp_mpeg12_layer_1,
2334 { "MP1", "btavdtp.codec.mpeg12.layer_1",
2335 FT_BOOLEAN, 8, NULL, 0x80,
2336 "MPEG Layer 1", HFILL }
2338 { &hf_btavdtp_mpeg12_layer_2,
2339 { "MP2", "btavdtp.codec.mpeg12.layer_2",
2340 FT_BOOLEAN, 8, NULL, 0x40,
2341 "MPEG Layer 2", HFILL }
2343 { &hf_btavdtp_mpeg12_layer_3,
2344 { "MP3", "btavdtp.codec.mpeg12.layer_3",
2345 FT_BOOLEAN, 8, NULL, 0x20,
2346 "MPEG Layer 3", HFILL }
2348 { &hf_btavdtp_mpeg12_crc_protection,
2349 { "CRC Protection", "btavdtp.codec.mpeg12.crc_protection",
2350 FT_BOOLEAN, 8, NULL, 0x10,
2353 { &hf_btavdtp_mpeg12_channel_mode_mono,
2354 { "Channel Mode Mono", "btavdtp.codec.mpeg12.channel_mode.mono",
2355 FT_BOOLEAN, 8, NULL, 0x08,
2358 { &hf_btavdtp_mpeg12_channel_mode_dual_channel,
2359 { "Channel Mode Dual Channel", "btavdtp.codec.mpeg12.channel_mode.dual_channel",
2360 FT_BOOLEAN, 8, NULL, 0x04,
2363 { &hf_btavdtp_mpeg12_channel_mode_stereo,
2364 { "Channel Mode Stereo", "btavdtp.codec.mpeg12.channel_mode.stereo",
2365 FT_BOOLEAN, 8, NULL, 0x02,
2368 { &hf_btavdtp_mpeg12_channel_mode_joint_stereo,
2369 { "Channel Mode Joint Stereo", "btavdtp.codec.mpeg12.channel_mode.joint_stereo",
2370 FT_BOOLEAN, 8, NULL, 0x01,
2373 { &hf_btavdtp_mpeg12_rfa,
2374 { "RFA", "btavdtp.codec.mpeg12.rfa",
2375 FT_BOOLEAN, 8, NULL, 0x80,
2378 { &hf_btavdtp_mpeg12_mpf_2,
2379 { "Media Payload Format 2", "btavdtp.codec.mpeg12.mpf_2",
2380 FT_BOOLEAN, 8, NULL, 0x40,
2383 { &hf_btavdtp_mpeg12_sampling_frequency_16000,
2384 { "Sampling Frequency 16000 Hz", "btavdtp.codec.sbc.sampling_frequency.16000",
2385 FT_BOOLEAN, 8, NULL, 0x20,
2388 { &hf_btavdtp_mpeg12_sampling_frequency_22050,
2389 { "Sampling Frequency 22050 Hz", "btavdtp.codec.sbc.sampling_frequency.22050",
2390 FT_BOOLEAN, 8, NULL, 0x10,
2393 { &hf_btavdtp_mpeg12_sampling_frequency_24000,
2394 { "Sampling Frequency 24000 Hz", "btavdtp.codec.sbc.sampling_frequency.24000",
2395 FT_BOOLEAN, 8, NULL, 0x08,
2398 { &hf_btavdtp_mpeg12_sampling_frequency_32000,
2399 { "Sampling Frequency 32000 Hz", "btavdtp.codec.sbc.sampling_frequency.32000",
2400 FT_BOOLEAN, 8, NULL, 0x04,
2403 { &hf_btavdtp_mpeg12_sampling_frequency_44100,
2404 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2405 FT_BOOLEAN, 8, NULL, 0x02,
2408 { &hf_btavdtp_mpeg12_sampling_frequency_48000,
2409 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2410 FT_BOOLEAN, 8, NULL, 0x01,
2413 { &hf_btavdtp_mpeg12_vbr_supported,
2414 { "VBR Supported", "btavdtp.codec.mpeg12.vbr",
2415 FT_BOOLEAN, 16, NULL, 0x8000,
2418 { &hf_btavdtp_mpeg12_bit_rate,
2419 { "Bit Rate", "btavdtp.codec.mpeg12.bit_rate",
2420 FT_UINT16, BASE_HEX, NULL, 0x7FFF,
2423 { &hf_btavdtp_mpeg24_object_type_mpeg2_aac_lc,
2424 { "MPEG2 ACC LC", "btavdtp.codec.mpeg24.object_type.mpeg2_aac_lc",
2425 FT_BOOLEAN, 8, NULL, 0x80,
2428 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_lc,
2429 { "MPEG4 ACC LC", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_lc",
2430 FT_BOOLEAN, 8, NULL, 0x40,
2433 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_ltp,
2434 { "MPEG4 ACC LTP", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_ltp",
2435 FT_BOOLEAN, 8, NULL, 0x20,
2438 { &hf_btavdtp_mpeg24_object_type_mpeg4_aac_scalable,
2439 { "MPEG4 ACC Scalable", "btavdtp.codec.mpeg24.object_type.mpeg4_aac_scalable",
2440 FT_BOOLEAN, 8, NULL, 0x10,
2443 { &hf_btavdtp_mpeg24_object_type_rfa,
2444 { "RFA", "btavdtp.codec.mpeg24.object_type.rfa",
2445 FT_UINT8, BASE_HEX, NULL, 0x0F,
2448 { &hf_btavdtp_mpeg24_sampling_frequency_8000,
2449 { "Sampling Frequency 8000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.8000",
2450 FT_BOOLEAN, 8, NULL, 0x80,
2453 { &hf_btavdtp_mpeg24_sampling_frequency_11025,
2454 { "Sampling Frequency 11025 Hz", "btavdtp.codec.mpeg24.sampling_frequency.11025",
2455 FT_BOOLEAN, 8, NULL, 0x40,
2458 { &hf_btavdtp_mpeg24_sampling_frequency_12000,
2459 { "Sampling Frequency 12000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.12000",
2460 FT_BOOLEAN, 8, NULL, 0x20,
2463 { &hf_btavdtp_mpeg24_sampling_frequency_16000,
2464 { "Sampling Frequency 16000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.16000",
2465 FT_BOOLEAN, 8, NULL, 0x10,
2468 { &hf_btavdtp_mpeg24_sampling_frequency_22050,
2469 { "Sampling Frequency 22050 Hz", "btavdtp.codec.mpeg24.sampling_frequency.22050",
2470 FT_BOOLEAN, 8, NULL, 0x08,
2473 { &hf_btavdtp_mpeg24_sampling_frequency_24000,
2474 { "Sampling Frequency 24000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.24000",
2475 FT_BOOLEAN, 8, NULL, 0x04,
2478 { &hf_btavdtp_mpeg24_sampling_frequency_32000,
2479 { "Sampling Frequency 32000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.32000",
2480 FT_BOOLEAN, 8, NULL, 0x02,
2483 { &hf_btavdtp_mpeg24_sampling_frequency_44100,
2484 { "Sampling Frequency 44100 Hz", "btavdtp.codec.mpeg24.sampling_frequency.44100",
2485 FT_BOOLEAN, 8, NULL, 0x01,
2488 { &hf_btavdtp_mpeg24_sampling_frequency_48000,
2489 { "Sampling Frequency 48000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.48000",
2490 FT_BOOLEAN, 8, NULL, 0x80,
2493 { &hf_btavdtp_mpeg24_sampling_frequency_64000,
2494 { "Sampling Frequency 64000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.64000",
2495 FT_BOOLEAN, 8, NULL, 0x40,
2498 { &hf_btavdtp_mpeg24_sampling_frequency_88200,
2499 { "Sampling Frequency 88200 Hz", "btavdtp.codec.mpeg24.sampling_frequency.88200",
2500 FT_BOOLEAN, 8, NULL, 0x20,
2503 { &hf_btavdtp_mpeg24_sampling_frequency_96000,
2504 { "Sampling Frequency 96000 Hz", "btavdtp.codec.mpeg24.sampling_frequency.96000",
2505 FT_BOOLEAN, 8, NULL, 0x10,
2508 { &hf_btavdtp_mpeg24_channels_1,
2509 { "Channels 1", "btavdtp.codec.mpeg24.channels.1",
2510 FT_BOOLEAN, 8, NULL, 0x08,
2513 { &hf_btavdtp_mpeg24_channels_2,
2514 { "Channels 2", "btavdtp.codec.mpeg24.channels.2",
2515 FT_BOOLEAN, 8, NULL, 0x04,
2518 { &hf_btavdtp_mpeg24_rfa,
2519 { "RFA", "btavdtp.codec.mpeg24.rfa",
2520 FT_UINT8, BASE_HEX, NULL, 0x03,
2523 { &hf_btavdtp_mpeg24_vbr_supported,
2524 { "VBR Supported", "btavdtp.codec.mpeg24.vbr",
2525 FT_BOOLEAN, 24, NULL, 0x800000,
2528 { &hf_btavdtp_mpeg24_bit_rate,
2529 { "Bit Rate", "btavdtp.codec.mpeg24.bit_rate",
2530 FT_UINT24, BASE_HEX, NULL, 0x7FFFFF,
2533 { &hf_btavdtp_atrac_version,
2534 { "Version", "btavdtp.codec.atrac.version",
2535 FT_UINT8, BASE_DEC, NULL, 0xE0,
2538 { &hf_btavdtp_atrac_channel_mode_single_channel,
2539 { "Channel Mode Single Channel", "btavdtp.codec.atrac.channel_mode.single_channel",
2540 FT_BOOLEAN, 8, NULL, 0x10,
2543 { &hf_btavdtp_atrac_channel_mode_dual_channel,
2544 { "Channel Mode Dual Channel", "btavdtp.codec.atrac.channel_mode.dual_channel",
2545 FT_BOOLEAN, 8, NULL, 0x08,
2548 { &hf_btavdtp_atrac_channel_mode_joint_stereo,
2549 { "Channel Mode Joint Stereo", "btavdtp.codec.atrac.channel_mode.joint_stereo",
2550 FT_BOOLEAN, 8, NULL, 0x04,
2553 { &hf_btavdtp_atrac_rfa1,
2554 { "RFA", "btavdtp.codec.atrac.rfa1",
2555 FT_UINT8, BASE_HEX, NULL, 0x03,
2558 { &hf_btavdtp_atrac_rfa2,
2559 { "RFA", "btavdtp.codec.atrac.rfa2",
2560 FT_UINT24, BASE_HEX, NULL, 0xC00000,
2563 { &hf_btavdtp_atrac_sampling_frequency_44100,
2564 { "Sampling Frequency 44100 Hz", "btavdtp.codec.sbc.sampling_frequency.44100",
2565 FT_BOOLEAN, 24, NULL, 0x200000,
2568 { &hf_btavdtp_atrac_sampling_frequency_48000,
2569 { "Sampling Frequency 48000 Hz", "btavdtp.codec.sbc.sampling_frequency.48000",
2570 FT_BOOLEAN, 24, NULL, 0x100000,
2573 { &hf_btavdtp_atrac_vbr_supported,
2574 { "VBR Supported", "btavdtp.codec.atrac.vbr",
2575 FT_BOOLEAN, 24, NULL, 0x080000,
2578 { &hf_btavdtp_atrac_bit_rate,
2579 { "Bit Rate", "btavdtp.codec.atrac.bit_rate",
2580 FT_UINT24, BASE_HEX, NULL, 0x07FFFF,
2583 { &hf_btavdtp_atrac_maximum_sul,
2584 { "Maximum SUL", "btavdtp.codec.atrac.maximum_sul",
2585 FT_UINT8, BASE_DEC, NULL, 0x00,
2586 "Sound Unit Length (SUL) is one of the parameters that determine bit rate of the audio stream.", HFILL }
2588 { &hf_btavdtp_atrac_rfa3,
2589 { "RFA", "btavdtp.codec.atrac.rfa3",
2590 FT_UINT8, BASE_HEX, NULL, 0x00,
2593 { &hf_btavdtp_h263_level_10,
2594 { "H264 Level 10", "btavdtp.codec.h264.level.10",
2595 FT_BOOLEAN, 8, NULL, 0x80,
2598 { &hf_btavdtp_h263_level_20,
2599 { "H264 Level 20", "btavdtp.codec.h264.level.20",
2600 FT_BOOLEAN, 8, NULL, 0x40,
2603 { &hf_btavdtp_h263_level_30,
2604 { "H264 Level 30", "btavdtp.codec.h264.level.30",
2605 FT_BOOLEAN, 8, NULL, 0x20,
2608 { &hf_btavdtp_h263_level_rfa,
2609 { "H264 Level RFA", "btavdtp.codec.h264.level.rfa",
2610 FT_UINT8, BASE_HEX, NULL, 0x1F,
2613 { &hf_btavdtp_mpeg4_level_0,
2614 { "MPEG Level 0", "btavdtp.codec.mpeg4.level.0",
2615 FT_BOOLEAN, 8, NULL, 0x80,
2618 { &hf_btavdtp_mpeg4_level_1,
2619 { "MPEG Level 1", "btavdtp.codec.mpeg4.level.1",
2620 FT_BOOLEAN, 8, NULL, 0x40,
2623 { &hf_btavdtp_mpeg4_level_2,
2624 { "MPEG Level 2", "btavdtp.codec.mpeg4.level.2",
2625 FT_BOOLEAN, 8, NULL, 0x20,
2628 { &hf_btavdtp_mpeg4_level_3,
2629 { "MPEG4 Level 3", "btavdtp.codec.mpeg4.level.3",
2630 FT_BOOLEAN, 8, NULL, 0x10,
2633 { &hf_btavdtp_mpeg4_level_rfa,
2634 { "MPEG4 Level RFA", "btavdtp.codec.mpeg4.level.rfa",
2635 FT_UINT8, BASE_HEX, NULL, 0x0F,
2638 { &hf_btavdtp_vendor_id,
2639 { "Vendor ID", "btavdtp.codec.vendor.vendor_id",
2640 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
2643 { &hf_btavdtp_vendor_specific_codec_id,
2644 { "Codec", "btavdtp.codec.vendor.codec_id",
2645 FT_UINT16, BASE_HEX, NULL, 0x00,
2648 { &hf_btavdtp_vendor_specific_value,
2649 { "Value", "btavdtp.codec.vendor.value",
2650 FT_NONE, BASE_NONE, NULL, 0x00,
2653 { &hf_btavdtp_vendor_specific_apt_codec_id,
2654 { "Codec", "btavdtp.codec.vendor.codec_id",
2655 FT_UINT16, BASE_HEX, VALS(vendor_apt_codec_vals), 0x00,
2658 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_16000,
2659 { "Sampling Frequency 16000 Hz", "btavdtp.codec.aptx.sampling_frequency.16000",
2660 FT_BOOLEAN, 8, NULL, 0x80,
2663 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_32000,
2664 { "Sampling Frequency 32000 Hz", "btavdtp.codec.aptx.sampling_frequency.32000",
2665 FT_BOOLEAN, 8, NULL, 0x40,
2668 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_44100,
2669 { "Sampling Frequency 44100 Hz", "btavdtp.codec.aptx.sampling_frequency.44100",
2670 FT_BOOLEAN, 8, NULL, 0x20,
2673 { &hf_btavdtp_vendor_specific_aptx_sampling_frequency_48000,
2674 { "Sampling Frequency 48000 Hz", "btavdtp.codec.aptx.sampling_frequency.48000",
2675 FT_BOOLEAN, 8, NULL, 0x10,
2678 { &hf_btavdtp_vendor_specific_aptx_channel_mode_mono,
2679 { "Channel Mode Mono", "btavdtp.codec.aptx.channel_mode.mono",
2680 FT_BOOLEAN, 8, NULL, 0x08,
2683 { &hf_btavdtp_vendor_specific_aptx_channel_mode_dual_channel,
2684 { "Channel Mode Dual Channel", "btavdtp.codec.aptx.channel_mode.dual_channel",
2685 FT_BOOLEAN, 8, NULL, 0x04,
2688 { &hf_btavdtp_vendor_specific_aptx_channel_mode_stereo,
2689 { "Channel Mode Stereo", "btavdtp.codec.aptx.channel_mode.stereo",
2690 FT_BOOLEAN, 8, NULL, 0x02,
2693 { &hf_btavdtp_vendor_specific_aptx_channel_mode_joint_stereo,
2694 { "Channel Mode Joint Stereo", "btavdtp.codec.aptx.channel_mode.joint_stereo",
2695 FT_BOOLEAN, 8, NULL, 0x01,
2698 { &hf_btavdtp_capabilities,
2699 { "Capabilities", "btavdtp.capabilities",
2700 FT_NONE, BASE_NONE, NULL, 0x0,
2703 { &hf_btavdtp_service,
2704 { "Service", "btavdtp.service",
2705 FT_NONE, BASE_NONE, NULL, 0x0,
2708 { &hf_btavdtp_service_multiplexing_entry,
2709 { "Entry", "btavdtp.service_multiplexing_entry",
2710 FT_NONE, BASE_NONE, NULL, 0x0,
2714 { "Data", "btavdtp.data",
2715 FT_NONE, BASE_NONE, NULL, 0x0,
2720 static gint *ett[] = {
2723 &ett_btavdtp_capabilities,
2724 &ett_btavdtp_service,
2727 proto_btavdtp = proto_register_protocol("Bluetooth AVDTP Protocol", "BT AVDTP", "btavdtp");
2728 btavdtp_handle = register_dissector("btavdtp", dissect_btavdtp, proto_btavdtp);
2730 proto_register_field_array(proto_btavdtp, hf, array_length(hf));
2731 proto_register_subtree_array(ett, array_length(ett));
2733 module = prefs_register_protocol(proto_btavdtp, NULL);
2734 prefs_register_static_text_preference(module, "avdtp.version",
2735 "Bluetooth Protocol AVDTP version: 1.3",
2736 "Version of protocol supported by this dissector.");
2738 channels = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2739 sep_list = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2740 sep_open = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2741 media_packet_times = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2742 #if RTP_PLAYER_WORKAROUND == TRUE
2743 file_scope_stream_number = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2748 proto_reg_handoff_btavdtp(void)
2750 dissector_add_string("bluetooth.uuid", "19", btavdtp_handle);
2752 dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_AVDTP, btavdtp_handle);
2754 dissector_add_for_decode_as("btl2cap.cid", btavdtp_handle);
2759 dissect_aptx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2761 proto_item *aptx_item;
2762 proto_tree *aptx_tree;
2764 bta2dp_codec_info_t *info;
2765 gdouble cumulative_frame_duration = 0;
2767 info = (bta2dp_codec_info_t *) data;
2769 col_set_str(pinfo->cinfo, COL_PROTOCOL, "APT-X");
2771 switch (pinfo->p2p_dir) {
2774 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
2778 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
2781 case P2P_DIR_UNKNOWN:
2782 col_clear(pinfo->cinfo, COL_INFO);
2786 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
2791 col_append_fstr(pinfo->cinfo, COL_INFO, "APT-X");
2793 aptx_item = proto_tree_add_item(tree, proto_aptx, tvb, 0, -1, ENC_NA);
2794 aptx_tree = proto_item_add_subtree(aptx_item, ett_aptx);
2796 proto_tree_add_item(aptx_tree, hf_aptx_data, tvb, 0, -1, ENC_NA);
2798 if (info && info->configuration && info->configuration_length >= 9) {
2799 gboolean fail = FALSE;
2800 gdouble expected_speed_data;
2801 gdouble frame_duration;
2802 gdouble frame_length = 2 * 2 * 4;
2803 gint number_of_channels;
2807 switch (info->configuration[8] >> 4) {
2825 return tvb_reported_length(tvb);
2827 switch (info->configuration[8] & 0x0F) {
2831 number_of_channels = 2;
2834 number_of_channels = 1;
2841 return tvb_reported_length(tvb);
2845 expected_speed_data = frequency * (sample_bits / 8.0) * number_of_channels;
2846 frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0);
2848 cumulative_frame_duration = (tvb_reported_length(tvb) / 4.0) * frame_duration;
2850 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_frame_duration, tvb, 0, 0, cumulative_frame_duration);
2851 proto_item_append_text(pitem, " ms");
2852 PROTO_ITEM_SET_GENERATED(pitem);
2854 if (info && info->previous_media_packet_info && info->current_media_packet_info) {
2857 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->abs_ts);
2858 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time, tvb, 0, 0, nstime_to_msec(&delta));
2859 proto_item_append_text(pitem, " ms");
2860 PROTO_ITEM_SET_GENERATED(pitem);
2862 pitem = proto_tree_add_double(aptx_tree, hf_aptx_avrcp_song_position, tvb, 0, 0, info->previous_media_packet_info->avrcp_song_position);
2863 proto_item_append_text(pitem, " ms");
2864 PROTO_ITEM_SET_GENERATED(pitem);
2866 nstime_delta(&delta, &pinfo->abs_ts, &info->previous_media_packet_info->first_abs_ts);
2867 pitem = proto_tree_add_double(aptx_tree, hf_aptx_delta_time_from_the_beginning, tvb, 0, 0, nstime_to_msec(&delta));
2868 proto_item_append_text(pitem, " ms");
2869 PROTO_ITEM_SET_GENERATED(pitem);
2871 if (!pinfo->fd->flags.visited)
2872 info->current_media_packet_info->cumulative_frame_duration += cumulative_frame_duration;
2874 pitem = proto_tree_add_double(aptx_tree, hf_aptx_cumulative_duration, tvb, 0, 0, info->previous_media_packet_info->cumulative_frame_duration);
2875 proto_item_append_text(pitem, " ms");
2876 PROTO_ITEM_SET_GENERATED(pitem);
2878 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));
2879 proto_item_append_text(pitem, " ms");
2880 PROTO_ITEM_SET_GENERATED(pitem);
2884 return tvb_reported_length(tvb);
2888 proto_register_aptx(void)
2890 static hf_register_info hf[] = {
2892 { "Data", "aptx.data",
2893 FT_BYTES, BASE_NONE, NULL, 0x00,
2896 { &hf_aptx_cumulative_frame_duration,
2897 { "Cumulative Frame Duration", "aptx.cumulative_frame_duration",
2898 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2901 { &hf_aptx_delta_time,
2902 { "Delta time", "aptx.delta_time",
2903 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2906 { &hf_aptx_avrcp_song_position,
2907 { "AVRCP Song Position", "aptx.avrcp_song_position",
2908 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2911 { &hf_aptx_delta_time_from_the_beginning,
2912 { "Delta time from the beginning", "aptx.delta_time_from_the_beginning",
2913 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2916 { &hf_aptx_cumulative_duration,
2917 { "Cumulative Music Duration", "aptx.cumulative_music_duration",
2918 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2922 { "Diff", "aptx.diff",
2923 FT_DOUBLE, BASE_NONE, NULL, 0x00,
2928 static gint *ett[] = {
2932 proto_aptx = proto_register_protocol("APT-X Codec", "APT-X", "aptx");
2933 proto_register_field_array(proto_aptx, hf, array_length(hf));
2934 proto_register_subtree_array(ett, array_length(ett));
2936 aptx_handle = register_dissector("aptx", dissect_aptx, proto_aptx);
2941 dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2944 proto_tree *bta2dp_tree;
2947 dissector_handle_t codec_dissector = NULL;
2948 bta2dp_codec_info_t bta2dp_codec_info;
2949 sep_data_t sep_data;
2950 gboolean no_avdtp_session;
2952 no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
2953 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
2955 sep_data.codec = CODEC_SBC;
2956 sep_data.content_protection_type = 0;
2957 sep_data.acp_seid = 0;
2958 sep_data.int_seid = 0;
2959 sep_data.previous_media_packet_info = NULL;
2960 sep_data.current_media_packet_info = NULL;
2961 sep_data.stream_start_in_frame = 0;
2962 sep_data.stream_end_in_frame = 0;
2963 sep_data.stream_number = 1;
2964 sep_data.vendor_id = 0;
2965 sep_data.vendor_codec = 0;
2966 sep_data.configuration_length = 0;
2967 sep_data.configuration = NULL;
2969 if (force_a2dp_scms_t || force_a2dp_codec != CODEC_DEFAULT) {
2970 if (force_a2dp_scms_t)
2971 sep_data.content_protection_type = 2;
2972 else if (data && !no_avdtp_session)
2973 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
2975 if (force_a2dp_codec != CODEC_DEFAULT)
2976 sep_data.codec = force_a2dp_codec;
2977 else if (data && !no_avdtp_session)
2978 sep_data.codec = ((sep_data_t *) data)->codec;
2980 if (data && !no_avdtp_session)
2981 sep_data = *((sep_data_t *) data);
2984 col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP");
2986 switch (pinfo->p2p_dir) {
2989 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
2993 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
2996 case P2P_DIR_UNKNOWN:
2997 col_clear(pinfo->cinfo, COL_INFO);
3001 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3006 ti = proto_tree_add_item(tree, proto_bta2dp, tvb, offset, -1, ENC_NA);
3007 col_append_fstr(pinfo->cinfo, COL_INFO, "Audio stream - %s",
3008 val_to_str_const(sep_data.codec, media_codec_audio_type_vals, "unknown codec"));
3010 bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp);
3012 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3013 PROTO_ITEM_SET_GENERATED(pitem);
3015 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_int_seid, tvb, 0, 0, sep_data.int_seid);
3016 PROTO_ITEM_SET_GENERATED(pitem);
3018 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, 0, 0, sep_data.codec);
3019 PROTO_ITEM_SET_GENERATED(pitem);
3021 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3022 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3023 PROTO_ITEM_SET_GENERATED(pitem);
3025 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3026 PROTO_ITEM_SET_GENERATED(pitem);
3028 if (sep_data.vendor_id == 0x004F && sep_data.vendor_codec == 0x0001)
3029 codec_dissector = aptx_handle;
3032 if (sep_data.content_protection_type > 0) {
3033 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3034 PROTO_ITEM_SET_GENERATED(pitem);
3037 if (sep_data.stream_start_in_frame > 0) {
3038 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3039 PROTO_ITEM_SET_GENERATED(pitem);
3042 if (sep_data.stream_end_in_frame > 0) {
3043 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3044 PROTO_ITEM_SET_GENERATED(pitem);
3047 pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_stream_number, tvb, 0, 0, sep_data.stream_number);
3048 PROTO_ITEM_SET_GENERATED(pitem);
3050 switch (sep_data.codec) {
3052 codec_dissector = sbc_handle;
3054 case CODEC_MPEG12_AUDIO:
3055 codec_dissector = mp2t_handle;
3057 case CODEC_MPEG24_AAC:
3058 codec_dissector = mpeg_audio_handle;
3061 codec_dissector = atrac_handle;
3064 codec_dissector = aptx_handle;
3068 bta2dp_codec_info.codec_dissector = codec_dissector;
3069 bta2dp_codec_info.configuration_length = sep_data.configuration_length;
3070 bta2dp_codec_info.configuration = sep_data.configuration;
3071 bta2dp_codec_info.content_protection_type = sep_data.content_protection_type;
3072 bta2dp_codec_info.previous_media_packet_info = sep_data.previous_media_packet_info;
3073 bta2dp_codec_info.current_media_packet_info = sep_data.current_media_packet_info;
3075 #if RTP_PLAYER_WORKAROUND == TRUE
3076 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3077 weak to recognize Bluetooth streams (key is: guint32 interface_id, guint32 adapter_id, guint32 chandle, guint32 cid, guint32 direction -> guint32 stream_number) */
3078 pinfo->srcport = sep_data.stream_number;
3079 pinfo->destport = sep_data.stream_number;
3082 if (bta2dp_codec_info.content_protection_type == 0 && codec_dissector == aptx_handle) {
3083 call_dissector_with_data(aptx_handle, tvb, pinfo, tree, &bta2dp_codec_info);
3085 bluetooth_add_address(pinfo, &pinfo->net_dst, sep_data.stream_number, "BT A2DP", pinfo->num, FALSE, &bta2dp_codec_info);
3086 call_dissector(rtp_handle, tvb, pinfo, tree);
3088 offset += tvb_reported_length_remaining(tvb, offset);
3094 proto_register_bta2dp(void)
3098 static hf_register_info hf[] = {
3099 { &hf_bta2dp_acp_seid,
3100 { "ACP SEID", "bta2dp.acp_seid",
3101 FT_UINT8, BASE_DEC, NULL, 0x00,
3104 { &hf_bta2dp_int_seid,
3105 { "INT SEID", "bta2dp.int_seid",
3106 FT_UINT8, BASE_DEC, NULL, 0x00,
3110 { "Codec", "bta2dp.codec",
3111 FT_UINT8, BASE_HEX, VALS(media_codec_audio_type_vals), 0x00,
3114 { &hf_bta2dp_vendor_id,
3115 { "Vendor ID", "bta2dp.codec.vendor.vendor_id",
3116 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3119 { &hf_bta2dp_vendor_codec_id,
3120 { "Vendor Codec", "bta2dp.codec.vendor.codec_id",
3121 FT_UINT16, BASE_HEX, NULL, 0x00,
3124 { &hf_bta2dp_content_protection,
3125 { "Content Protection", "bta2dp.content_protection",
3126 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3129 { &hf_bta2dp_stream_start_in_frame,
3130 { "Stream Start in Frame", "bta2dp.stream_start_in_frame",
3131 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3134 { &hf_bta2dp_stream_end_in_frame,
3135 { "Stream End in Frame", "bta2dp.stream_end_in_frame",
3136 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3139 { &hf_bta2dp_stream_number,
3140 { "Stream Number", "bta2dp.stream_number",
3141 FT_UINT32, BASE_DEC, NULL, 0x00,
3146 static gint *ett[] = {
3150 proto_bta2dp = proto_register_protocol("Bluetooth A2DP Profile", "BT A2DP", "bta2dp");
3151 proto_register_field_array(proto_bta2dp, hf, array_length(hf));
3152 proto_register_subtree_array(ett, array_length(ett));
3154 bta2dp_handle = register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp);
3156 module = prefs_register_protocol(proto_bta2dp, NULL);
3157 prefs_register_static_text_preference(module, "a2dp.version",
3158 "Bluetooth Profile A2DP version: 1.3",
3159 "Version of profile supported by this dissector.");
3161 prefs_register_bool_preference(module, "a2dp.content_protection.scms_t",
3162 "Force SCMS-T decoding",
3163 "Force decoding stream as A2DP with Content Protection SCMS-T ",
3164 &force_a2dp_scms_t);
3166 prefs_register_enum_preference(module, "a2dp.codec",
3168 "Force decoding stream as A2DP with specified codec",
3169 &force_a2dp_codec, pref_a2dp_codec, FALSE);
3173 proto_reg_handoff_bta2dp(void)
3175 sbc_handle = find_dissector_add_dependency("sbc", proto_bta2dp);
3176 mp2t_handle = find_dissector_add_dependency("mp2t", proto_bta2dp);
3177 mpeg_audio_handle = find_dissector_add_dependency("mpeg-audio", proto_bta2dp);
3178 /* TODO: ATRAC dissector does not exist yet */
3179 atrac_handle = find_dissector_add_dependency("atrac", proto_bta2dp);
3181 rtp_handle = find_dissector_add_dependency("rtp", proto_bta2dp);
3183 dissector_add_string("bluetooth.uuid", "110a", bta2dp_handle);
3184 dissector_add_string("bluetooth.uuid", "110b", bta2dp_handle);
3185 dissector_add_string("bluetooth.uuid", "110d", bta2dp_handle);
3187 dissector_add_for_decode_as("btl2cap.cid", bta2dp_handle);
3191 dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3194 proto_tree *btvdp_tree;
3197 dissector_handle_t codec_dissector = NULL;
3198 btvdp_codec_info_t btvdp_codec_info;
3199 sep_data_t sep_data;
3200 gboolean no_avdtp_session;
3202 no_avdtp_session = (proto_btavdtp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
3203 wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
3205 sep_data.codec = CODEC_H263_BASELINE;
3206 sep_data.content_protection_type = 0;
3207 sep_data.acp_seid = 0;
3208 sep_data.int_seid = 0;
3209 sep_data.previous_media_packet_info = NULL;
3210 sep_data.current_media_packet_info = NULL;
3211 sep_data.stream_start_in_frame = 0;
3212 sep_data.stream_end_in_frame = 0;
3213 sep_data.stream_number = 1;
3214 sep_data.vendor_id = 0;
3215 sep_data.vendor_codec = 0;
3216 sep_data.configuration_length = 0;
3217 sep_data.configuration = NULL;
3219 if (force_vdp_scms_t || force_vdp_codec) {
3220 if (force_vdp_scms_t)
3221 sep_data.content_protection_type = 2;
3222 else if (data && !no_avdtp_session)
3223 sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
3225 if (force_vdp_codec)
3226 sep_data.codec = force_vdp_codec;
3227 else if (data && !no_avdtp_session)
3228 sep_data.codec = ((sep_data_t *) data)->codec;
3230 if (data && !no_avdtp_session)
3231 sep_data = *((sep_data_t *) data);
3234 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP");
3236 switch (pinfo->p2p_dir) {
3239 col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
3243 col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
3246 case P2P_DIR_UNKNOWN:
3247 col_clear(pinfo->cinfo, COL_INFO);
3251 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
3256 ti = proto_tree_add_item(tree, proto_btvdp, tvb, offset, -1, ENC_NA);
3257 col_append_fstr(pinfo->cinfo, COL_INFO, "Video stream - %s",
3258 val_to_str_const(sep_data.codec, media_codec_video_type_vals, "unknown codec"));
3260 btvdp_tree = proto_item_add_subtree(ti, ett_btvdp);
3262 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_acp_seid, tvb, 0, 0, sep_data.acp_seid);
3263 PROTO_ITEM_SET_GENERATED(pitem);
3265 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_int_seid, tvb, 0, 0, sep_data.int_seid);
3266 PROTO_ITEM_SET_GENERATED(pitem);
3268 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, 0, 0, sep_data.codec);
3269 PROTO_ITEM_SET_GENERATED(pitem);
3271 if (sep_data.codec == 0xFF) { /* Vendor Specific Codec */
3272 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_id, tvb, 0, 0, sep_data.vendor_id);
3273 PROTO_ITEM_SET_GENERATED(pitem);
3275 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_vendor_codec_id, tvb, 0, 0, sep_data.vendor_codec);
3276 PROTO_ITEM_SET_GENERATED(pitem);
3279 if (sep_data.content_protection_type > 0) {
3280 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_content_protection, tvb, 0, 0, sep_data.content_protection_type);
3281 PROTO_ITEM_SET_GENERATED(pitem);
3284 if (sep_data.stream_start_in_frame > 0) {
3285 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_start_in_frame, tvb, 0, 0, sep_data.stream_start_in_frame);
3286 PROTO_ITEM_SET_GENERATED(pitem);
3289 if (sep_data.stream_end_in_frame > 0) {
3290 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_end_in_frame, tvb, 0, 0, sep_data.stream_end_in_frame);
3291 PROTO_ITEM_SET_GENERATED(pitem);
3294 pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_stream_number, tvb, 0, 0, sep_data.stream_number);
3295 PROTO_ITEM_SET_GENERATED(pitem);
3297 switch (sep_data.codec) {
3298 case CODEC_H263_BASELINE:
3299 case CODEC_H263_PROFILE_3:
3300 case CODEC_H263_PROFILE_8:
3301 codec_dissector = h263_handle;
3303 case CODEC_MPEG4_VSP:
3304 codec_dissector = mp4v_es_handle;
3308 btvdp_codec_info.codec_dissector = codec_dissector;
3309 btvdp_codec_info.content_protection_type = sep_data.content_protection_type;
3311 #if RTP_PLAYER_WORKAROUND == TRUE
3312 /* XXX: Workaround to get multiple RTP streams, because conversations are too
3313 weak to recognize Bluetooth streams (key is: guint32 interface_id, guint32 adapter_id, guint32 chandle, guint32 cid, guint32 direction -> guint32 stream_number) */
3314 pinfo->srcport = sep_data.stream_number;
3315 pinfo->destport = sep_data.stream_number;
3318 bluetooth_add_address(pinfo, &pinfo->net_dst, 0, "BT VDP", pinfo->num, TRUE, &btvdp_codec_info);
3319 call_dissector(rtp_handle, tvb, pinfo, tree);
3320 offset += tvb_reported_length_remaining(tvb, offset);
3326 proto_register_btvdp(void)
3329 expert_module_t* expert_btavdtp;
3331 static hf_register_info hf[] = {
3332 { &hf_btvdp_acp_seid,
3333 { "ACP SEID", "btvdp.acp_seid",
3334 FT_UINT8, BASE_DEC, NULL, 0x00,
3337 { &hf_btvdp_int_seid,
3338 { "INT SEID", "btvdp.int_seid",
3339 FT_UINT8, BASE_DEC, NULL, 0x00,
3343 { "Codec", "btvdp.codec",
3344 FT_UINT8, BASE_HEX, VALS(media_codec_video_type_vals), 0x00,
3347 { &hf_btvdp_vendor_id,
3348 { "Vendor ID", "btvdp.codec.vendor.vendor_id",
3349 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &bluetooth_company_id_vals_ext, 0x00,
3352 { &hf_btvdp_vendor_codec_id,
3353 { "Vendor Codec", "btvdp.codec.vendor.codec_id",
3354 FT_UINT16, BASE_HEX, NULL, 0x00,
3357 { &hf_btvdp_content_protection,
3358 { "Content Protection", "btvdp.content_protection",
3359 FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
3362 { &hf_btvdp_stream_start_in_frame,
3363 { "Stream Start in Frame", "btvdp.stream_start_in_frame",
3364 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3367 { &hf_btvdp_stream_end_in_frame,
3368 { "Stream End in Frame", "btvdp.stream_end_in_frame",
3369 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3372 { &hf_btvdp_stream_number,
3373 { "Stream Number", "btvdp.stream_number",
3374 FT_UINT32, BASE_DEC, NULL, 0x00,
3379 static gint *ett[] = {
3383 static ei_register_info ei[] = {
3384 { &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 }},
3385 { &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 }},
3386 { &ei_btavdtp_unexpected_losc_data, { "btavdtp.unexpected_losc_data", PI_PROTOCOL, PI_WARN, "Unexpected losc data", EXPFILL }},
3389 proto_btvdp = proto_register_protocol("Bluetooth VDP Profile", "BT VDP", "btvdp");
3390 btvdp_handle = register_dissector("btvdp", dissect_btvdp, proto_btvdp);
3391 proto_register_field_array(proto_btvdp, hf, array_length(hf));
3392 proto_register_subtree_array(ett, array_length(ett));
3393 expert_btavdtp = expert_register_protocol(proto_btvdp);
3394 expert_register_field_array(expert_btavdtp, ei, array_length(ei));
3396 module = prefs_register_protocol(proto_btvdp, NULL);
3397 prefs_register_static_text_preference(module, "vdp.version",
3398 "Bluetooth Profile VDP version: 1.1",
3399 "Version of profile supported by this dissector.");
3401 prefs_register_bool_preference(module, "vdp.content_protection.scms_t",
3402 "Force SCMS-T decoding",
3403 "Force decoding stream as VDP with Content Protection SCMS-T ",
3406 prefs_register_enum_preference(module, "vdp.codec",
3408 "Force decoding stream as VDP with specified codec",
3409 &force_vdp_codec, pref_vdp_codec, FALSE);
3413 proto_reg_handoff_btvdp(void)
3415 h263_handle = find_dissector_add_dependency("h263", proto_btvdp);
3416 mp4v_es_handle = find_dissector_add_dependency("mp4v-es", proto_btvdp);
3418 rtp_handle = find_dissector_add_dependency("rtp", proto_btvdp);
3420 dissector_add_string("bluetooth.uuid", "1303", btvdp_handle);
3421 dissector_add_string("bluetooth.uuid", "1304", btvdp_handle);
3422 dissector_add_string("bluetooth.uuid", "1305", btvdp_handle);
3424 dissector_add_for_decode_as("btl2cap.cid", btvdp_handle);
3430 dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3432 proto_item *main_item;
3433 proto_tree *main_tree;
3436 main_item = proto_tree_add_item(tree, proto_bta2dp_cph_scms_t, tvb, offset, 1, ENC_NA);
3437 main_tree = proto_item_add_subtree(main_item, ett_bta2dp_cph_scms_t);
3439 proto_tree_add_item(main_tree, hf_bta2dp_reserved , tvb, offset, 1, ENC_NA);
3440 proto_tree_add_item(main_tree, hf_bta2dp_cp_bit, tvb, offset, 1, ENC_NA);
3441 proto_tree_add_item(main_tree, hf_bta2dp_l_bit , tvb, offset, 1, ENC_NA);
3448 proto_register_bta2dp_content_protection_header_scms_t(void)
3450 static hf_register_info hf[] = {
3452 { "L-bit", "bta2dp.content_protection_header.scms_t.l_bit",
3453 FT_BOOLEAN, 8, NULL, 0x01,
3456 { &hf_bta2dp_cp_bit,
3457 { "Cp-bit", "bta2dp.content_protection_header.scms_t.cp_bit",
3458 FT_BOOLEAN, 8, NULL, 0x02,
3461 { &hf_bta2dp_reserved,
3462 { "Reserved", "bta2dp.content_protection_header.scms_t.reserved",
3463 FT_BOOLEAN, 8, NULL, 0xFC,
3468 static gint *ett[] = {
3469 &ett_bta2dp_cph_scms_t
3472 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");
3473 proto_register_field_array(proto_bta2dp_cph_scms_t, hf, array_length(hf));
3474 proto_register_subtree_array(ett, array_length(ett));
3476 register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t);
3480 dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3482 proto_item *main_item;
3483 proto_tree *main_tree;
3486 main_item = proto_tree_add_item(tree, proto_btvdp_cph_scms_t, tvb, offset, 1, ENC_NA);
3487 main_tree = proto_item_add_subtree(main_item, ett_btvdp_cph_scms_t);
3489 proto_tree_add_item(main_tree, hf_btvdp_reserved , tvb, offset, 1, ENC_NA);
3490 proto_tree_add_item(main_tree, hf_btvdp_cp_bit, tvb, offset, 1, ENC_NA);
3491 proto_tree_add_item(main_tree, hf_btvdp_l_bit , tvb, offset, 1, ENC_NA);
3498 proto_register_btvdp_content_protection_header_scms_t(void)
3500 static hf_register_info hf[] = {
3502 { "L-bit", "btvdp.content_protection_header.scms_t.l_bit",
3503 FT_BOOLEAN, 8, NULL, 0x01,
3507 { "Cp-bit", "btvdp.content_protection_header.scms_t.cp_bit",
3508 FT_BOOLEAN, 8, NULL, 0x02,
3511 { &hf_btvdp_reserved,
3512 { "Reserved", "btvdp.content_protection_header.scms_t.reserved",
3513 FT_BOOLEAN, 8, NULL, 0xFC,
3518 static gint *ett[] = {
3519 &ett_btvdp_cph_scms_t
3522 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");
3523 proto_register_field_array(proto_btvdp_cph_scms_t, hf, array_length(hf));
3524 proto_register_subtree_array(ett, array_length(ett));
3526 register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t);
3530 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3535 * indent-tabs-mode: nil
3538 * vi: set shiftwidth=4 tabstop=8 expandtab:
3539 * :indentSize=4:tabSize=8:noTabs=true: