2 * Routines for Bluetooth AVRCP dissection
4 * Copyright 2012, Michal Labedzki for Tieto Corporation
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
19 #include <epan/iana_charsets.h>
20 #include "packet-btl2cap.h"
21 #include "packet-btsdp.h"
22 #include "packet-btavctp.h"
23 #include "packet-btavrcp.h"
25 static int proto_btavrcp
;
27 static int hf_btavrcp_rfa
;
28 static int hf_btavrcp_ctype
;
29 static int hf_btavrcp_subunit_type
;
30 static int hf_btavrcp_subunit_id
;
31 static int hf_btavrcp_opcode
;
32 static int hf_btavrcp_company_id
;
33 static int hf_btavrcp_length
;
34 static int hf_btavrcp_pdu_id
;
35 static int hf_btavrcp_bt_pdu_id
;
36 static int hf_btavrcp_bt_continuing_pdu_id
;
37 static int hf_btavrcp_browsing_pdu_id
;
38 static int hf_btavrcp_reserved
;
39 static int hf_btavrcp_packet_type
;
40 static int hf_btavrcp_passthrough_state
;
41 static int hf_btavrcp_passthrough_operation
;
42 static int hf_btavrcp_passthrough_data_length
;
43 static int hf_btavrcp_passthrough_company_id
;
44 static int hf_btavrcp_passthrough_vendor_unique_id
;
45 static int hf_btavrcp_unit_unknown
;
46 static int hf_btavrcp_unit_type
;
47 static int hf_btavrcp_unit_id
;
48 static int hf_btavrcp_subunit_page
;
49 static int hf_btavrcp_subunit_extension_code
;
50 static int hf_btavrcp_item
;
51 static int hf_btavrcp_folder
;
52 static int hf_btavrcp_player_id
;
53 static int hf_btavrcp_status
;
54 static int hf_btavrcp_uid_counter
;
55 static int hf_btavrcp_number_of_items
;
56 static int hf_btavrcp_number_of_items16
;
57 static int hf_btavrcp_character_set
;
58 static int hf_btavrcp_folder_depth
;
59 static int hf_btavrcp_folder_name_length
;
60 static int hf_btavrcp_folder_name
;
61 static int hf_btavrcp_search
;
62 static int hf_btavrcp_search_length
;
63 static int hf_btavrcp_number_of_attributes
;
64 static int hf_btavrcp_uid
;
65 static int hf_btavrcp_scope
;
66 static int hf_btavrcp_start_item
;
67 static int hf_btavrcp_end_item
;
68 static int hf_btavrcp_direction
;
69 static int hf_btavrcp_identifier
;
70 static int hf_btavrcp_song_length
;
71 static int hf_btavrcp_song_position
;
72 static int hf_btavrcp_play_status
;
73 static int hf_btavrcp_notification_interval
;
74 static int hf_btavrcp_event_id
;
75 static int hf_btavrcp_battery_status
;
76 static int hf_btavrcp_number_of_character_set
;
77 static int hf_btavrcp_absolute_volume_rfa
;
78 static int hf_btavrcp_absolute_volume
;
79 static int hf_btavrcp_capability
;
80 static int hf_btavrcp_capability_count
;
81 static int hf_btavrcp_item_type
;
82 static int hf_btavrcp_item_length
;
83 static int hf_btavrcp_system_status
;
84 static int hf_btavrcp_number_of_settings
;
85 static int hf_btavrcp_settings_attribute
;
86 static int hf_btavrcp_settings_value
;
87 static int hf_btavrcp_displayable_name
;
88 static int hf_btavrcp_displayable_name_length
;
89 static int hf_btavrcp_media_type
;
90 static int hf_btavrcp_folder_type
;
91 static int hf_btavrcp_folder_playable
;
92 static int hf_btavrcp_major_player_type
;
93 static int hf_btavrcp_player_subtype
;
94 static int hf_btavrcp_player_item
;
95 static int hf_btavrcp_attribute
;
96 static int hf_btavrcp_attribute_count
;
97 static int hf_btavrcp_attribute_value
;
98 static int hf_btavrcp_attribute_value_length
;
99 static int hf_btavrcp_attribute_item
;
100 static int hf_btavrcp_attribute_list
;
101 static int hf_btavrcp_attribute_entries
;
102 static int hf_btavrcp_attribute_name_length
;
103 static int hf_btavrcp_attribute_name
;
104 static int hf_btavrcp_setting_value_length
;
105 static int hf_btavrcp_setting_value
;
106 static int hf_btavrcp_features
;
107 static int hf_btavrcp_not_used_features
;
108 static int hf_btavrcp_feature_reserved_0
;
109 static int hf_btavrcp_feature_reserved_1
;
110 static int hf_btavrcp_feature_reserved_2
;
111 static int hf_btavrcp_feature_reserved_3
;
112 static int hf_btavrcp_feature_reserved_4
;
113 static int hf_btavrcp_feature_reserved_5
;
114 static int hf_btavrcp_feature_reserved_6
;
115 static int hf_btavrcp_feature_reserved_7
;
116 static int hf_btavrcp_feature_passthrough_select
;
117 static int hf_btavrcp_feature_passthrough_up
;
118 static int hf_btavrcp_feature_passthrough_down
;
119 static int hf_btavrcp_feature_passthrough_left
;
120 static int hf_btavrcp_feature_passthrough_right
;
121 static int hf_btavrcp_feature_passthrough_right_up
;
122 static int hf_btavrcp_feature_passthrough_right_down
;
123 static int hf_btavrcp_feature_passthrough_left_up
;
124 static int hf_btavrcp_feature_passthrough_left_down
;
125 static int hf_btavrcp_feature_passthrough_root_menu
;
126 static int hf_btavrcp_feature_passthrough_setup_menu
;
127 static int hf_btavrcp_feature_passthrough_contents_menu
;
128 static int hf_btavrcp_feature_passthrough_favorite_menu
;
129 static int hf_btavrcp_feature_passthrough_exit
;
130 static int hf_btavrcp_feature_passthrough_0
;
131 static int hf_btavrcp_feature_passthrough_1
;
132 static int hf_btavrcp_feature_passthrough_2
;
133 static int hf_btavrcp_feature_passthrough_3
;
134 static int hf_btavrcp_feature_passthrough_4
;
135 static int hf_btavrcp_feature_passthrough_5
;
136 static int hf_btavrcp_feature_passthrough_6
;
137 static int hf_btavrcp_feature_passthrough_7
;
138 static int hf_btavrcp_feature_passthrough_8
;
139 static int hf_btavrcp_feature_passthrough_9
;
140 static int hf_btavrcp_feature_passthrough_dot
;
141 static int hf_btavrcp_feature_passthrough_enter
;
142 static int hf_btavrcp_feature_passthrough_clear
;
143 static int hf_btavrcp_feature_passthrough_channel_up
;
144 static int hf_btavrcp_feature_passthrough_channel_down
;
145 static int hf_btavrcp_feature_passthrough_previous_channel
;
146 static int hf_btavrcp_feature_passthrough_sound_select
;
147 static int hf_btavrcp_feature_passthrough_input_select
;
148 static int hf_btavrcp_feature_passthrough_display_information
;
149 static int hf_btavrcp_feature_passthrough_help
;
150 static int hf_btavrcp_feature_passthrough_page_up
;
151 static int hf_btavrcp_feature_passthrough_page_down
;
152 static int hf_btavrcp_feature_passthrough_power
;
153 static int hf_btavrcp_feature_passthrough_volume_up
;
154 static int hf_btavrcp_feature_passthrough_volume_down
;
155 static int hf_btavrcp_feature_passthrough_mute
;
156 static int hf_btavrcp_feature_passthrough_play
;
157 static int hf_btavrcp_feature_passthrough_stop
;
158 static int hf_btavrcp_feature_passthrough_pause
;
159 static int hf_btavrcp_feature_passthrough_record
;
160 static int hf_btavrcp_feature_passthrough_rewind
;
161 static int hf_btavrcp_feature_passthrough_fast_forward
;
162 static int hf_btavrcp_feature_passthrough_eject
;
163 static int hf_btavrcp_feature_passthrough_forward
;
164 static int hf_btavrcp_feature_passthrough_backward
;
165 static int hf_btavrcp_feature_passthrough_angle
;
166 static int hf_btavrcp_feature_passthrough_subpicture
;
167 static int hf_btavrcp_feature_passthrough_f1
;
168 static int hf_btavrcp_feature_passthrough_f2
;
169 static int hf_btavrcp_feature_passthrough_f3
;
170 static int hf_btavrcp_feature_passthrough_f4
;
171 static int hf_btavrcp_feature_passthrough_f5
;
172 static int hf_btavrcp_feature_vendor_unique
;
173 static int hf_btavrcp_feature_basic_group_navigation
;
174 static int hf_btavrcp_feature_advanced_control_player
;
175 static int hf_btavrcp_feature_browsing
;
176 static int hf_btavrcp_feature_searching
;
177 static int hf_btavrcp_feature_addtonowplayer
;
178 static int hf_btavrcp_feature_uid_unique
;
179 static int hf_btavrcp_feature_only_browsable_when_addressed
;
180 static int hf_btavrcp_feature_only_searchable_when_addressed
;
181 static int hf_btavrcp_feature_nowplaying
;
182 static int hf_btavrcp_feature_uid_persistency
;
183 static int hf_btavrcp_feature_number_of_items
;
184 static int hf_btavrcp_feature_cover_art
;
185 static int hf_btavrcp_reassembled
;
186 static int hf_btavrcp_current_path
;
187 static int hf_btavrcp_response_time
;
188 static int hf_btavrcp_command_in_frame
;
189 static int hf_btavrcp_response_in_frame
;
190 static int hf_btavrcp_data
;
192 static int ett_btavrcp
;
193 static int ett_btavrcp_attribute_list
;
194 static int ett_btavrcp_attribute_entry
;
195 static int ett_btavrcp_attribute_entries
;
196 static int ett_btavrcp_element
;
197 static int ett_btavrcp_folder
;
198 static int ett_btavrcp_player
;
199 static int ett_btavrcp_features
;
200 static int ett_btavrcp_features_not_used
;
201 static int ett_btavrcp_path
;
203 static expert_field ei_btavrcp_no_response
;
204 static expert_field ei_btavrcp_item_length_bad
;
205 static expert_field ei_btavrcp_unexpected_data
;
207 static dissector_handle_t btavrcp_handle
;
209 #define OPCODE_VENDOR_DEPENDENT 0x00
210 #define OPCODE_UNIT 0x30
211 #define OPCODE_SUBUNIT 0x31
212 #define OPCODE_PASSTHROUGH 0x7C
214 #define ITEM_MEDIAPLAYER 0x01
215 #define ITEM_FOLDER 0x02
216 #define ITEM_MEDIA_ELEMENT 0x03
218 #define PACKET_TYPE_SINGLE 0x00
219 #define PACKET_TYPE_START 0x01
220 #define PACKET_TYPE_CONTINUE 0x02
221 #define PACKET_TYPE_END 0x03
223 #define EVENT_PLAYBACK_STATUS_CHANGED 0x01
224 #define EVENT_TRACK_CHANGED 0x02
225 #define EVENT_TRACK_REACHED_END 0x03
226 #define EVENT_TRACK_REACHED_START 0x04
227 #define EVENT_PLAYBACK_POSITION_CHANGED 0x05
228 #define EVENT_BATTERY_STATUS_CHANGED 0x06
229 #define EVENT_SYSTEM_STATUS_CHANGED 0x07
230 #define EVENT_PLAYER_APPLICATION_SETTING_CHANGED 0x08
231 #define EVENT_NOWPLAYING_CONTENT_CHANGED 0x09
232 #define EVENT_AVAILABLE_PLAYERS_CHANGED 0x0A
233 #define EVENT_ADDRESSEDPLAYER_CHANGED 0x0B
234 #define EVENT_UIDS_CHANGED 0x0C
235 #define EVENT_VOLUME_CHANGED 0x0D
237 #define PDU_GET_CAPABILITIES 0x10
238 #define PDU_LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES 0x11
239 #define PDU_LIST_PLAYER_APPLICATION_SETTING_VALUE 0x12
240 #define PDU_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE 0x13
241 #define PDU_SET_PLAYER_APPLICATION_SETTING_VALUE 0x14
242 #define PDU_GET_PLAYER_APPLICATION_SETTING_ATTRIBUTE_TEXT 0x15
243 #define PDU_GET_PLAYER_APPLICATION_SETTING_VALUE_TEXT 0x16
244 #define PDU_INFORM_DISPLAYABLE_CHARACTER_SET 0x17
245 #define PDU_INFORM_BATTERY_STATUS_OF_CT 0x18
246 #define PDU_GET_ELEMENT_ATTRIBUTES 0x20
247 #define PDU_GET_PLAY_STATUS 0x30
248 #define PDU_REGISTER_NOTIFICATION 0x31
249 #define PDU_REQUEST_CONTINUING_RESPONSE 0x40
250 #define PDU_ABORT_CONTINUING_RESPONSE 0x41
251 #define PDU_SET_ABSOLUTE_VOLUME 0x50
252 #define PDU_SET_ADDRESSED_PLAYER 0x60
253 #define PDU_SET_BROWSED_PLAYER 0x70
254 #define PDU_GET_FOLDER_ITEMS 0x71
255 #define PDU_CHANGE_PATH 0x72
256 #define PDU_GET_ITEM_ATTRIBUTES 0x73
257 #define PDU_PLAY_ITEM 0x74
258 #define PDU_SEARCH 0x80
259 #define PDU_ADD_TO_NOW_PLAYING 0x90
260 #define PDU_GENERAL_REJECT 0xA0
262 #define STATUS_OK 0x04
264 static wmem_tree_t
*reassembling
;
265 static wmem_tree_t
*timing
;
266 wmem_tree_t
*btavrcp_song_positions
= NULL
;
268 typedef struct _avrcp_proto_data_t
{
269 uint32_t interface_id
;
273 } avrcp_proto_data_t
;
275 typedef struct _fragment
{
276 unsigned start_frame_number
;
277 unsigned end_frame_number
;
278 uint32_t interface_id
;
285 wmem_tree_t
*fragments
;
288 typedef struct _data_fragment_t
{
293 typedef struct _timing_info
{
294 unsigned command_frame_number
;
295 nstime_t command_timestamp
;
296 unsigned response_frame_number
;
297 nstime_t response_timestamp
;
298 unsigned max_response_time
;
300 uint32_t interface_id
;
309 static const value_string packet_type_vals
[] = {
310 { PACKET_TYPE_SINGLE
, "Single" },
311 { PACKET_TYPE_START
, "Start" },
312 { PACKET_TYPE_CONTINUE
, "Continue" },
313 { PACKET_TYPE_END
, "End" },
317 static const value_string ctype_vals
[] = {
320 { 0x02, "Specific Inquiry" },
322 { 0x04, "General Inquiry" },
323 { 0x05, "reserved" },
324 { 0x06, "reserved" },
325 { 0x07, "reserved" },
326 { 0x08, "Not Implemented" },
327 { 0x09, "Accepted" },
328 { 0x0A, "Rejected" },
329 { 0x0B, "In Transition" },
332 { 0x0E, "reserved" },
337 static const value_string opcode_vals
[] = {
338 { OPCODE_VENDOR_DEPENDENT
, "Vendor dependent" },
339 { OPCODE_UNIT
, "Unit Info" },
340 { OPCODE_SUBUNIT
, "Subunit Info" },
341 { OPCODE_PASSTHROUGH
, "Pass Through" },
345 static const value_string subunit_type_vals
[] = {
350 { 0x04, "Tape Recorder/Player" },
355 { 0x08, "reserved" },
358 { 0x0A, "Bulletin Board" },
359 { 0x0B, "Camera Storage" },
361 { 0x1C, "Vendor Unique" },
362 { 0x1D, "All subunit types" },
363 { 0x1E, "Subunit_type extended to next byte" },
368 static const value_string passthrough_state_vals
[] = {
370 { 0x01, "Released" },
374 static const value_string passthrough_operation_vals
[] = {
375 { 0x41, "VOLUME UP" },
376 { 0x42, "VOLUME DOWN" },
383 { 0x49, "FAST FORWARD" },
386 { 0x4C, "BACKWARD" },
390 static const value_string pdu_id_vals
[] = {
391 { PDU_GET_CAPABILITIES
, "GetCapabilities" },
392 { PDU_LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES
, "ListPlayerApplicationSettingAttributes" },
393 { PDU_LIST_PLAYER_APPLICATION_SETTING_VALUE
, "ListPlayerApplicationSettingValue" },
394 { PDU_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE
, "GetCurrentPlayerApplicationSettingValue" },
395 { PDU_SET_PLAYER_APPLICATION_SETTING_VALUE
, "SetPlayerApplicationSettingValue" },
396 { PDU_GET_PLAYER_APPLICATION_SETTING_ATTRIBUTE_TEXT
, "GetPlayerApplicationSettingAttributeText" },
397 { PDU_GET_PLAYER_APPLICATION_SETTING_VALUE_TEXT
, "GetPlayerApplicationSettingValueText" },
398 { PDU_INFORM_DISPLAYABLE_CHARACTER_SET
, "InformDisplayableCharacterSet" },
399 { PDU_INFORM_BATTERY_STATUS_OF_CT
, "InformBatteryStatusOfCT" },
400 { PDU_GET_ELEMENT_ATTRIBUTES
, "GetElementAttributes" },
401 { PDU_GET_PLAY_STATUS
, "GetPlayStatus" },
402 { PDU_REGISTER_NOTIFICATION
, "RegisterNotification" },
403 { PDU_REQUEST_CONTINUING_RESPONSE
, "RequestContinuingResponse" },
404 { PDU_ABORT_CONTINUING_RESPONSE
, "AbortContinuingResponse" },
405 { PDU_SET_ABSOLUTE_VOLUME
, "SetAbsoluteVolume" },
406 { PDU_SET_ADDRESSED_PLAYER
, "SetAddressedPlayer" },
407 { PDU_PLAY_ITEM
, "PlayItem" },
408 { PDU_ADD_TO_NOW_PLAYING
, "AddToNowPlaying" },
412 static const value_string browsing_pdu_id_vals
[] = {
413 { PDU_SET_BROWSED_PLAYER
, "SetBrowsedPlayer" },
414 { PDU_GET_FOLDER_ITEMS
, "GetFolderItems" },
415 { PDU_CHANGE_PATH
, "ChangePath" },
416 { PDU_GET_ITEM_ATTRIBUTES
, "GetItemAttributes" },
417 { PDU_SEARCH
, "Search" },
418 { PDU_GENERAL_REJECT
, "GeneralReject" },
422 static const value_string status_vals
[] = {
423 { 0x00, "Invalid Command" },
424 { 0x01, "Invalid Parameter" },
425 { 0x02, "Parameter Not Found" },
426 { 0x03, "Internal Error" },
428 { 0x05, "UID Changed" },
429 { 0x06, "Reserved" },
430 { 0x07, "Invalid Direction" },
431 { 0x08, "Not a Directory" },
432 { 0x09, "Does Not Exist" },
433 { 0x0A, "Invalid Scope" },
434 { 0x0B, "Range Out of Bounds" },
435 { 0x0C, "UID is a Directory" },
436 { 0x0D, "Media In Use" },
437 { 0x0E, "Now Player List Full" },
438 { 0x0F, "Search Not Supported" },
439 { 0x10, "Search in Progress" },
440 { 0x11, "Invalid Player Id" },
441 { 0x12, "Player Not Browsable" },
442 { 0x13, "Player Not Addressed" },
443 { 0x14, "No Valid Search Results" },
444 { 0x15, "No Available Players" },
445 { 0x16, "Addressed Player Changed" },
449 static const value_string vendor_unique_id_vals
[] = {
450 { 0x0000, "Next Group" },
451 { 0x0001, "Previous Group" },
455 static const value_string direction_vals
[] = {
456 { 0x00, "Folder Up" },
457 { 0x01, "Folder Down" },
461 static const value_string attribute_count_vals
[] = {
462 { 0x00, "All attributes are requested" },
463 { 0xFF, "No attributes are requested" },
467 static const value_string scope_vals
[] = {
468 { 0x00, "MediaPlayerList" },
471 { 0x03, "NowPlaying" },
475 static const value_string attribute_id_vals
[] = {
480 { 0x04, "Media Number" },
481 { 0x05, "Total Number of Media" },
483 { 0x07, "Playing Time" },
487 static const value_string settings_vals
[] = {
489 { 0x01, "Equalizer" },
490 { 0x02, "Repeat mode" },
496 static const value_string notification_vals
[] = {
497 { EVENT_PLAYBACK_STATUS_CHANGED
, "PlaybackStatusChanged" },
498 { EVENT_TRACK_CHANGED
, "TrackChanged" },
499 { EVENT_TRACK_REACHED_END
, "TrackReachedEnd" },
500 { EVENT_TRACK_REACHED_START
, "TrackReachedStart" },
501 { EVENT_PLAYBACK_POSITION_CHANGED
, "PlaybackPositionChanged" },
502 { EVENT_BATTERY_STATUS_CHANGED
, "BatteryStatusChanged" },
503 { EVENT_SYSTEM_STATUS_CHANGED
, "SystemStatusChanged" },
504 { EVENT_PLAYER_APPLICATION_SETTING_CHANGED
, "PlayerApplicationSettingChanged" },
505 { EVENT_NOWPLAYING_CONTENT_CHANGED
, "NowPlayingContentChanged" },
506 { EVENT_AVAILABLE_PLAYERS_CHANGED
, "AvailablePlayersChanged" },
507 { EVENT_ADDRESSEDPLAYER_CHANGED
, "AddressedPlayerChanged" },
508 { EVENT_UIDS_CHANGED
, "UIDsChanged" },
509 { EVENT_VOLUME_CHANGED
, "VolumeChanged" },
513 static const value_string play_status_vals
[] = {
517 { 0x03, "Forward Seek" },
518 { 0x04, "Reverse Seek" },
523 static const value_string battery_status_vals
[] = {
526 { 0x02, "Critical" },
527 { 0x03, "External" },
528 { 0x04, "Full Charge" },
532 static const value_string capability_vals
[] = {
533 { 0x02, "Company ID" },
534 { 0x03, "Events Supported" },
538 static const value_string item_type_vals
[] = {
539 { 0x01, "Media Player Item" },
540 { 0x02, "Folder Item" },
541 { 0x03, "Media Element Item" },
545 static const value_string system_status_vals
[] = {
546 { 0x00, "Power On" },
547 { 0x01, "Power Off" },
548 { 0x02, "Unplugged" },
552 static const value_string media_type_vals
[] = {
558 static const value_string folder_type_vals
[] = {
564 { 0x05, "Playlists" },
569 static const value_string folder_playable_vals
[] = {
570 { 0x00, "Not Playable" },
571 { 0x01, "Playable" },
575 static const value_string major_player_type_vals
[] = {
578 { 0x04, "Broadcasting Audio" },
579 { 0x08, "Broadcasting Video" },
583 static const value_string player_subtype_vals
[] = {
584 { 0x01, "Audio Book" },
589 static const value_string unique_all_supported_attributes
[] = {
590 { 0x00, "All Supported Attributes" },
594 void proto_register_btavrcp(void);
595 void proto_reg_handoff_btavrcp(void);
598 dissect_attribute_id_list(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
,
601 unsigned i_attribute
;
605 pitem
= proto_tree_add_item(tree
, hf_btavrcp_attribute_list
, tvb
, offset
, count
* 4, ENC_NA
);
606 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_attribute_list
);
608 for (i_attribute
= 0; i_attribute
< count
; ++i_attribute
) {
609 proto_tree_add_item(ptree
, hf_btavrcp_attribute
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
618 dissect_attribute_entries(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
619 int offset
, unsigned count
)
622 unsigned attribute_id
;
623 unsigned value_length
;
626 proto_item
*pitem
= NULL
;
627 proto_tree
*ptree
= NULL
;
628 proto_item
*entry_item
= NULL
;
629 proto_tree
*entry_tree
= NULL
;
632 for (i_entry
= 0; i_entry
< count
; ++i_entry
) {
633 length
+= 4 + 2 + 2 + tvb_get_ntohs(tvb
, offset
+ length
+ 4 + 2);
636 pitem
= proto_tree_add_item(tree
, hf_btavrcp_attribute_entries
, tvb
, offset
, length
, ENC_NA
);
637 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_attribute_entries
);
639 for (i_entry
= 0; i_entry
< count
; ++i_entry
) {
640 attribute_id
= tvb_get_ntohl(tvb
, offset
);
641 value_length
= tvb_get_ntohs(tvb
, offset
+ 4 + 2);
642 value
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 4 + 2 + 2, value_length
, ENC_ASCII
);
644 if (attribute_id
== 0x01) col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Title: \"%s\"", value
);
646 entry_item
= proto_tree_add_none_format(ptree
, hf_btavrcp_attribute_item
, tvb
, offset
, 4 + 2 + 2 + value_length
, "Attribute [%21s]: %s", val_to_str_const(attribute_id
, attribute_id_vals
, "Unknown"), value
);
647 entry_tree
= proto_item_add_subtree(entry_item
, ett_btavrcp_attribute_entry
);
649 proto_tree_add_item(entry_tree
, hf_btavrcp_attribute
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
651 proto_tree_add_item(entry_tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
653 proto_tree_add_item(entry_tree
, hf_btavrcp_setting_value_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
655 proto_tree_add_item(entry_tree
, hf_btavrcp_setting_value
, tvb
, offset
, value_length
, ENC_UTF_8
| ENC_NA
);
656 offset
+= value_length
;
664 dissect_item_mediaplayer(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
666 unsigned displayable_name_length
;
667 unsigned item_length
;
668 unsigned feature_octet
;
670 uint8_t *displayable_name
;
673 proto_item
*features_item
;
674 proto_tree
*features_tree
;
675 proto_item
*features_not_set_item
;
676 proto_tree
*features_not_set_tree
;
678 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
679 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 2 + 1 + 4 + 16 + 1 + 2);
680 displayable_name
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 1 + 2 + 2 + 1 + 4 + 16 + 1 + 2 + 2, displayable_name_length
, ENC_ASCII
);
682 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_player_item
, tvb
, offset
, 1 + 2 + item_length
, "Player: %s", displayable_name
);
683 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_player
);
685 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
687 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
690 proto_tree_add_item(ptree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
693 proto_tree_add_item(ptree
, hf_btavrcp_major_player_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
696 proto_tree_add_item(ptree
, hf_btavrcp_player_subtype
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
699 proto_tree_add_item(ptree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
702 /* feature bit mask */
703 features_item
= proto_tree_add_item(ptree
, hf_btavrcp_features
, tvb
, offset
, 16, ENC_NA
);
704 features_tree
= proto_item_add_subtree(features_item
, ett_btavrcp_features
);
706 features_not_set_item
= proto_tree_add_item(features_tree
, hf_btavrcp_not_used_features
, tvb
, offset
, 16, ENC_NA
);
707 features_not_set_tree
= proto_item_add_subtree(features_not_set_item
, ett_btavrcp_features_not_used
);
709 feature_octet
= tvb_get_uint8(tvb
, offset
+ 0);
710 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_select
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
711 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_up
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
712 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_down
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
713 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_left
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
714 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_right
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
715 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_right_up
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
716 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_right_down
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
717 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_left_up
, tvb
, offset
+ 0, 1, ENC_BIG_ENDIAN
);
719 feature_octet
= tvb_get_uint8(tvb
, offset
+ 1);
720 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_left_down
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
721 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_root_menu
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
722 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_setup_menu
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
723 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_contents_menu
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
724 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_favorite_menu
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
725 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_exit
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
726 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_0
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
727 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_1
, tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
729 feature_octet
= tvb_get_uint8(tvb
, offset
+ 2);
730 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_2
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
731 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_3
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
732 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_4
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
733 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_5
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
734 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_6
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
735 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_7
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
736 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_8
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
737 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_9
, tvb
, offset
+ 2, 1, ENC_BIG_ENDIAN
);
739 feature_octet
= tvb_get_uint8(tvb
, offset
+ 3);
740 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_dot
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
741 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_enter
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
742 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_clear
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
743 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_channel_up
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
744 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_channel_down
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
745 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_previous_channel
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
746 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_sound_select
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
747 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_input_select
, tvb
, offset
+ 3, 1, ENC_BIG_ENDIAN
);
749 feature_octet
= tvb_get_uint8(tvb
, offset
+ 4);
750 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_display_information
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
751 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_help
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
752 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_page_up
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
753 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_page_down
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
754 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_power
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
755 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_volume_up
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
756 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_volume_down
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
757 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_mute
, tvb
, offset
+ 4, 1, ENC_BIG_ENDIAN
);
759 feature_octet
= tvb_get_uint8(tvb
, offset
+ 5);
760 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_play
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
761 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_stop
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
762 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_pause
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
763 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_record
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
764 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_rewind
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
765 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_fast_forward
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
766 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_eject
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
767 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_forward
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
769 feature_octet
= tvb_get_uint8(tvb
, offset
+ 6);
770 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_backward
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
771 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_angle
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
772 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_subpicture
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
773 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_f1
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
774 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_f2
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
775 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_f3
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
776 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_f4
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
777 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_passthrough_f5
, tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
779 feature_octet
= tvb_get_uint8(tvb
, offset
+ 7);
780 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_vendor_unique
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
781 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_basic_group_navigation
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
782 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_advanced_control_player
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
783 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_browsing
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
784 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_searching
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
785 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_addtonowplayer
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
786 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_uid_unique
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
787 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_only_browsable_when_addressed
, tvb
, offset
+ 7, 1, ENC_BIG_ENDIAN
);
789 feature_octet
= tvb_get_uint8(tvb
, offset
+ 8);
790 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_only_searchable_when_addressed
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
791 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_nowplaying
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
792 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_uid_persistency
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
793 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_number_of_items
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
794 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_cover_art
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
797 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_5
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
798 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_6
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
799 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_7
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
801 for (i_feature
= 9; i_feature
<= 16; ++i_feature
) {
802 feature_octet
= tvb_get_uint8(tvb
, offset
+ i_feature
);
803 proto_tree_add_item((feature_octet
& (1 << 0)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_0
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
804 proto_tree_add_item((feature_octet
& (1 << 1)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_1
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
805 proto_tree_add_item((feature_octet
& (1 << 2)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_2
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
806 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_3
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
807 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_4
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
808 proto_tree_add_item((feature_octet
& (1 << 5)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_5
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
809 proto_tree_add_item((feature_octet
& (1 << 6)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_6
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
810 proto_tree_add_item((feature_octet
& (1 << 7)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_7
, tvb
, offset
+ i_feature
, 1, ENC_BIG_ENDIAN
);
814 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
817 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
818 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
821 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
822 offset
+= displayable_name_length
;
829 dissect_item_media_element(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
832 unsigned number_of_attributes
;
833 unsigned displayable_name_length
;
834 unsigned item_length
;
835 uint8_t *displayable_name
;
840 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
841 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 8 + 1 + 2);
842 displayable_name
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 1 + 2 + 8 + 1 + 2 + 2, displayable_name_length
, ENC_ASCII
);
844 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_item
, tvb
, offset
, 1 + 2 + item_length
, "Element: %s", displayable_name
);
845 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_element
);
847 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
849 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
853 proto_tree_add_item(ptree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
856 proto_tree_add_item(ptree
, hf_btavrcp_media_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
859 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
862 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
863 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
866 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
867 offset
+= displayable_name_length
;
869 proto_tree_add_item(ptree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
870 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
873 offset
= dissect_attribute_entries(tvb
, pinfo
, ptree
, offset
, number_of_attributes
);
875 if ( item_length
!= (unsigned) offset
- offset_in
) {
876 expert_add_info(pinfo
, pitem
, &ei_btavrcp_item_length_bad
);
884 dissect_item_folder(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
886 unsigned displayable_name_length
;
887 unsigned item_length
;
888 uint8_t *displayable_name
;
892 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
893 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 8 + 1 + 1 + 2);
894 displayable_name
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 1 + 2 + 8 + 1 + 1 + 2 + 2, displayable_name_length
, ENC_ASCII
);
896 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_folder
, tvb
, offset
, 1 + 2 + item_length
, "Folder : %s", displayable_name
);
897 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_folder
);
899 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
901 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
904 proto_tree_add_item(ptree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
907 proto_tree_add_item(ptree
, hf_btavrcp_folder_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
910 proto_tree_add_item(ptree
, hf_btavrcp_folder_playable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
913 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
916 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
917 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
920 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
921 offset
+= displayable_name_length
;
928 dissect_passthrough(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
929 int offset
, bool is_command
, uint32_t *op
)
934 proto_tree_add_item(tree
, hf_btavrcp_passthrough_state
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
935 proto_tree_add_item(tree
, hf_btavrcp_passthrough_operation
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
936 *op
= tvb_get_uint8(tvb
, offset
);
937 operation
= tvb_get_uint8(tvb
, offset
) & 0x7F;
938 state
= (tvb_get_uint8(tvb
, offset
) & 0x80) >> 7;
940 proto_tree_add_item(tree
, hf_btavrcp_passthrough_data_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
944 if (operation
== 0x7E) {
945 proto_tree_add_item(tree
, hf_btavrcp_passthrough_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
947 proto_tree_add_item(tree
, hf_btavrcp_passthrough_vendor_unique_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
952 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s (%s)",
953 val_to_str_const(operation
, passthrough_operation_vals
, "Unknown opcode"),
954 val_to_str_const(state
, passthrough_state_vals
, "unknown"));
960 dissect_unit(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, bool is_command
)
963 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 5, ENC_NA
);
966 proto_tree_add_item(tree
, hf_btavrcp_unit_unknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
968 proto_tree_add_item(tree
, hf_btavrcp_unit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
969 proto_tree_add_item(tree
, hf_btavrcp_unit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
971 proto_tree_add_item(tree
, hf_btavrcp_passthrough_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
980 dissect_subunit(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, bool is_command
)
982 proto_tree_add_item(tree
, hf_btavrcp_subunit_page
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
983 proto_tree_add_item(tree
, hf_btavrcp_subunit_extension_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
987 proto_tree_add_item(tree
, hf_btavrcp_subunit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
988 proto_tree_add_item(tree
, hf_btavrcp_subunit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
990 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 3, ENC_NA
);
993 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 4, ENC_NA
);
1002 dissect_vendor_dependent(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1003 int offset
, unsigned ctype
, uint32_t *op
, uint32_t *op_arg
,
1004 bool is_command
, avrcp_proto_data_t
*avrcp_proto_data
)
1008 unsigned company_id
;
1010 unsigned packet_type
;
1011 unsigned parameter_length
;
1013 wmem_tree_key_t key
[7];
1015 uint32_t frame_number
;
1017 unsigned volume_percent
;
1018 fragment_t
*fragment
;
1019 data_fragment_t
*data_fragment
;
1023 proto_tree_add_item(tree
, hf_btavrcp_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1024 company_id
= tvb_get_ntoh24(tvb
, offset
);
1027 if (company_id
== OUI_BLUETOOTH
) {
1028 proto_tree_add_item(tree
, hf_btavrcp_bt_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1031 if (tvb_reported_length_remaining(tvb
, offset
) == 0) {
1032 col_append_str(pinfo
->cinfo
, COL_INFO
, " - No PDU ID");
1036 proto_tree_add_item(tree
, hf_btavrcp_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1038 pdu_id
= tvb_get_uint8(tvb
, offset
);
1039 *op
= pdu_id
| (company_id
<< 8);
1042 if (company_id
!= OUI_BLUETOOTH
) {
1043 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1044 val_to_str_const(pdu_id
, NULL
, "Unknown PDU ID"));
1047 proto_tree_add_item(tree
, hf_btavrcp_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1048 proto_tree_add_item(tree
, hf_btavrcp_packet_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1049 packet_type
= tvb_get_uint8(tvb
, offset
) & 0x03;
1052 proto_tree_add_item(tree
, hf_btavrcp_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1053 parameter_length
= tvb_get_ntohs(tvb
, offset
);
1056 if (company_id
!= OUI_BLUETOOTH
)
1059 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1060 val_to_str_const(pdu_id
, pdu_id_vals
, "Unknown PDU ID"));
1062 if (parameter_length
== 0) return offset
;
1064 length
= tvb_reported_length_remaining(tvb
, offset
);
1065 if (packet_type
== PACKET_TYPE_START
) {
1066 if (pinfo
->fd
->visited
== 0 && tvb_captured_length_remaining(tvb
, offset
) == length
) {
1067 k_op
= pdu_id
| (company_id
<< 8);
1068 frame_number
= pinfo
->num
;
1070 fragment
= wmem_new(wmem_file_scope(), fragment_t
);
1071 fragment
->start_frame_number
= pinfo
->num
;
1072 fragment
->end_frame_number
= 0;
1073 fragment
->state
= 0;
1075 fragment
->count
= 1;
1076 fragment
->fragments
= wmem_tree_new(wmem_file_scope());
1078 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1079 data_fragment
->length
= length
;
1080 data_fragment
->data
= (uint8_t *) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1081 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1083 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1086 key
[0].key
= &avrcp_proto_data
->interface_id
;
1088 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1090 key
[2].key
= &avrcp_proto_data
->chandle
;
1092 key
[3].key
= &avrcp_proto_data
->channel
;
1096 key
[5].key
= &frame_number
;
1100 fragment
->interface_id
= avrcp_proto_data
->interface_id
;
1101 fragment
->adapter_id
= avrcp_proto_data
->adapter_id
;
1102 fragment
->chandle
= avrcp_proto_data
->chandle
;
1103 fragment
->psm
= avrcp_proto_data
->channel
;
1104 fragment
->op
= pdu_id
| (company_id
<< 8);
1106 wmem_tree_insert32_array(reassembling
, key
, fragment
);
1109 col_append_str(pinfo
->cinfo
, COL_INFO
, " [start]");
1111 } else if (packet_type
== PACKET_TYPE_CONTINUE
) {
1112 if (pinfo
->fd
->visited
== 0 && tvb_captured_length_remaining(tvb
, offset
) == length
) {
1113 k_op
= pdu_id
| (company_id
<< 8);
1114 frame_number
= pinfo
->num
;
1117 key
[0].key
= &avrcp_proto_data
->interface_id
;
1119 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1121 key
[2].key
= &avrcp_proto_data
->chandle
;
1123 key
[3].key
= &avrcp_proto_data
->channel
;
1127 key
[5].key
= &frame_number
;
1131 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1132 if (fragment
&& fragment
->interface_id
== avrcp_proto_data
->interface_id
&&
1133 fragment
->adapter_id
== avrcp_proto_data
->adapter_id
&&
1134 fragment
->chandle
== avrcp_proto_data
->chandle
&&
1135 fragment
->psm
== avrcp_proto_data
->channel
&&
1136 fragment
->op
== (pdu_id
| (company_id
<< 8)) &&
1137 fragment
->state
== 1) {
1138 fragment
->count
+= 1;
1139 fragment
->state
= 0;
1141 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1142 data_fragment
->length
= length
;
1143 data_fragment
->data
= (uint8_t *) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1144 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1145 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1149 col_append_str(pinfo
->cinfo
, COL_INFO
, " [continue]");
1151 } else if (packet_type
== PACKET_TYPE_END
) {
1155 col_append_str(pinfo
->cinfo
, COL_INFO
, " [end]");
1157 k_op
= pdu_id
| (company_id
<< 8);
1158 frame_number
= pinfo
->num
;
1161 key
[0].key
= &avrcp_proto_data
->interface_id
;
1163 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1165 key
[2].key
= &avrcp_proto_data
->chandle
;
1167 key
[3].key
= &avrcp_proto_data
->channel
;
1171 key
[5].key
= &frame_number
;
1175 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1176 if (fragment
&& fragment
->interface_id
== avrcp_proto_data
->interface_id
&&
1177 fragment
->adapter_id
== avrcp_proto_data
->adapter_id
&&
1178 fragment
->chandle
== avrcp_proto_data
->chandle
&&
1179 fragment
->psm
== avrcp_proto_data
->channel
&&
1180 fragment
->op
== (pdu_id
| (company_id
<< 8))) {
1183 if (fragment
->state
== 1 && pinfo
->fd
->visited
== 0) {
1184 fragment
->end_frame_number
= pinfo
->num
;
1185 fragment
->count
+= 1;
1186 fragment
->state
= 2;
1188 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1189 data_fragment
->length
= length
;
1190 data_fragment
->data
= (uint8_t *) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1191 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1192 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1196 if (fragment
->state
== 2) {
1197 unsigned i_length
= 0;
1198 uint8_t *reassembled
;
1200 for (i_frame
= 1; i_frame
<= fragment
->count
; ++i_frame
) {
1201 data_fragment
= (data_fragment_t
*)wmem_tree_lookup32_le(fragment
->fragments
, i_frame
);
1202 length
+= data_fragment
->length
;
1205 reassembled
= (uint8_t *) wmem_alloc(pinfo
->pool
, length
);
1207 for (i_frame
= 1; i_frame
<= fragment
->count
; ++i_frame
) {
1208 data_fragment
= (data_fragment_t
*)wmem_tree_lookup32_le(fragment
->fragments
, i_frame
);
1209 memcpy(reassembled
+ i_length
,
1210 data_fragment
->data
,
1211 data_fragment
->length
);
1212 i_length
+= data_fragment
->length
;
1215 next_tvb
= tvb_new_child_real_data(tvb
, reassembled
, length
, length
);
1216 add_new_data_source(pinfo
, next_tvb
, "Reassembled AVRCP");
1221 pitem
= proto_tree_add_item(tree
, hf_btavrcp_reassembled
, tvb
, offset
, 0, ENC_NA
);
1222 proto_item_set_generated(pitem
);
1227 if (ctype
== 0x0a) { /* REJECT */
1229 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1230 status
= tvb_get_uint8(tvb
, offset
);
1233 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1234 val_to_str_const(status
, status_vals
, "Unknown status"));
1235 } else switch(pdu_id
) {
1236 case PDU_GET_CAPABILITIES
:
1238 unsigned capability
;
1240 proto_tree_add_item(tree
, hf_btavrcp_capability
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1241 capability
= tvb_get_uint8(tvb
, offset
);
1242 *op_arg
= capability
;
1243 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(%s)",
1244 val_to_str_const(capability
, capability_vals
, "unknown"));
1247 unsigned capability
;
1248 unsigned capability_count
;
1249 unsigned i_capability
;
1251 proto_tree_add_item(tree
, hf_btavrcp_capability
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1252 capability
= tvb_get_uint8(tvb
, offset
);
1253 *op_arg
= capability
;
1255 proto_tree_add_item(tree
, hf_btavrcp_capability_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1256 capability_count
= tvb_get_uint8(tvb
, offset
);
1259 for (i_capability
= 0; i_capability
< capability_count
; ++i_capability
) {
1260 if (capability
== 0x02) {
1261 proto_tree_add_item(tree
, hf_btavrcp_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1263 } else if (capability
== 0x03) {
1264 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1269 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(%s) - Count: %u",
1270 val_to_str_const(capability
, capability_vals
, "unknown"), capability_count
);
1273 case PDU_LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES
:
1277 unsigned number_of_attributes
;
1278 unsigned i_attribute
;
1280 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1281 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1284 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1285 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1290 case PDU_LIST_PLAYER_APPLICATION_SETTING_VALUE
:
1292 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1295 unsigned number_of_values
;
1298 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1299 number_of_values
= tvb_get_uint8(tvb
, offset
);
1302 for (i_value
= 0; i_value
< number_of_values
; ++i_value
) {
1303 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1308 case PDU_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE
:
1310 unsigned number_of_attributes
;
1311 unsigned i_attribute
;
1313 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1314 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1317 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1318 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1322 unsigned number_of_settings
;
1325 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1326 number_of_settings
= tvb_get_uint8(tvb
, offset
);
1329 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1330 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1332 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1337 case PDU_SET_PLAYER_APPLICATION_SETTING_VALUE
:
1339 unsigned number_of_settings
;
1342 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1343 number_of_settings
= tvb_get_uint8(tvb
, offset
);
1346 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1347 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1349 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1356 case PDU_GET_PLAYER_APPLICATION_SETTING_ATTRIBUTE_TEXT
:
1358 unsigned number_of_attributes
;
1359 unsigned i_attribute
;
1361 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1362 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1365 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1366 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1370 unsigned number_of_attributes
;
1371 unsigned i_attribute
;
1372 unsigned attribute_name_length
;
1374 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1375 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1378 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1379 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1382 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1385 proto_tree_add_item(tree
, hf_btavrcp_attribute_name_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1386 attribute_name_length
= tvb_get_ntohs(tvb
, offset
);
1389 proto_tree_add_item(tree
, hf_btavrcp_attribute_name
, tvb
, offset
, attribute_name_length
, ENC_UTF_8
| ENC_NA
);
1390 offset
+= attribute_name_length
;
1394 case PDU_GET_PLAYER_APPLICATION_SETTING_VALUE_TEXT
:
1396 unsigned number_of_values
;
1399 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1401 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1402 number_of_values
= tvb_get_uint8(tvb
, offset
);
1405 for (i_value
= 0; i_value
< number_of_values
; ++i_value
) {
1406 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1410 unsigned number_of_values
;
1411 unsigned i_attribute
;
1412 unsigned attribute_value_length
;
1414 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1415 number_of_values
= tvb_get_uint8(tvb
, offset
);
1418 for (i_attribute
= 0; i_attribute
< number_of_values
; ++i_attribute
) {
1419 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1422 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1425 proto_tree_add_item(tree
, hf_btavrcp_attribute_value_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1426 attribute_value_length
= tvb_get_ntohs(tvb
, offset
);
1429 proto_tree_add_item(tree
, hf_btavrcp_attribute_value
, tvb
, offset
, attribute_value_length
, ENC_UTF_8
| ENC_NA
);
1430 offset
+= attribute_value_length
;
1434 case PDU_INFORM_DISPLAYABLE_CHARACTER_SET
:
1436 unsigned number_of_character_set
;
1437 unsigned i_character_set
;
1439 proto_tree_add_item(tree
, hf_btavrcp_number_of_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1440 number_of_character_set
= tvb_get_uint8(tvb
, offset
);
1443 for (i_character_set
= 0; i_character_set
< number_of_character_set
; ++i_character_set
) {
1444 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1451 case PDU_INFORM_BATTERY_STATUS_OF_CT
:
1453 unsigned battery_status
;
1455 proto_tree_add_item(tree
, hf_btavrcp_battery_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1456 battery_status
= tvb_get_uint8(tvb
, offset
);
1458 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Battery: %s", val_to_str_const(battery_status
, battery_status_vals
, "unknown"));
1463 case PDU_GET_ELEMENT_ATTRIBUTES
:
1465 unsigned number_of_attributes
;
1466 uint64_t identifier
;
1468 proto_tree_add_item(tree
, hf_btavrcp_identifier
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1469 identifier
= tvb_get_ntoh64(tvb
, offset
);
1472 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - 0x%08X%08X", (unsigned) (identifier
>> 32), (unsigned) (identifier
& 0xFFFFFFFF));
1473 if (identifier
== 0x00) col_append_str(pinfo
->cinfo
, COL_INFO
, " (PLAYING)");
1475 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1476 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1478 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, number_of_attributes
);
1480 unsigned number_of_attributes
;
1482 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1483 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
1485 offset
= dissect_attribute_entries(tvb
, pinfo
, tree
, offset
, number_of_attributes
);
1488 case PDU_GET_PLAY_STATUS
:
1492 unsigned song_length
;
1493 unsigned song_position
;
1494 unsigned play_status
;
1496 proto_tree_add_item(tree
, hf_btavrcp_song_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1497 song_length
= tvb_get_ntohl(tvb
, offset
);
1499 proto_tree_add_item(tree
, hf_btavrcp_song_position
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1500 song_position
= tvb_get_ntohl(tvb
, offset
);
1502 proto_tree_add_item(tree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1503 play_status
= tvb_get_uint8(tvb
, offset
);
1506 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " PlayStatus: %s, SongPosition: %ums, SongLength: %ums",
1507 val_to_str_const(play_status
, play_status_vals
, "unknown"), song_position
, song_length
);
1510 case PDU_REGISTER_NOTIFICATION
:
1511 event_id
= tvb_get_uint8(tvb
, offset
);
1513 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1514 val_to_str_const(event_id
, notification_vals
, "Unknown Event ID"));
1517 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1519 proto_tree_add_item(tree
, hf_btavrcp_notification_interval
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1522 unsigned number_of_settings
;
1524 uint64_t identifier
;
1525 unsigned play_status
;
1526 unsigned song_position
;
1527 unsigned battery_status
;
1528 unsigned uid_counter
;
1530 unsigned system_status
;
1532 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1535 if (ctype
== 0x0D || ctype
== 0x0F) switch(event_id
) {
1536 case EVENT_PLAYBACK_STATUS_CHANGED
:
1537 proto_tree_add_item(tree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1538 play_status
= tvb_get_uint8(tvb
, offset
);
1540 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - PlayStatus: %s", val_to_str_const(play_status
, play_status_vals
, "unknown"));
1542 case EVENT_TRACK_CHANGED
:
1543 pitem
= proto_tree_add_item(tree
, hf_btavrcp_identifier
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1544 identifier
= tvb_get_ntoh64(tvb
, offset
);
1547 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - 0x%08X%08X", (unsigned) (identifier
>> 32), (unsigned) (identifier
& 0xFFFFFFFF));
1548 if (identifier
== UINT64_C(0x0000000000000000)) {
1549 col_append_str(pinfo
->cinfo
, COL_INFO
, " (SELECTED)");
1550 proto_item_append_text(pitem
, " (SELECTED)");
1551 } else if (identifier
== UINT64_C(0xFFFFFFFFFFFFFFFF)) {
1552 col_append_str(pinfo
->cinfo
, COL_INFO
, " (NOT SELECTED)");
1553 proto_item_append_text(pitem
, " (NOT SELECTED)");
1557 case EVENT_TRACK_REACHED_END
:
1560 case EVENT_TRACK_REACHED_START
:
1563 case EVENT_PLAYBACK_POSITION_CHANGED
:
1564 pitem
= proto_tree_add_item(tree
, hf_btavrcp_song_position
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1565 song_position
= tvb_get_ntohl(tvb
, offset
);
1567 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - SongPosition: %ums", song_position
);
1568 if (song_position
== 0xFFFFFFFF) {
1569 proto_item_append_text(pitem
, " (NOT SELECTED)");
1570 col_append_str(pinfo
->cinfo
, COL_INFO
, " (NOT SELECTED)");
1571 } else if (!pinfo
->fd
->visited
) {
1572 btavrcp_song_position_data_t
*song_position_data
;
1574 frame_number
= pinfo
->num
;
1577 key
[0].key
= &avrcp_proto_data
->interface_id
;
1579 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1581 key
[2].key
= &frame_number
;
1585 song_position_data
= wmem_new(wmem_file_scope(), btavrcp_song_position_data_t
);
1586 song_position_data
->song_position
= song_position
;
1587 song_position_data
->used_in_frame
= 0;
1589 wmem_tree_insert32_array(btavrcp_song_positions
, key
, song_position_data
);
1592 case EVENT_BATTERY_STATUS_CHANGED
:
1593 proto_tree_add_item(tree
, hf_btavrcp_battery_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1594 battery_status
= tvb_get_uint8(tvb
, offset
);
1596 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Battery: %s", val_to_str_const(battery_status
, battery_status_vals
, "unknown"));
1598 case EVENT_SYSTEM_STATUS_CHANGED
:
1599 proto_tree_add_item(tree
, hf_btavrcp_system_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1600 system_status
= tvb_get_uint8(tvb
, offset
);
1602 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - SystemStatus: %s", val_to_str_const(system_status
, system_status_vals
, "unknown"));
1604 case EVENT_PLAYER_APPLICATION_SETTING_CHANGED
:
1605 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1606 number_of_settings
= tvb_get_uint8(tvb
, offset
);
1609 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1610 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1612 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1616 case EVENT_NOWPLAYING_CONTENT_CHANGED
:
1619 case EVENT_AVAILABLE_PLAYERS_CHANGED
:
1622 case EVENT_ADDRESSEDPLAYER_CHANGED
:
1623 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1624 player_id
= tvb_get_ntohs(tvb
, offset
);
1626 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1627 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1629 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - PlayerID: %u, UidCounter: 0x%04x", player_id
, uid_counter
);
1631 case EVENT_UIDS_CHANGED
:
1632 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1633 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1635 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - UidCounter: 0x%04x", uid_counter
);
1637 case EVENT_VOLUME_CHANGED
:
1638 proto_tree_add_item(tree
, hf_btavrcp_absolute_volume_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1639 pitem
= proto_tree_add_item(tree
, hf_btavrcp_absolute_volume
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1641 volume
= tvb_get_uint8(tvb
, offset
) & 0x7F;
1642 volume_percent
= (unsigned) ((double) volume
* 100 / (double) 0x7F);
1645 proto_item_append_text(pitem
, " (%u%%)", volume_percent
);
1646 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Volume: %u%%", volume_percent
);
1649 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
1650 offset
= tvb_reported_length(tvb
);
1656 case PDU_REQUEST_CONTINUING_RESPONSE
:
1658 unsigned continuing_op
;
1660 proto_tree_add_item(tree
, hf_btavrcp_bt_continuing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1661 continuing_op
= tvb_get_uint8(tvb
, offset
) | (company_id
<< 8);
1662 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1663 val_to_str_const(tvb_get_uint8(tvb
, offset
), pdu_id_vals
, "Unknown opcode"));
1666 if (pinfo
->fd
->visited
== 0) {
1667 k_op
= continuing_op
;
1668 frame_number
= pinfo
->num
;
1671 key
[0].key
= &avrcp_proto_data
->interface_id
;
1673 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1675 key
[2].key
= &avrcp_proto_data
->chandle
;
1677 key
[3].key
= &avrcp_proto_data
->channel
;
1681 key
[5].key
= &frame_number
;
1685 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1686 if (fragment
&& fragment
->interface_id
== avrcp_proto_data
->interface_id
&&
1687 fragment
->adapter_id
== avrcp_proto_data
->adapter_id
&&
1688 fragment
->chandle
== avrcp_proto_data
->chandle
&&
1689 fragment
->psm
== avrcp_proto_data
->channel
&&
1690 fragment
->op
== continuing_op
&&
1691 fragment
->state
== 0) {
1692 fragment
->state
= 1;
1696 *op
= continuing_op
;
1701 case PDU_ABORT_CONTINUING_RESPONSE
:
1703 unsigned continuing_op
;
1705 proto_tree_add_item(tree
, hf_btavrcp_bt_continuing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1706 continuing_op
= tvb_get_uint8(tvb
, offset
) | (company_id
<< 8);
1707 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1708 val_to_str_const(tvb_get_uint8(tvb
, offset
), pdu_id_vals
, "Unknown opcode"));
1711 if (pinfo
->fd
->visited
== 0) {
1712 k_op
= continuing_op
;
1713 frame_number
= pinfo
->num
;
1716 key
[0].key
= &avrcp_proto_data
->interface_id
;
1718 key
[1].key
= &avrcp_proto_data
->adapter_id
;
1720 key
[2].key
= &avrcp_proto_data
->chandle
;
1722 key
[3].key
= &avrcp_proto_data
->channel
;
1726 key
[5].key
= &frame_number
;
1730 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1731 if (fragment
&& fragment
->interface_id
== avrcp_proto_data
->interface_id
&&
1732 fragment
->adapter_id
== avrcp_proto_data
->adapter_id
&&
1733 fragment
->chandle
== avrcp_proto_data
->chandle
&&
1734 fragment
->psm
== avrcp_proto_data
->channel
&&
1735 fragment
->op
== continuing_op
&&
1736 fragment
->state
== 0) {
1737 fragment
->state
= 3;
1744 case PDU_SET_ABSOLUTE_VOLUME
:
1745 proto_tree_add_item(tree
, hf_btavrcp_absolute_volume_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1746 pitem
= proto_tree_add_item(tree
, hf_btavrcp_absolute_volume
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1747 volume
= tvb_get_uint8(tvb
, offset
) & 0x7F;
1748 volume_percent
= (unsigned) ((double) volume
* 100 / (double) 0x7F);
1751 proto_item_append_text(pitem
, " (%u%%)", volume_percent
);
1752 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Volume: %u%%", volume_percent
);
1754 case PDU_SET_ADDRESSED_PLAYER
:
1758 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1759 player_id
= tvb_get_ntohs(tvb
, offset
);
1762 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Player ID: %u", player_id
);
1766 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1767 status
= tvb_get_uint8(tvb
, offset
);
1770 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1771 val_to_str_const(status
, status_vals
, "Unknown status"));
1778 unsigned uid_counter
;
1780 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1781 scope
= tvb_get_uint8(tvb
, offset
);
1783 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1784 uid
= tvb_get_ntoh64(tvb
, offset
);
1786 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1787 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1790 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" PRIx64
", UidCounter: 0x%04x",
1791 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
1795 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1796 status
= tvb_get_uint8(tvb
, offset
);
1798 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1799 val_to_str_const(status
, status_vals
, "Unknown status"));
1802 case PDU_ADD_TO_NOW_PLAYING
:
1806 unsigned uid_counter
;
1808 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1809 scope
= tvb_get_uint8(tvb
, offset
);
1811 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1812 uid
= tvb_get_ntoh64(tvb
, offset
);
1814 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1815 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1818 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" PRIx64
", UidCounter: 0x%04x",
1819 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
1823 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1824 status
= tvb_get_uint8(tvb
, offset
);
1826 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1827 val_to_str_const(status
, status_vals
, "Unknown status"));
1837 dissect_browsing(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1838 int offset
, bool is_command
)
1841 unsigned status
= 0x00;
1843 proto_tree_add_item(tree
, hf_btavrcp_browsing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1844 pdu_id
= tvb_get_uint8(tvb
, offset
);
1847 proto_tree_add_item(tree
, hf_btavrcp_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1851 col_append_str(pinfo
->cinfo
, COL_INFO
, ": Command");
1853 /* common code "status" in response */
1854 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1855 status
= tvb_get_uint8(tvb
, offset
);
1858 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s",
1859 val_to_str_const(status
, status_vals
, "Unknown status"));
1862 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1863 val_to_str_const(pdu_id
, browsing_pdu_id_vals
, "Unknown opcode"));
1865 if (is_command
|| status
== STATUS_OK
) switch(pdu_id
) {
1866 case PDU_SET_BROWSED_PLAYER
:
1870 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1871 player_id
= tvb_get_ntohs(tvb
, offset
);
1874 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Player ID: %u", player_id
);
1877 unsigned folder_depth
;
1878 unsigned folder_name_length
;
1881 const uint8_t *folder_name
;
1883 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1885 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1887 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1889 proto_tree_add_item(tree
, hf_btavrcp_folder_depth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1890 folder_depth
= tvb_get_uint8(tvb
, offset
);
1893 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_current_path
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), "Current Path: /");
1894 col_append_str(pinfo
->cinfo
, COL_INFO
, "Current Path: /");
1895 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_path
);
1897 for (i_folder
= 0; i_folder
< folder_depth
; ++i_folder
) {
1898 proto_tree_add_item(ptree
, hf_btavrcp_folder_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1899 folder_name_length
= tvb_get_ntohs(tvb
, offset
);
1901 proto_tree_add_item_ret_string(ptree
, hf_btavrcp_folder_name
, tvb
, offset
, folder_name_length
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &folder_name
);
1902 offset
+= folder_name_length
;
1903 proto_item_append_text(pitem
, "%s/", folder_name
);
1904 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s/", folder_name
);
1908 case PDU_GET_FOLDER_ITEMS
:
1910 unsigned attribute_count
;
1912 unsigned start_item
;
1915 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1916 scope
= tvb_get_uint8(tvb
, offset
);
1918 proto_tree_add_item(tree
, hf_btavrcp_start_item
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1919 start_item
= tvb_get_ntohl(tvb
, offset
);
1921 proto_tree_add_item(tree
, hf_btavrcp_end_item
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1922 end_item
= tvb_get_ntohl(tvb
, offset
);
1924 proto_tree_add_item(tree
, hf_btavrcp_attribute_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1925 attribute_count
= tvb_get_uint8(tvb
, offset
);
1927 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, attribute_count
);
1929 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, StartItem: 0x%04x, EndItem: 0x%04x",
1930 val_to_str_const(scope
, scope_vals
, "unknown"), start_item
, end_item
);
1932 unsigned number_of_items
;
1933 unsigned uid_counter
;
1936 unsigned item_length
;
1938 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1939 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1941 proto_tree_add_item(tree
, hf_btavrcp_number_of_items16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1942 number_of_items
= tvb_get_ntohs(tvb
, offset
);
1945 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - UidCounter: 0x%04x, NumberOfItems: %u",
1946 uid_counter
, number_of_items
);
1948 for (i_item
= 0; i_item
< number_of_items
; ++i_item
) {
1949 item_type
= tvb_get_uint8(tvb
, offset
);
1950 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
1952 if (item_type
== ITEM_MEDIAPLAYER
) {
1953 dissect_item_mediaplayer(tvb
, pinfo
, tree
, offset
);
1954 offset
+= 1 + 2 + item_length
;
1955 } else if (item_type
== ITEM_MEDIA_ELEMENT
) {
1956 dissect_item_media_element(tvb
, pinfo
, tree
, offset
);
1957 offset
+= 1 + 2 + item_length
;
1958 } else if (item_type
== ITEM_FOLDER
) {
1959 dissect_item_folder(tvb
, pinfo
, tree
, offset
);
1960 offset
+= 1 + 2 + item_length
;
1962 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, item_length
, ENC_NA
);
1963 offset
+= 1 + 2 + item_length
;
1968 case PDU_CHANGE_PATH
:
1971 unsigned uid_counter
;
1974 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1975 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1977 proto_tree_add_item(tree
, hf_btavrcp_direction
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1978 direction
= tvb_get_uint8(tvb
, offset
);
1980 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1981 uid
= tvb_get_ntoh64(tvb
, offset
);
1984 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Direction: %s, Uid: 0x%016" PRIx64
", UidCounter: 0x%04x",
1985 val_to_str_const(direction
, direction_vals
, "unknown"), uid
, uid_counter
);
1987 unsigned number_of_items
;
1989 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1990 number_of_items
= tvb_get_ntohl(tvb
, offset
);
1992 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - NumberOfItems: %u", number_of_items
);
1995 case PDU_GET_ITEM_ATTRIBUTES
:
1997 unsigned number_of_attributes
;
1999 unsigned uid_counter
;
2002 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2003 scope
= tvb_get_uint8(tvb
, offset
);
2005 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
2006 uid
= tvb_get_ntoh64(tvb
, offset
);
2008 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2009 uid_counter
= tvb_get_ntohs(tvb
, offset
);
2011 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2012 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
2014 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" PRIx64
", UidCounter: 0x%04x",
2015 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
2018 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, number_of_attributes
);
2020 unsigned number_of_attributes
;
2022 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2023 number_of_attributes
= tvb_get_uint8(tvb
, offset
);
2025 offset
= dissect_attribute_entries(tvb
, pinfo
, tree
, offset
, number_of_attributes
);
2030 unsigned search_length
;
2032 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2034 proto_tree_add_item(tree
, hf_btavrcp_search_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2035 search_length
= tvb_get_ntohs(tvb
, offset
);
2037 proto_tree_add_item(tree
, hf_btavrcp_search
, tvb
, offset
, search_length
, ENC_NA
);
2038 offset
+= search_length
;
2040 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2042 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2046 case PDU_GENERAL_REJECT
:
2047 /* implemented in common code before switch() */
2056 dissect_btavrcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2059 proto_tree
*btavrcp_tree
;
2060 proto_item
*pitem
= NULL
;
2064 uint32_t op_arg
= 0;
2066 unsigned response_time
;
2067 unsigned max_response_time
;
2068 unsigned is_command
;
2069 timing_info_t
*timing_info
;
2070 wmem_tree_key_t key
[9];
2072 uint32_t frame_number
;
2074 avrcp_proto_data_t avrcp_proto_data
;
2076 previous_proto
= (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo
->layers
)))));
2077 if (previous_proto
== proto_btavctp
) {
2078 btavctp_data_t
*avctp_data
;
2080 avctp_data
= (btavctp_data_t
*) data
;
2082 avrcp_proto_data
.interface_id
= avctp_data
->interface_id
;
2083 avrcp_proto_data
.adapter_id
= avctp_data
->adapter_id
;
2084 avrcp_proto_data
.chandle
= avctp_data
->chandle
;
2085 avrcp_proto_data
.channel
= avctp_data
->psm
;
2087 is_command
= !avctp_data
->cr
;
2089 avrcp_proto_data
.interface_id
= HCI_INTERFACE_DEFAULT
;
2090 avrcp_proto_data
.adapter_id
= HCI_ADAPTER_DEFAULT
;
2091 avrcp_proto_data
.chandle
= 0;
2092 avrcp_proto_data
.channel
= 0;
2094 /* NOTE: There is need to allow user specify that */
2095 is_command
= (pinfo
->p2p_dir
== P2P_DIR_SENT
);
2098 ti
= proto_tree_add_item(tree
, proto_btavrcp
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
), ENC_NA
);
2099 btavrcp_tree
= proto_item_add_subtree(ti
, ett_btavrcp
);
2101 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AVRCP");
2103 switch (pinfo
->p2p_dir
) {
2105 col_set_str(pinfo
->cinfo
, COL_INFO
, "Sent ");
2108 col_set_str(pinfo
->cinfo
, COL_INFO
, "Rcvd ");
2111 col_set_str(pinfo
->cinfo
, COL_INFO
, "UnknownDirection ");
2115 if (avrcp_proto_data
.channel
== BTL2CAP_PSM_AVCTP_BRWS
) {
2116 col_append_str(pinfo
->cinfo
, COL_INFO
, "Browsing");
2117 offset
= dissect_browsing(tvb
, pinfo
, btavrcp_tree
, offset
, is_command
);
2119 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2120 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_ctype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2121 ctype
= tvb_get_uint8(tvb
, offset
) & 0x0F;
2123 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_subunit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2124 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_subunit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2126 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_opcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2127 opcode
= tvb_get_uint8(tvb
, offset
);
2130 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s: %s",
2131 val_to_str_const(opcode
, opcode_vals
, "Unknown opcode"),
2132 val_to_str_const(ctype
, ctype_vals
, "Unknown ctype"));
2135 case OPCODE_PASSTHROUGH
:
2136 offset
= dissect_passthrough(tvb
, pinfo
, btavrcp_tree
, offset
,
2140 offset
= dissect_unit(tvb
, btavrcp_tree
, offset
, is_command
);
2142 case OPCODE_SUBUNIT
:
2143 offset
= dissect_subunit(tvb
, btavrcp_tree
, offset
, is_command
);
2145 case OPCODE_VENDOR_DEPENDENT
:
2146 offset
= dissect_vendor_dependent(tvb
, pinfo
, btavrcp_tree
,
2147 offset
, ctype
, &op
, &op_arg
, is_command
, &avrcp_proto_data
);
2151 k_op_arg
= (ctype
== 0x0a) ? UINT32_MAX
: op_arg
;
2152 frame_number
= pinfo
->num
;
2155 key
[0].key
= &avrcp_proto_data
.interface_id
;
2157 key
[1].key
= &avrcp_proto_data
.adapter_id
;
2159 key
[2].key
= &avrcp_proto_data
.chandle
;
2161 key
[3].key
= &avrcp_proto_data
.channel
;
2163 key
[4].key
= &opcode
;
2167 key
[6].key
= &k_op_arg
;
2169 key
[7].key
= &frame_number
;
2173 if (pinfo
->fd
->visited
== 0) {
2175 if (ctype
== 0x00) { /* MTC is for CONTROL */
2176 max_response_time
= 200;
2177 } else if (ctype
== 0x01 || ctype
== 0x03) {
2178 /* MTP is for STATUS, NOTIFY */
2179 max_response_time
= 1000;
2181 max_response_time
= 100;
2184 timing_info
= wmem_new(wmem_file_scope(), timing_info_t
);
2185 timing_info
->command_frame_number
= pinfo
->num
;
2186 timing_info
->command_timestamp
= pinfo
->abs_ts
;
2187 timing_info
->response_frame_number
= 0;
2188 timing_info
->response_timestamp
.secs
= 0;
2189 timing_info
->response_timestamp
.nsecs
= 0;
2190 timing_info
->max_response_time
= max_response_time
;
2192 timing_info
->interface_id
= avrcp_proto_data
.interface_id
;
2193 timing_info
->adapter_id
= avrcp_proto_data
.adapter_id
;
2194 timing_info
->chandle
= avrcp_proto_data
.chandle
;
2195 timing_info
->psm
= avrcp_proto_data
.channel
;
2196 timing_info
->opcode
= opcode
;
2197 timing_info
->op
= op
;
2198 timing_info
->op_arg
= op_arg
;
2199 timing_info
->used
= 0;
2201 wmem_tree_insert32_array(timing
, key
, timing_info
);
2203 timing_info
= (timing_info_t
*)wmem_tree_lookup32_array_le(timing
, key
);
2204 if (timing_info
&& timing_info
->interface_id
== avrcp_proto_data
.interface_id
&&
2205 timing_info
->adapter_id
== avrcp_proto_data
.adapter_id
&&
2206 timing_info
->chandle
== avrcp_proto_data
.chandle
&&
2207 timing_info
->psm
== avrcp_proto_data
.channel
&&
2208 timing_info
->opcode
== opcode
&&
2209 timing_info
->op
== op
&&
2210 ((ctype
== 0x0a) ? 1 : (timing_info
->op_arg
== op_arg
)) &&
2211 timing_info
->used
== 0) {
2212 timing_info
->response_frame_number
= pinfo
->num
;
2213 timing_info
->response_timestamp
= pinfo
->abs_ts
;
2214 timing_info
->used
= 1;
2218 k_op_arg
= (ctype
== 0x0a) ? UINT32_MAX
: op_arg
;
2219 frame_number
= pinfo
->num
;
2222 key
[0].key
= &avrcp_proto_data
.interface_id
;
2224 key
[1].key
= &avrcp_proto_data
.adapter_id
;
2226 key
[2].key
= &avrcp_proto_data
.chandle
;
2228 key
[3].key
= &avrcp_proto_data
.channel
;
2230 key
[4].key
= &opcode
;
2234 key
[6].key
= &k_op_arg
;
2236 key
[7].key
= &frame_number
;
2242 timing_info
= (timing_info_t
*)wmem_tree_lookup32_array_le(timing
, key
);
2243 if (timing_info
&& timing_info
->interface_id
== avrcp_proto_data
.interface_id
&&
2244 timing_info
->adapter_id
== avrcp_proto_data
.adapter_id
&&
2245 timing_info
->chandle
== avrcp_proto_data
.chandle
&&
2246 timing_info
->psm
== avrcp_proto_data
.channel
&&
2247 timing_info
->opcode
== opcode
&&
2248 timing_info
->op
== op
&&
2249 ((ctype
== 0x0a) ? 1 : (timing_info
->op_arg
== op_arg
))) {
2251 if (timing_info
->command_timestamp
.nsecs
> timing_info
->response_timestamp
.nsecs
) {
2252 response_time
= timing_info
->response_timestamp
.nsecs
+ (1000000000 - timing_info
->command_timestamp
.nsecs
);
2253 response_time
/= 1000000;
2254 response_time
+= ((unsigned)timing_info
->response_timestamp
.secs
- 1 - (unsigned)timing_info
->command_timestamp
.secs
) / 1000;
2256 response_time
= timing_info
->response_timestamp
.nsecs
- timing_info
->command_timestamp
.nsecs
;
2257 response_time
/= 1000000;
2258 response_time
+= ((unsigned)timing_info
->response_timestamp
.secs
- (unsigned)timing_info
->command_timestamp
.secs
) / 1000;
2261 if (timing_info
->response_frame_number
== 0) {
2262 response_time
= UINT_MAX
;
2265 pitem
= proto_tree_add_uint(btavrcp_tree
, hf_btavrcp_response_time
, tvb
, 0, 0, response_time
);
2266 proto_item_append_text(pitem
, "/%ums", timing_info
->max_response_time
);
2267 if (response_time
> timing_info
->max_response_time
) {
2268 proto_item_append_text(pitem
, "; TIME EXCEEDED");
2270 proto_item_set_generated(pitem
);
2272 if (timing_info
->response_frame_number
== 0) {
2273 pitem
= proto_tree_add_expert(btavrcp_tree
, pinfo
, &ei_btavrcp_no_response
, tvb
, 0, 0);
2274 proto_item_set_generated(pitem
);
2277 pitem
= proto_tree_add_uint(btavrcp_tree
, hf_btavrcp_response_in_frame
, tvb
, 0, 0, timing_info
->response_frame_number
);
2278 proto_item_set_generated(pitem
);
2280 pitem
= proto_tree_add_uint(btavrcp_tree
, hf_btavrcp_command_in_frame
, tvb
, 0, 0, timing_info
->command_frame_number
);
2281 proto_item_set_generated(pitem
);
2289 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2290 pitem
= proto_tree_add_item(btavrcp_tree
, hf_btavrcp_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
2291 expert_add_info(pinfo
, pitem
, &ei_btavrcp_unexpected_data
);
2299 proto_register_btavrcp(void)
2302 expert_module_t
* expert_btavrcp
;
2304 static hf_register_info hf
[] = {
2305 { &hf_btavrcp_reserved
,
2306 { "Reserved", "btavrcp.reserved",
2307 FT_UINT8
, BASE_HEX
, NULL
, 0xF0,
2310 { &hf_btavrcp_ctype
,
2311 { "Ctype", "btavrcp.ctype",
2312 FT_UINT8
, BASE_HEX
, VALS(ctype_vals
), 0x0F,
2315 { &hf_btavrcp_subunit_type
,
2316 { "Subunit Type", "btavrcp.subunit_type",
2317 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2320 { &hf_btavrcp_subunit_id
,
2321 { "Subunit ID", "btavrcp.subunit_id",
2322 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2325 { &hf_btavrcp_opcode
,
2326 { "Opcode", "btavrcp.opcode",
2327 FT_UINT8
, BASE_HEX
, VALS(opcode_vals
), 0x00,
2330 { &hf_btavrcp_company_id
,
2331 { "Company ID", "btavrcp.company_id",
2332 FT_UINT24
, BASE_OUI
, NULL
, 0x00,
2335 { &hf_btavrcp_passthrough_state
,
2336 { "State", "btavrcp.passthrough.state",
2337 FT_UINT8
, BASE_HEX
, VALS(passthrough_state_vals
), 0x80,
2340 { &hf_btavrcp_passthrough_operation
,
2341 { "Operation ID", "btavrcp.passthrough.operation",
2342 FT_UINT8
, BASE_HEX
, VALS(passthrough_operation_vals
), 0x7F,
2345 { &hf_btavrcp_passthrough_data_length
,
2346 { "Data Length", "btavrcp.passthrough.length",
2347 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2350 { &hf_btavrcp_passthrough_vendor_unique_id
,
2351 { "Vendor Unique ID", "btavrcp.passthrough.vendor_unique_id",
2352 FT_UINT16
, BASE_HEX
, VALS(vendor_unique_id_vals
), 0x00,
2355 { &hf_btavrcp_passthrough_company_id
,
2356 { "Company ID", "btavrcp.passthrough.company_id",
2357 FT_UINT24
, BASE_OUI
, NULL
, 0x00,
2360 { &hf_btavrcp_unit_unknown
,
2361 { "Unknown", "btavrcp.unit.unknown",
2362 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2365 { &hf_btavrcp_unit_type
,
2366 { "Unit Type", "btavrcp.unit.type",
2367 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2370 { &hf_btavrcp_unit_id
,
2371 { "Subunit ID", "btavrcp.unit.id",
2372 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2375 { &hf_btavrcp_subunit_page
,
2376 { "Page", "btavrcp.subunit.page",
2377 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2380 { &hf_btavrcp_subunit_extension_code
,
2381 { "Extension Code", "btavrcp.subunit.extension_code",
2382 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2385 { &hf_btavrcp_bt_pdu_id
,
2386 { "PDU ID", "btavrcp.pdu_id",
2387 FT_UINT8
, BASE_HEX
, VALS(pdu_id_vals
), 0x00,
2390 { &hf_btavrcp_pdu_id
,
2391 { "PDU ID", "btavrcp.pdu_id",
2392 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2395 { &hf_btavrcp_bt_continuing_pdu_id
,
2396 { "Continuing PDU ID", "btavrcp.pdu_id",
2397 FT_UINT8
, BASE_HEX
, VALS(pdu_id_vals
), 0x00,
2400 { &hf_btavrcp_browsing_pdu_id
,
2401 { "PDU ID", "btavrcp.pdu_id",
2402 FT_UINT8
, BASE_HEX
, VALS(browsing_pdu_id_vals
), 0x00,
2406 { "RFA", "btavrcp.rfa",
2407 FT_UINT8
, BASE_HEX
, NULL
, 0xFC,
2410 { &hf_btavrcp_packet_type
,
2411 { "Packet Type", "btavrcp.packet_type",
2412 FT_UINT8
, BASE_HEX
, VALS(packet_type_vals
), 0x03,
2415 { &hf_btavrcp_length
,
2416 { "Parameter Length", "btavrcp.length",
2417 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2420 { &hf_btavrcp_player_id
,
2421 { "Player ID", "btavrcp.player_id",
2422 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2425 { &hf_btavrcp_status
,
2426 { "Status", "btavrcp.status",
2427 FT_UINT8
, BASE_HEX
, VALS(status_vals
), 0x00,
2430 { &hf_btavrcp_uid_counter
,
2431 { "UID Counter", "btavrcp.uid_counter",
2432 FT_UINT16
, BASE_HEX
, NULL
, 0x00,
2435 { &hf_btavrcp_character_set
,
2436 { "Character Set", "btavrcp.character_set",
2437 FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &mibenum_vals_character_sets_ext
, 0x00,
2440 { &hf_btavrcp_number_of_items
,
2441 { "Number Of Items", "btavrcp.number_of_items",
2442 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2443 "32bit number of items", HFILL
}
2445 { &hf_btavrcp_number_of_items16
,
2446 { "Number Of Items", "btavrcp.number_of_items",
2447 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2448 "16bit number of items", HFILL
}
2450 { &hf_btavrcp_folder_depth
,
2451 { "Folder Depth", "btavrcp.folder_depth",
2452 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2455 { &hf_btavrcp_folder_name_length
,
2456 { "Folder Name Length", "btavrcp.folder_name_length",
2457 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2460 { &hf_btavrcp_folder_name
,
2461 { "Folder Name", "btavrcp.folder_name",
2462 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2465 { &hf_btavrcp_search_length
,
2466 { "Search String Length", "btavrcp.search_length",
2467 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2470 { &hf_btavrcp_search
,
2471 { "Search String", "btavrcp.search",
2472 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2475 { &hf_btavrcp_number_of_attributes
,
2476 { "Number of Attributes", "btavrcp.number_of_attributes",
2477 FT_UINT8
, BASE_DEC
|BASE_SPECIAL_VALS
, VALS(unique_all_supported_attributes
), 0x00,
2480 { &hf_btavrcp_attribute_count
,
2481 { "Attribute Count", "btavrcp.attribute_count",
2482 FT_UINT8
, BASE_DEC
, VALS(attribute_count_vals
), 0x00,
2485 { &hf_btavrcp_direction
,
2486 { "Direction", "btavrcp.direction",
2487 FT_UINT8
, BASE_HEX
, VALS(direction_vals
), 0x00,
2490 { &hf_btavrcp_scope
,
2491 { "Scope", "btavrcp.scope",
2492 FT_UINT8
, BASE_HEX
, VALS(scope_vals
), 0x00,
2495 { &hf_btavrcp_start_item
,
2496 { "StartItem", "btavrcp.start_item",
2497 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2500 { &hf_btavrcp_end_item
,
2501 { "EndItem", "btavrcp.end_item",
2502 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2506 { "UID", "btavrcp.uid",
2507 FT_UINT64
, BASE_HEX
, NULL
, 0x00,
2510 { &hf_btavrcp_identifier
,
2511 { "Identifier", "btavrcp.identifier",
2512 FT_UINT64
, BASE_HEX
, NULL
, 0x00,
2515 { &hf_btavrcp_play_status
,
2516 { "Play Status", "btavrcp.play_status",
2517 FT_UINT8
, BASE_HEX
, VALS(play_status_vals
), 0x00,
2520 { &hf_btavrcp_song_length
,
2521 { "Song Length", "btavrcp.song_length",
2522 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2525 { &hf_btavrcp_song_position
,
2526 { "Song Position", "btavrcp.song_position",
2527 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2530 { &hf_btavrcp_notification_interval
,
2531 { "Interval", "btavrcp.notification.interval",
2532 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2535 { &hf_btavrcp_event_id
,
2536 { "Event ID", "btavrcp.notification.event_id",
2537 FT_UINT8
, BASE_HEX
, VALS(notification_vals
), 0x00,
2540 { &hf_btavrcp_battery_status
,
2541 { "Battery Status", "btavrcp.battery_status",
2542 FT_UINT8
, BASE_HEX
, VALS(battery_status_vals
), 0x00,
2545 { &hf_btavrcp_number_of_character_set
,
2546 { "Number of Character Set", "btavrcp.number_of_character_set",
2547 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2550 { &hf_btavrcp_absolute_volume_rfa
,
2551 { "RFA", "btavrcp.absoluter_volume_rfa",
2552 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2555 { &hf_btavrcp_absolute_volume
,
2556 { "Volume", "btavrcp.volume",
2557 FT_UINT8
, BASE_HEX
, NULL
, 0x7F,
2560 { &hf_btavrcp_capability
,
2561 { "Capability", "btavrcp.capability",
2562 FT_UINT8
, BASE_HEX
, VALS(capability_vals
), 0x00,
2565 { &hf_btavrcp_capability_count
,
2566 { "Capability Count", "btavrcp.capability.count",
2567 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2570 { &hf_btavrcp_item_type
,
2571 { "Item Type", "btavrcp.item.type",
2572 FT_UINT8
, BASE_HEX
, VALS(item_type_vals
), 0x00,
2575 { &hf_btavrcp_item_length
,
2576 { "Item Length", "btavrcp.item.length",
2577 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2581 { &hf_btavrcp_number_of_settings
,
2582 { "Number of Settings", "btavrcp.number_of_settings",
2583 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2586 { &hf_btavrcp_settings_attribute
,
2587 { "Setting Attribute", "btavrcp.settings.attribute",
2588 FT_UINT8
, BASE_HEX
, VALS(settings_vals
), 0x00,
2591 { &hf_btavrcp_settings_value
,
2592 { "Setting Value", "btavrcp.settings.value",
2593 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2596 { &hf_btavrcp_system_status
,
2597 { "System Status", "btavrcp.system_status",
2598 FT_UINT8
, BASE_HEX
, VALS(system_status_vals
), 0x00,
2601 { &hf_btavrcp_player_item
,
2602 { "Player", "btavrcp.player_item",
2603 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2606 { &hf_btavrcp_folder
,
2607 { "Folder", "btavrcp.folder",
2608 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2612 { "Item", "btavrcp.item",
2613 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2616 { &hf_btavrcp_features
,
2617 { "Features", "btavrcp.features",
2618 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2621 { &hf_btavrcp_not_used_features
,
2622 { "Not Used Features", "btavrcp.not_used_features",
2623 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2626 { &hf_btavrcp_attribute_list
,
2627 { "Attribute List", "btavrcp.attribute_list",
2628 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2631 { &hf_btavrcp_attribute_item
,
2632 { "Attribute", "btavrcp.attribute_item",
2633 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2636 { &hf_btavrcp_attribute_entries
,
2637 { "Attribute Entries", "btavrcp.attribute_entries",
2638 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2641 { &hf_btavrcp_attribute
,
2642 { "Attribute ID", "btavrcp.attribute",
2643 FT_UINT32
, BASE_HEX
, VALS(attribute_id_vals
), 0x00,
2646 { &hf_btavrcp_attribute_value_length
,
2647 { "Value Length", "btavrcp.value.length",
2648 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2651 { &hf_btavrcp_attribute_value
,
2652 { "Value", "btavrcp.value",
2653 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2656 { &hf_btavrcp_displayable_name_length
,
2657 { "Displayable Name Length", "btavrcp.displayable_name_length",
2658 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2661 { &hf_btavrcp_displayable_name
,
2662 { "Displayable Name", "btavrcp.displayable_name",
2663 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2666 { &hf_btavrcp_media_type
,
2667 { "Media Type", "btavrcp.media_type",
2668 FT_UINT8
, BASE_HEX
, VALS(media_type_vals
), 0x00,
2671 { &hf_btavrcp_folder_type
,
2672 { "Folder Type", "btavrcp.folder_type",
2673 FT_UINT8
, BASE_HEX
, VALS(folder_type_vals
), 0x00,
2676 { &hf_btavrcp_folder_playable
,
2677 { "Folder Playable", "btavrcp.folder_playable",
2678 FT_UINT8
, BASE_HEX
, VALS(folder_playable_vals
), 0x00,
2681 { &hf_btavrcp_major_player_type
,
2682 { "Major Player Type", "btavrcp.major_player_type",
2683 FT_UINT8
, BASE_HEX
, VALS(major_player_type_vals
), 0x00,
2686 { &hf_btavrcp_player_subtype
,
2687 { "Player SubType", "btavrcp.player_subtype",
2688 FT_UINT32
, BASE_HEX
, VALS(player_subtype_vals
), 0x00,
2691 { &hf_btavrcp_setting_value_length
,
2692 { "Value Length", "btavrcp.setting_value.length",
2693 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2696 { &hf_btavrcp_setting_value
,
2697 { "Value", "btavrcp.setting_value",
2698 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2701 { &hf_btavrcp_attribute_name_length
,
2702 { "Name Length", "btavrcp.attribute_name.length",
2703 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2706 { &hf_btavrcp_attribute_name
,
2707 { "Name", "btavrcp.attribute_name",
2708 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2712 { &hf_btavrcp_feature_reserved_0
,
2713 { "Feature Reserved", "btavrcp.feature.reserved",
2714 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2717 { &hf_btavrcp_feature_reserved_1
,
2718 { "Feature Reserved", "btavrcp.feature.reserved",
2719 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2722 { &hf_btavrcp_feature_reserved_2
,
2723 { "Feature Reserved", "btavrcp.feature.reserved",
2724 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2727 { &hf_btavrcp_feature_reserved_3
,
2728 { "Feature Reserved", "btavrcp.feature.reserved",
2729 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2732 { &hf_btavrcp_feature_reserved_4
,
2733 { "Feature Reserved", "btavrcp.feature.reserved",
2734 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2737 { &hf_btavrcp_feature_reserved_5
,
2738 { "Feature Reserved", "btavrcp.feature.reserved",
2739 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2742 { &hf_btavrcp_feature_reserved_6
,
2743 { "Feature Reserved", "btavrcp.feature.reserved",
2744 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2747 { &hf_btavrcp_feature_reserved_7
,
2748 { "Feature Reserved", "btavrcp.feature.reserved",
2749 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2752 { &hf_btavrcp_feature_passthrough_select
,
2753 { "PASSTHROUGH Select", "btavrcp.feature.passthrough.select",
2754 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2757 { &hf_btavrcp_feature_passthrough_up
,
2758 { "PASSTHROUGH Up", "btavrcp.feature.passthrough.up",
2759 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2762 { &hf_btavrcp_feature_passthrough_down
,
2763 { "PASSTHROUGH Down", "btavrcp.feature.passthrough.down",
2764 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2767 { &hf_btavrcp_feature_passthrough_left
,
2768 { "PASSTHROUGH Left", "btavrcp.feature.passthrough.left",
2769 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2772 { &hf_btavrcp_feature_passthrough_right
,
2773 { "PASSTHROUGH Right", "btavrcp.feature.passthrough.right",
2774 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2777 { &hf_btavrcp_feature_passthrough_right_up
,
2778 { "PASSTHROUGH Right Up", "btavrcp.feature.passthrough.right_up",
2779 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2782 { &hf_btavrcp_feature_passthrough_right_down
,
2783 { "PASSTHROUGH Right Down", "btavrcp.feature.passthrough.right_down",
2784 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2787 { &hf_btavrcp_feature_passthrough_left_up
,
2788 { "PASSTHROUGH Left Up", "btavrcp.feature.passthrough.left_up",
2789 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2792 { &hf_btavrcp_feature_passthrough_left_down
,
2793 { "PASSTHROUGH Left Down", "btavrcp.feature.passthrough.left_down",
2794 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2797 { &hf_btavrcp_feature_passthrough_root_menu
,
2798 { "PASSTHROUGH Root Menu", "btavrcp.feature.passthrough.root_menu",
2799 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2802 { &hf_btavrcp_feature_passthrough_setup_menu
,
2803 { "PASSTHROUGH Setup Menu", "btavrcp.feature.passthrough.setup_menu",
2804 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2807 { &hf_btavrcp_feature_passthrough_contents_menu
,
2808 { "PASSTHROUGH Contents Menu", "btavrcp.feature.passthrough.contents_menu",
2809 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2812 { &hf_btavrcp_feature_passthrough_favorite_menu
,
2813 { "PASSTHROUGH Favorite Menu", "btavrcp.feature.passthrough.favorite_menu",
2814 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2817 { &hf_btavrcp_feature_passthrough_exit
,
2818 { "PASSTHROUGH Exit", "btavrcp.feature.passthrough.exit",
2819 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2822 { &hf_btavrcp_feature_passthrough_0
,
2823 { "PASSTHROUGH 0", "btavrcp.feature.passthrough.0",
2824 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2827 { &hf_btavrcp_feature_passthrough_1
,
2828 { "PASSTHROUGH 1", "btavrcp.feature.passthrough.1",
2829 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2832 { &hf_btavrcp_feature_passthrough_2
,
2833 { "PASSTHROUGH 2", "btavrcp.feature.passthrough.2",
2834 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2837 { &hf_btavrcp_feature_passthrough_3
,
2838 { "PASSTHROUGH 3", "btavrcp.feature.passthrough.3",
2839 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2842 { &hf_btavrcp_feature_passthrough_4
,
2843 { "PASSTHROUGH 4", "btavrcp.feature.passthrough.4",
2844 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2847 { &hf_btavrcp_feature_passthrough_5
,
2848 { "PASSTHROUGH 5", "btavrcp.feature.passthrough.5",
2849 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2852 { &hf_btavrcp_feature_passthrough_6
,
2853 { "PASSTHROUGH 6", "btavrcp.feature.passthrough.6",
2854 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2857 { &hf_btavrcp_feature_passthrough_7
,
2858 { "PASSTHROUGH 7", "btavrcp.feature.passthrough.7",
2859 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2862 { &hf_btavrcp_feature_passthrough_8
,
2863 { "PASSTHROUGH 8", "btavrcp.feature.passthrough.8",
2864 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2867 { &hf_btavrcp_feature_passthrough_9
,
2868 { "PASSTHROUGH 9", "btavrcp.feature.passthrough.9",
2869 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2872 { &hf_btavrcp_feature_passthrough_dot
,
2873 { "PASSTHROUGH Dot", "btavrcp.feature.passthrough.dot",
2874 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2877 { &hf_btavrcp_feature_passthrough_enter
,
2878 { "PASSTHROUGH Enter", "btavrcp.feature.passthrough.enter",
2879 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2882 { &hf_btavrcp_feature_passthrough_clear
,
2883 { "PASSTHROUGH Clear", "btavrcp.feature.passthrough.clear",
2884 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2887 { &hf_btavrcp_feature_passthrough_channel_up
,
2888 { "PASSTHROUGH Channel Up", "btavrcp.feature.passthrough.channel_up",
2889 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2892 { &hf_btavrcp_feature_passthrough_channel_down
,
2893 { "PASSTHROUGH Channel Down", "btavrcp.feature.passthrough.channel_down",
2894 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2897 { &hf_btavrcp_feature_passthrough_previous_channel
,
2898 { "PASSTHROUGH Previous Channel", "btavrcp.feature.passthrough.previous_channel",
2899 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2902 { &hf_btavrcp_feature_passthrough_sound_select
,
2903 { "PASSTHROUGH Sound Select", "btavrcp.feature.passthrough.sound_select",
2904 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2907 { &hf_btavrcp_feature_passthrough_input_select
,
2908 { "PASSTHROUGH Input Select", "btavrcp.feature.passthrough.input_select",
2909 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2912 { &hf_btavrcp_feature_passthrough_display_information
,
2913 { "PASSTHROUGH Display Information", "btavrcp.feature.passthrough.display_information",
2914 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2917 { &hf_btavrcp_feature_passthrough_help
,
2918 { "PASSTHROUGH Help", "btavrcp.feature.passthrough.help",
2919 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2922 { &hf_btavrcp_feature_passthrough_page_up
,
2923 { "PASSTHROUGH Page Up", "btavrcp.feature.passthrough.page_up",
2924 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2927 { &hf_btavrcp_feature_passthrough_page_down
,
2928 { "PASSTHROUGH Page Down", "btavrcp.feature.passthrough.page_down",
2929 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2932 { &hf_btavrcp_feature_passthrough_power
,
2933 { "PASSTHROUGH Power", "btavrcp.feature.passthrough.power",
2934 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2937 { &hf_btavrcp_feature_passthrough_volume_up
,
2938 { "PASSTHROUGH Volume Up", "btavrcp.feature.passthrough.volume_up",
2939 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2942 { &hf_btavrcp_feature_passthrough_volume_down
,
2943 { "PASSTHROUGH Volume Down", "btavrcp.feature.passthrough.volume_down",
2944 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2947 { &hf_btavrcp_feature_passthrough_mute
,
2948 { "PASSTHROUGH Mute", "btavrcp.feature.passthrough.mute",
2949 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2952 { &hf_btavrcp_feature_passthrough_play
,
2953 { "PASSTHROUGH Play", "btavrcp.feature.passthrough.play",
2954 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2957 { &hf_btavrcp_feature_passthrough_stop
,
2958 { "PASSTHROUGH Stop", "btavrcp.feature.passthrough.stop",
2959 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2962 { &hf_btavrcp_feature_passthrough_pause
,
2963 { "PASSTHROUGH Pause", "btavrcp.feature.passthrough.pause",
2964 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2967 { &hf_btavrcp_feature_passthrough_record
,
2968 { "PASSTHROUGH Record", "btavrcp.feature.passthrough.record",
2969 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2972 { &hf_btavrcp_feature_passthrough_rewind
,
2973 { "PASSTHROUGH Rewind", "btavrcp.feature.passthrough.rewind",
2974 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2977 { &hf_btavrcp_feature_passthrough_fast_forward
,
2978 { "PASSTHROUGH FastForward", "btavrcp.feature.passthrough.fast_forward",
2979 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2982 { &hf_btavrcp_feature_passthrough_eject
,
2983 { "PASSTHROUGH Eject", "btavrcp.feature.passthrough.eject",
2984 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2987 { &hf_btavrcp_feature_passthrough_forward
,
2988 { "PASSTHROUGH Forward", "btavrcp.feature.passthrough.forward",
2989 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2992 { &hf_btavrcp_feature_passthrough_backward
,
2993 { "PASSTHROUGH Backward", "btavrcp.feature.passthrough.backward",
2994 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2997 { &hf_btavrcp_feature_passthrough_angle
,
2998 { "PASSTHROUGH Angle", "btavrcp.feature.passthrough.angle",
2999 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3002 { &hf_btavrcp_feature_passthrough_subpicture
,
3003 { "PASSTHROUGH SubPicture", "btavrcp.feature.passthrough.subpicture",
3004 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3007 { &hf_btavrcp_feature_passthrough_f1
,
3008 { "PASSTHROUGH F1", "btavrcp.feature.passthrough.f1",
3009 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
3012 { &hf_btavrcp_feature_passthrough_f2
,
3013 { "PASSTHROUGH F2", "btavrcp.feature.passthrough.f2",
3014 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
3017 { &hf_btavrcp_feature_passthrough_f3
,
3018 { "PASSTHROUGH F3", "btavrcp.feature.passthrough.f3",
3019 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
3022 { &hf_btavrcp_feature_passthrough_f4
,
3023 { "PASSTHROUGH F4", "btavrcp.feature.passthrough.f4",
3024 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
3027 { &hf_btavrcp_feature_passthrough_f5
,
3028 { "PASSTHROUGH F5", "btavrcp.feature.passthrough.f5",
3029 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
3032 { &hf_btavrcp_feature_vendor_unique
,
3033 { "Vendor Unique", "btavrcp.feature.vendor_unique",
3034 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
3037 { &hf_btavrcp_feature_basic_group_navigation
,
3038 { "Basic Group Navigation", "btavrcp.feature.basic_group_navigation",
3039 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3042 { &hf_btavrcp_feature_advanced_control_player
,
3043 { "Advanced Control Player", "btavrcp.feature.advanced_control_player",
3044 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3047 { &hf_btavrcp_feature_browsing
,
3048 { "Browsing", "btavrcp.feature.browsing",
3049 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
3052 { &hf_btavrcp_feature_searching
,
3053 { "Searching", "btavrcp.feature.searching",
3054 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
3057 { &hf_btavrcp_feature_addtonowplayer
,
3058 { "AddToNowPlaying", "btavrcp.feature.addtonowplaying",
3059 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
3062 { &hf_btavrcp_feature_uid_unique
,
3063 { "UID Unique", "btavrcp.feature.uid_unique",
3064 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
3067 { &hf_btavrcp_feature_only_browsable_when_addressed
,
3068 { "Only Browsable When Addressed", "btavrcp.feature.only_browsable_when_addressed",
3069 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
3072 { &hf_btavrcp_feature_only_searchable_when_addressed
,
3073 { "Only Searchable When Addressed", "btavrcp.feature.only_searchable_when_addressed",
3074 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
3077 { &hf_btavrcp_feature_nowplaying
,
3078 { "Nowplaying", "btavrcp.feature.nowplaying",
3079 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3082 { &hf_btavrcp_feature_uid_persistency
,
3083 { "UID Persistency", "btavrcp.feature.uid_persistency",
3084 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3087 { &hf_btavrcp_feature_number_of_items
,
3088 { "Number of Items", "btavrcp.feature.number_of_items",
3089 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
3092 { &hf_btavrcp_feature_cover_art
,
3093 { "Cover Art", "btavrcp.feature.cover_art",
3094 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
3097 /* end of features */
3098 { &hf_btavrcp_current_path
,
3099 { "Current Path", "btavrcp.current_path",
3100 FT_NONE
, BASE_NONE
, NULL
, 0x00,
3103 { &hf_btavrcp_reassembled
,
3104 { "Reassembled", "btavrcp.reassembled",
3105 FT_NONE
, BASE_NONE
, NULL
, 0x00,
3108 { &hf_btavrcp_response_time
,
3109 { "Response Time", "btavrcp.response_time",
3110 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
3113 { &hf_btavrcp_command_in_frame
,
3114 { "Command in frame", "btavrcp.command_in_frame",
3115 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x00,
3118 { &hf_btavrcp_response_in_frame
,
3119 { "Response in frame", "btavrcp.response_in_frame",
3120 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x00,
3124 { "Data", "btavrcp.data",
3125 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3130 static int *ett
[] = {
3132 &ett_btavrcp_attribute_list
,
3133 &ett_btavrcp_attribute_entry
,
3134 &ett_btavrcp_attribute_entries
,
3135 &ett_btavrcp_element
,
3136 &ett_btavrcp_player
,
3137 &ett_btavrcp_features
,
3138 &ett_btavrcp_features_not_used
,
3139 &ett_btavrcp_folder
,
3143 static ei_register_info ei
[] = {
3144 { &ei_btavrcp_item_length_bad
, { "btavrcp.item.length.bad", PI_PROTOCOL
, PI_WARN
, "Item length does not correspond to sum of length of attributes", EXPFILL
}},
3145 { &ei_btavrcp_unexpected_data
, { "btavrcp.unexpected_data", PI_PROTOCOL
, PI_WARN
, "Unexpected data", EXPFILL
}},
3146 { &ei_btavrcp_no_response
, { "btavrcp.no_response", PI_PROTOCOL
, PI_WARN
, "No response", EXPFILL
}},
3149 reassembling
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3150 timing
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3151 btavrcp_song_positions
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3153 proto_btavrcp
= proto_register_protocol("Bluetooth AVRCP Profile", "BT AVRCP", "btavrcp");
3154 btavrcp_handle
= register_dissector("btavrcp", dissect_btavrcp
, proto_btavrcp
);
3156 proto_register_field_array(proto_btavrcp
, hf
, array_length(hf
));
3157 proto_register_subtree_array(ett
, array_length(ett
));
3158 expert_btavrcp
= expert_register_protocol(proto_btavrcp
);
3159 expert_register_field_array(expert_btavrcp
, ei
, array_length(ei
));
3161 module
= prefs_register_protocol_subtree("Bluetooth", proto_btavrcp
, NULL
);
3162 prefs_register_static_text_preference(module
, "avrcp.version",
3163 "Bluetooth Profile AVRCP version: 1.5",
3164 "Version of profile supported by this dissector.");
3168 proto_reg_handoff_btavrcp(void)
3170 dissector_add_string("bluetooth.uuid", "110c", btavrcp_handle
);
3171 dissector_add_string("bluetooth.uuid", "110e", btavrcp_handle
);
3172 dissector_add_string("bluetooth.uuid", "110f", btavrcp_handle
);
3177 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3182 * indent-tabs-mode: nil
3185 * vi: set shiftwidth=4 tabstop=8 expandtab:
3186 * :indentSize=4:tabSize=8:noTabs=true: