2 * Routines for Bluetooth AVRCP dissection
4 * Copyright 2012, Michal Labedzki for Tieto Corporation
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include <epan/prefs.h>
31 #include <epan/expert.h>
33 #include <epan/wmem/wmem.h>
35 #include "packet-wap.h"
36 #include "packet-btl2cap.h"
37 #include "packet-btsdp.h"
38 #include "packet-btavctp.h"
40 static int proto_btavrcp
= -1;
42 static int hf_btavrcp_rfa
= -1;
43 static int hf_btavrcp_ctype
= -1;
44 static int hf_btavrcp_subunit_type
= -1;
45 static int hf_btavrcp_subunit_id
= -1;
46 static int hf_btavrcp_opcode
= -1;
47 static int hf_btavrcp_company_id
= -1;
48 static int hf_btavrcp_length
= -1;
49 static int hf_btavrcp_pdu_id
= -1;
50 static int hf_btavrcp_bt_pdu_id
= -1;
51 static int hf_btavrcp_bt_continuing_pdu_id
= -1;
52 static int hf_btavrcp_browsing_pdu_id
= -1;
53 static int hf_btavrcp_reserved
= -1;
54 static int hf_btavrcp_packet_type
= -1;
55 static int hf_btavrcp_passthrough_state
= -1;
56 static int hf_btavrcp_passthrough_operation
= -1;
57 static int hf_btavrcp_passthrough_data_length
= -1;
58 static int hf_btavrcp_passthrough_company_id
= -1;
59 static int hf_btavrcp_passthrough_vendor_unique_id
= -1;
60 static int hf_btavrcp_unit_unknown
= -1;
61 static int hf_btavrcp_unit_type
= -1;
62 static int hf_btavrcp_unit_id
= -1;
63 static int hf_btavrcp_subunit_page
= -1;
64 static int hf_btavrcp_subunit_extention_code
= -1;
65 static int hf_btavrcp_item
= -1;
66 static int hf_btavrcp_folder
= -1;
67 static int hf_btavrcp_player_id
= -1;
68 static int hf_btavrcp_status
= -1;
69 static int hf_btavrcp_uid_counter
= -1;
70 static int hf_btavrcp_number_of_items
= -1;
71 static int hf_btavrcp_number_of_items16
= -1;
72 static int hf_btavrcp_character_set
= -1;
73 static int hf_btavrcp_folder_depth
= -1;
74 static int hf_btavrcp_folder_name_length
= -1;
75 static int hf_btavrcp_folder_name
= -1;
76 static int hf_btavrcp_search
= -1;
77 static int hf_btavrcp_search_length
= -1;
78 static int hf_btavrcp_number_of_attributes
= -1;
79 static int hf_btavrcp_uid
= -1;
80 static int hf_btavrcp_scope
= -1;
81 static int hf_btavrcp_start_item
= -1;
82 static int hf_btavrcp_end_item
= -1;
83 static int hf_btavrcp_direction
= -1;
84 static int hf_btavrcp_identifier
= -1;
85 static int hf_btavrcp_song_length
= -1;
86 static int hf_btavrcp_song_position
= -1;
87 static int hf_btavrcp_play_status
= -1;
88 static int hf_btavrcp_notification_interval
= -1;
89 static int hf_btavrcp_event_id
= -1;
90 static int hf_btavrcp_battery_status
= -1;
91 static int hf_btavrcp_number_of_character_set
= -1;
92 static int hf_btavrcp_absolute_volume_rfa
= -1;
93 static int hf_btavrcp_absolute_volume
= -1;
94 static int hf_btavrcp_capability
= -1;
95 static int hf_btavrcp_capability_count
= -1;
96 static int hf_btavrcp_item_type
= -1;
97 static int hf_btavrcp_item_length
= -1;
98 static int hf_btavrcp_system_status
= -1;
99 static int hf_btavrcp_number_of_settings
= -1;
100 static int hf_btavrcp_settings_attribute
= -1;
101 static int hf_btavrcp_settings_value
= -1;
102 static int hf_btavrcp_displayable_name
= -1;
103 static int hf_btavrcp_displayable_name_length
= -1;
104 static int hf_btavrcp_media_type
= -1;
105 static int hf_btavrcp_folder_type
= -1;
106 static int hf_btavrcp_folder_playable
= -1;
107 static int hf_btavrcp_major_player_type
= -1;
108 static int hf_btavrcp_player_subtype
= -1;
109 static int hf_btavrcp_player_item
= -1;
110 static int hf_btavrcp_attribute
= -1;
111 static int hf_btavrcp_attribute_count
= -1;
112 static int hf_btavrcp_attribute_value
= -1;
113 static int hf_btavrcp_attribute_value_length
= -1;
114 static int hf_btavrcp_attribute_item
= -1;
115 static int hf_btavrcp_attribute_list
= -1;
116 static int hf_btavrcp_attribute_entries
= -1;
117 static int hf_btavrcp_attribute_name_length
= -1;
118 static int hf_btavrcp_attribute_name
= -1;
119 static int hf_btavrcp_setting_value_length
= -1;
120 static int hf_btavrcp_setting_value
= -1;
121 static int hf_btavrcp_features
= -1;
122 static int hf_btavrcp_not_used_features
= -1;
123 static int hf_btavrcp_feature_reserved_0
= -1;
124 static int hf_btavrcp_feature_reserved_1
= -1;
125 static int hf_btavrcp_feature_reserved_2
= -1;
126 static int hf_btavrcp_feature_reserved_3
= -1;
127 static int hf_btavrcp_feature_reserved_4
= -1;
128 static int hf_btavrcp_feature_reserved_5
= -1;
129 static int hf_btavrcp_feature_reserved_6
= -1;
130 static int hf_btavrcp_feature_reserved_7
= -1;
131 static int hf_btavrcp_feature_passthrough_select
= -1;
132 static int hf_btavrcp_feature_passthrough_up
= -1;
133 static int hf_btavrcp_feature_passthrough_down
= -1;
134 static int hf_btavrcp_feature_passthrough_left
= -1;
135 static int hf_btavrcp_feature_passthrough_right
= -1;
136 static int hf_btavrcp_feature_passthrough_right_up
= -1;
137 static int hf_btavrcp_feature_passthrough_right_down
= -1;
138 static int hf_btavrcp_feature_passthrough_left_up
= -1;
139 static int hf_btavrcp_feature_passthrough_left_down
= -1;
140 static int hf_btavrcp_feature_passthrough_root_menu
= -1;
141 static int hf_btavrcp_feature_passthrough_setup_menu
= -1;
142 static int hf_btavrcp_feature_passthrough_contents_menu
= -1;
143 static int hf_btavrcp_feature_passthrough_favorite_menu
= -1;
144 static int hf_btavrcp_feature_passthrough_exit
= -1;
145 static int hf_btavrcp_feature_passthrough_0
= -1;
146 static int hf_btavrcp_feature_passthrough_1
= -1;
147 static int hf_btavrcp_feature_passthrough_2
= -1;
148 static int hf_btavrcp_feature_passthrough_3
= -1;
149 static int hf_btavrcp_feature_passthrough_4
= -1;
150 static int hf_btavrcp_feature_passthrough_5
= -1;
151 static int hf_btavrcp_feature_passthrough_6
= -1;
152 static int hf_btavrcp_feature_passthrough_7
= -1;
153 static int hf_btavrcp_feature_passthrough_8
= -1;
154 static int hf_btavrcp_feature_passthrough_9
= -1;
155 static int hf_btavrcp_feature_passthrough_dot
= -1;
156 static int hf_btavrcp_feature_passthrough_enter
= -1;
157 static int hf_btavrcp_feature_passthrough_clear
= -1;
158 static int hf_btavrcp_feature_passthrough_channel_up
= -1;
159 static int hf_btavrcp_feature_passthrough_channel_down
= -1;
160 static int hf_btavrcp_feature_passthrough_previous_channel
= -1;
161 static int hf_btavrcp_feature_passthrough_sound_select
= -1;
162 static int hf_btavrcp_feature_passthrough_input_select
= -1;
163 static int hf_btavrcp_feature_passthrough_display_information
= -1;
164 static int hf_btavrcp_feature_passthrough_help
= -1;
165 static int hf_btavrcp_feature_passthrough_page_up
= -1;
166 static int hf_btavrcp_feature_passthrough_page_down
= -1;
167 static int hf_btavrcp_feature_passthrough_power
= -1;
168 static int hf_btavrcp_feature_passthrough_volume_up
= -1;
169 static int hf_btavrcp_feature_passthrough_volume_down
= -1;
170 static int hf_btavrcp_feature_passthrough_mute
= -1;
171 static int hf_btavrcp_feature_passthrough_play
= -1;
172 static int hf_btavrcp_feature_passthrough_stop
= -1;
173 static int hf_btavrcp_feature_passthrough_pause
= -1;
174 static int hf_btavrcp_feature_passthrough_record
= -1;
175 static int hf_btavrcp_feature_passthrough_rewind
= -1;
176 static int hf_btavrcp_feature_passthrough_fast_forward
= -1;
177 static int hf_btavrcp_feature_passthrough_eject
= -1;
178 static int hf_btavrcp_feature_passthrough_forward
= -1;
179 static int hf_btavrcp_feature_passthrough_backward
= -1;
180 static int hf_btavrcp_feature_passthrough_angle
= -1;
181 static int hf_btavrcp_feature_passthrough_subpicture
= -1;
182 static int hf_btavrcp_feature_passthrough_f1
= -1;
183 static int hf_btavrcp_feature_passthrough_f2
= -1;
184 static int hf_btavrcp_feature_passthrough_f3
= -1;
185 static int hf_btavrcp_feature_passthrough_f4
= -1;
186 static int hf_btavrcp_feature_passthrough_f5
= -1;
187 static int hf_btavrcp_feature_vendor_unique
= -1;
188 static int hf_btavrcp_feature_basic_group_navigation
= -1;
189 static int hf_btavrcp_feature_advanced_control_player
= -1;
190 static int hf_btavrcp_feature_browsing
= -1;
191 static int hf_btavrcp_feature_searching
= -1;
192 static int hf_btavrcp_feature_addtonowplayer
= -1;
193 static int hf_btavrcp_feature_uid_unique
= -1;
194 static int hf_btavrcp_feature_only_browsable_when_addressed
= -1;
195 static int hf_btavrcp_feature_only_searchable_when_addressed
= -1;
196 static int hf_btavrcp_feature_nowplaying
= -1;
197 static int hf_btavrcp_feature_uid_persistency
= -1;
198 static int hf_btavrcp_reassembled
= -1;
199 static int hf_btavrcp_currect_path
= -1;
200 static int hf_btavrcp_response_time
= -1;
201 static int hf_btavrcp_data
= -1;
203 static gint ett_btavrcp
= -1;
204 static gint ett_btavrcp_attribute_list
= -1;
205 static gint ett_btavrcp_attribute_entry
= -1;
206 static gint ett_btavrcp_attribute_entries
= -1;
207 static gint ett_btavrcp_element
= -1;
208 static gint ett_btavrcp_folder
= -1;
209 static gint ett_btavrcp_player
= -1;
210 static gint ett_btavrcp_features
= -1;
211 static gint ett_btavrcp_features_not_used
= -1;
212 static gint ett_btavrcp_path
= -1;
214 static expert_field ei_btavrcp_item_length_bad
= EI_INIT
;
215 static expert_field ei_btavrcp_unexpected_data
= EI_INIT
;
217 #define OPCODE_VENDOR_DEPENDANT 0x00
218 #define OPCODE_UNIT 0x30
219 #define OPCODE_SUBUNIT 0x31
220 #define OPCODE_PASSTHROUGH 0x7C
222 #define ITEM_MEDIAPLAYER 0x01
223 #define ITEM_FOLDER 0x02
224 #define ITEM_MEDIA_ELEMENT 0x03
226 #define PACKET_TYPE_SINGLE 0x00
227 #define PACKET_TYPE_START 0x01
228 #define PACKET_TYPE_CONTINUE 0x02
229 #define PACKET_TYPE_END 0x03
231 #define EVENT_PLAYBACK_STATUS_CHANGED 0x01
232 #define EVENT_TRACK_CHANGED 0x02
233 #define EVENT_TRACK_REACHED_END 0x03
234 #define EVENT_TRACK_REACHED_START 0x04
235 #define EVENT_PLAYBACK_POSITION_CHANGED 0x05
236 #define EVENT_BATTERY_STATUS_CHANGED 0x06
237 #define EVENT_SYSTEM_STATUS_CHANGED 0x07
238 #define EVENT_PLAYER_APPLICATION_SETTING_CHANGED 0x08
239 #define EVENT_NOWPLAYING_CONTENT_CHANGED 0x09
240 #define EVENT_AVAILABLE_PLAYERS_CHANGED 0x0A
241 #define EVENT_ADDRESSEDPLAYER_CHANGED 0x0B
242 #define EVENT_UIDS_CHANGED 0x0C
243 #define EVENT_VOLUME_CHANGED 0x0D
245 #define PDU_GET_CAPABILITIES 0x10
246 #define PDU_LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES 0x11
247 #define PDU_LIST_PLAYER_APPLICATION_SETTING_VALUE 0x12
248 #define PDU_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE 0x13
249 #define PDU_SET_PLAYER_APPLICATION_SETTING_VALUE 0x14
250 #define PDU_GET_PLAYER_APPLICATION_SETTING_ATTRIBUTE_TEXT 0x15
251 #define PDU_GET_PLAYER_APPLICATION_SETTING_VALUE_TEXT 0x16
252 #define PDU_INFORM_DISPLAYABLE_CHARACTER_SET 0x17
253 #define PDU_INFORM_BATTERY_STATUS_OF_CT 0x18
254 #define PDU_GET_ELEMENT_ATTRIBUTES 0x20
255 #define PDU_GET_PLAY_STATUS 0x30
256 #define PDU_REGISTER_NOTIFICATION 0x31
257 #define PDU_REQUEST_CONTINUING_RESPONSE 0x40
258 #define PDU_ABORT_CONTINUING_RESPONSE 0x41
259 #define PDU_SET_ABSOLUTE_VOLUME 0x50
260 #define PDU_SET_ADDRESSED_PLAYER 0x60
261 #define PDU_SET_BROWSED_PLAYER 0x70
262 #define PDU_GET_FOLDER_ITEMS 0x71
263 #define PDU_CHANGE_PATH 0x72
264 #define PDU_GET_ITEM_ATTRIBUTES 0x73
265 #define PDU_PLAY_ITEM 0x74
266 #define PDU_SEARCH 0x80
267 #define PDU_ADD_TO_NOW_PLAYING 0x90
268 #define PDU_GENERAL_REJECT 0xA0
270 #define STATUS_OK 0x04
272 static wmem_tree_t
*reassembling
= NULL
;
273 static wmem_tree_t
*timing
= NULL
;
275 typedef struct _fragment
{
276 guint start_frame_number
;
277 guint end_frame_number
;
278 guint32 interface_id
;
285 wmem_tree_t
*fragments
;
288 typedef struct _data_fragment_t
{
293 typedef struct _timing_info
{
294 guint command_frame_number
;
295 nstime_t command_timestamp
;
296 guint response_frame_number
;
297 nstime_t response_timestamp
;
298 guint max_response_time
;
300 guint32 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_DEPENDANT
, "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, "Revrse 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 { 0x00, "Audio Book" },
589 void proto_register_btavrcp(void);
590 void proto_reg_handoff_btavrcp(void);
593 dissect_attribute_id_list(tvbuff_t
*tvb
, proto_tree
*tree
, gint offset
,
600 pitem
= proto_tree_add_item(tree
, hf_btavrcp_attribute_list
, tvb
, offset
, count
* 4, ENC_NA
);
601 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_attribute_list
);
603 for (i_attribute
= 0; i_attribute
< count
; ++i_attribute
) {
604 proto_tree_add_item(ptree
, hf_btavrcp_attribute
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
613 dissect_attribute_entries(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
614 gint offset
, guint count
)
621 proto_item
*pitem
= NULL
;
622 proto_tree
*ptree
= NULL
;
623 proto_item
*entry_item
= NULL
;
624 proto_tree
*entry_tree
= NULL
;
627 for (i_entry
= 0; i_entry
< count
; ++i_entry
) {
628 length
+= 4 + 2 + 2 + tvb_get_ntohs(tvb
, offset
+ length
+ 4 + 2);
631 pitem
= proto_tree_add_item(tree
, hf_btavrcp_attribute_entries
, tvb
, offset
, length
, ENC_NA
);
632 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_attribute_entries
);
634 for (i_entry
= 0; i_entry
< count
; ++i_entry
) {
635 attribute_id
= tvb_get_ntohl(tvb
, offset
);
636 value_length
= tvb_get_ntohs(tvb
, offset
+ 4 + 2);
637 value
= tvb_get_string(NULL
, tvb
, offset
+ 4 + 2 + 2, value_length
);
639 if (attribute_id
== 0x01) col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Title: \"%s\"", value
);
641 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
);
642 entry_tree
= proto_item_add_subtree(entry_item
, ett_btavrcp_attribute_entry
);
644 proto_tree_add_item(entry_tree
, hf_btavrcp_attribute
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
646 proto_tree_add_item(entry_tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
648 proto_tree_add_item(entry_tree
, hf_btavrcp_setting_value_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
650 proto_tree_add_item(entry_tree
, hf_btavrcp_setting_value
, tvb
, offset
, value_length
, ENC_UTF_8
| ENC_NA
);
651 offset
+= value_length
;
659 dissect_item_mediaplayer(tvbuff_t
*tvb
, proto_tree
*tree
, gint offset
)
661 guint displayable_name_length
;
665 guint8
*displayable_name
;
668 proto_item
*features_item
;
669 proto_tree
*features_tree
;
670 proto_item
*features_not_set_item
;
671 proto_tree
*features_not_set_tree
;
673 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
674 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 1 + 1 + 4 + 16 + 1 + 2);
675 displayable_name
= tvb_get_string(NULL
, tvb
, offset
+ 1 + 2 + 1 + 1 + 4 + 16 + 1 + 2 + 2, displayable_name_length
);
677 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_player_item
, tvb
, offset
, 1 + 2 + item_length
, "Player: %s", displayable_name
);
678 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_player
);
680 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
682 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
685 proto_tree_add_item(ptree
, hf_btavrcp_player_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
688 proto_tree_add_item(ptree
, hf_btavrcp_major_player_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
691 proto_tree_add_item(ptree
, hf_btavrcp_player_subtype
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
694 /* feature bit mask */
695 features_item
= proto_tree_add_item(ptree
, hf_btavrcp_features
, tvb
, offset
, 16, ENC_NA
);
696 features_tree
= proto_item_add_subtree(features_item
, ett_btavrcp_features
);
698 features_not_set_item
= proto_tree_add_item(features_tree
, hf_btavrcp_not_used_features
, tvb
, offset
, 16, ENC_NA
);
699 features_not_set_tree
= proto_item_add_subtree(features_not_set_item
, ett_btavrcp_features_not_used
);
701 feature_octet
= tvb_get_guint8(tvb
, offset
+ 0);
702 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
);
703 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
);
704 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
);
705 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
);
706 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
);
707 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
);
708 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
);
709 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
);
711 feature_octet
= tvb_get_guint8(tvb
, offset
+ 1);
712 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
);
713 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
);
714 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
);
715 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
);
716 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
);
717 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
);
718 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
);
719 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
);
721 feature_octet
= tvb_get_guint8(tvb
, offset
+ 2);
722 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
);
723 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
);
724 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
);
725 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
);
726 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
);
727 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
);
728 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
);
729 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
);
731 feature_octet
= tvb_get_guint8(tvb
, offset
+ 3);
732 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
);
733 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
);
734 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
);
735 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
);
736 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
);
737 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
);
738 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
);
739 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
);
741 feature_octet
= tvb_get_guint8(tvb
, offset
+ 4);
742 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
);
743 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
);
744 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
);
745 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
);
746 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
);
747 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
);
748 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
);
749 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
);
751 feature_octet
= tvb_get_guint8(tvb
, offset
+ 5);
752 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
);
753 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
);
754 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
);
755 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
);
756 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
);
757 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
);
758 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
);
759 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
);
761 feature_octet
= tvb_get_guint8(tvb
, offset
+ 6);
762 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
);
763 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
);
764 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
);
765 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
);
766 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
);
767 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
);
768 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
);
769 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
);
771 feature_octet
= tvb_get_guint8(tvb
, offset
+ 7);
772 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
);
773 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
);
774 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
);
775 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
);
776 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
);
777 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
);
778 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
);
779 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
);
781 feature_octet
= tvb_get_guint8(tvb
, offset
+ 8);
782 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
);
783 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
);
784 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
);
787 proto_tree_add_item((feature_octet
& (1 << 3)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_3
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
788 proto_tree_add_item((feature_octet
& (1 << 4)) ? features_tree
: features_not_set_tree
, hf_btavrcp_feature_reserved_4
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
789 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
);
790 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
);
791 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
);
793 for (i_feature
= 9; i_feature
<= 16; ++i_feature
) {
794 feature_octet
= tvb_get_guint8(tvb
, offset
+ i_feature
);
795 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
);
796 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
);
797 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
);
798 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
);
799 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
);
800 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
);
801 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
);
802 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
);
806 proto_tree_add_item(ptree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
809 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
812 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
813 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
816 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
817 offset
+= displayable_name_length
;
824 dissect_item_media_element(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
827 guint number_of_attributes
;
828 guint displayable_name_length
;
830 guint8
*displayable_name
;
835 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
836 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 8 + 1 + 2);
837 displayable_name
= tvb_get_string(NULL
, tvb
, offset
+ 1 + 2 + 8 + 1 + 2 + 2, displayable_name_length
);
839 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_item
, tvb
, offset
, 1 + 2 + item_length
, "Element: %s", displayable_name
);
840 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_element
);
842 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
844 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
848 proto_tree_add_item(ptree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
851 proto_tree_add_item(ptree
, hf_btavrcp_media_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
854 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
857 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
858 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
861 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
862 offset
+= displayable_name_length
;
864 proto_tree_add_item(ptree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
865 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
868 offset
= dissect_attribute_entries(tvb
, pinfo
, ptree
, offset
, number_of_attributes
);
870 if ( item_length
!= (guint
) offset
- offset_in
) {
871 expert_add_info(pinfo
, pitem
, &ei_btavrcp_item_length_bad
);
879 dissect_item_folder(tvbuff_t
*tvb
, proto_tree
*tree
, gint offset
)
881 guint displayable_name_length
;
883 guint8
*displayable_name
;
887 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
888 displayable_name_length
= tvb_get_ntohs(tvb
, offset
+ 1 + 2 + 8 + 1 + 1 + 2);
889 displayable_name
= tvb_get_string(NULL
, tvb
, offset
+ 1 + 2 + 8 + 1 + 1 + 2 + 2, displayable_name_length
);
891 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_folder
, tvb
, offset
, 1 + 2 + item_length
, "Folder : %s", displayable_name
);
892 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_folder
);
894 proto_tree_add_item(ptree
, hf_btavrcp_item_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
896 proto_tree_add_item(ptree
, hf_btavrcp_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
899 proto_tree_add_item(ptree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
902 proto_tree_add_item(ptree
, hf_btavrcp_folder_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
905 proto_tree_add_item(ptree
, hf_btavrcp_folder_playable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
908 proto_tree_add_item(ptree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
911 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
912 displayable_name_length
= tvb_get_ntohs(tvb
, offset
);
915 proto_tree_add_item(ptree
, hf_btavrcp_displayable_name
, tvb
, offset
, displayable_name_length
, ENC_UTF_8
| ENC_NA
);
916 offset
+= displayable_name_length
;
923 dissect_passthrough(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
924 gint offset
, gboolean is_command
, guint32
*op
)
929 proto_tree_add_item(tree
, hf_btavrcp_passthrough_state
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
930 proto_tree_add_item(tree
, hf_btavrcp_passthrough_operation
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
931 *op
= tvb_get_guint8(tvb
, offset
);
932 operation
= tvb_get_guint8(tvb
, offset
) & 0x7F;
933 state
= (tvb_get_guint8(tvb
, offset
) & 0x80) >> 7;
935 proto_tree_add_item(tree
, hf_btavrcp_passthrough_data_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
939 if (operation
== 0x7E) {
940 proto_tree_add_item(tree
, hf_btavrcp_passthrough_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
942 proto_tree_add_item(tree
, hf_btavrcp_passthrough_vendor_unique_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
947 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s (%s)",
948 val_to_str_const(operation
, passthrough_operation_vals
, "Unknown opcode"),
949 val_to_str_const(state
, passthrough_state_vals
, "unknown"));
955 dissect_unit(tvbuff_t
*tvb
, proto_tree
*tree
, gint offset
, gboolean is_command
)
958 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 5, ENC_NA
);
961 proto_tree_add_item(tree
, hf_btavrcp_unit_unknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
963 proto_tree_add_item(tree
, hf_btavrcp_unit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
964 proto_tree_add_item(tree
, hf_btavrcp_unit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
966 proto_tree_add_item(tree
, hf_btavrcp_passthrough_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
975 dissect_subunit(tvbuff_t
*tvb
, proto_tree
*tree
, gint offset
, gboolean is_command
)
977 proto_tree_add_item(tree
, hf_btavrcp_subunit_page
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
978 proto_tree_add_item(tree
, hf_btavrcp_subunit_extention_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
982 proto_tree_add_item(tree
, hf_btavrcp_subunit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
983 proto_tree_add_item(tree
, hf_btavrcp_subunit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
985 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 3, ENC_NA
);
988 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, 4, ENC_NA
);
997 dissect_vendor_dependant(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
998 gint offset
, guint ctype
, guint32
*op
, guint32
*op_arg
,
999 gboolean is_command
, btavctp_data_t
*avctp_data
)
1006 guint parameter_length
;
1008 wmem_tree_key_t key
[7];
1009 guint32 k_interface_id
;
1010 guint32 k_adapter_id
;
1014 guint32 k_frame_number
;
1015 guint32 interface_id
;
1020 guint volume_percent
;
1021 fragment_t
*fragment
;
1022 data_fragment_t
*data_fragment
;
1026 interface_id
= avctp_data
->interface_id
;
1027 adapter_id
= avctp_data
->adapter_id
;
1028 chandle
= avctp_data
->chandle
;
1029 psm
= avctp_data
->psm
;
1031 proto_tree_add_item(tree
, hf_btavrcp_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1032 company_id
= tvb_get_ntoh24(tvb
, offset
);
1035 if (company_id
== OUI_BLUETOOTH
) {
1036 proto_tree_add_item(tree
, hf_btavrcp_bt_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1039 if (tvb_length_remaining(tvb
, offset
) == 0) {
1040 col_append_str(pinfo
->cinfo
, COL_INFO
, " - No PDU ID");
1044 proto_tree_add_item(tree
, hf_btavrcp_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1046 pdu_id
= tvb_get_guint8(tvb
, offset
);
1047 *op
= pdu_id
| (company_id
<< 8);
1050 if (company_id
!= OUI_BLUETOOTH
) {
1051 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1052 val_to_str_const(pdu_id
, NULL
, "Unknown PDU ID"));
1055 proto_tree_add_item(tree
, hf_btavrcp_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1056 proto_tree_add_item(tree
, hf_btavrcp_packet_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1057 packet_type
= tvb_get_guint8(tvb
, offset
) & 0x03;
1060 proto_tree_add_item(tree
, hf_btavrcp_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1061 parameter_length
= tvb_get_ntohs(tvb
, offset
);
1064 if (company_id
!= OUI_BLUETOOTH
)
1067 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1068 val_to_str_const(pdu_id
, pdu_id_vals
, "Unknown PDU ID"));
1070 if (parameter_length
== 0) return offset
;
1072 length
= tvb_ensure_length_remaining(tvb
, offset
);
1073 if (packet_type
== PACKET_TYPE_START
) {
1074 if (pinfo
->fd
->flags
.visited
== 0) {
1075 k_interface_id
= interface_id
;
1076 k_adapter_id
= adapter_id
;
1077 k_chandle
= chandle
;
1079 k_op
= pdu_id
| (company_id
<< 8);
1080 k_frame_number
= pinfo
->fd
->num
;
1082 fragment
= wmem_new(wmem_file_scope(), fragment_t
);
1083 fragment
->start_frame_number
= pinfo
->fd
->num
;
1084 fragment
->end_frame_number
= 0;
1085 fragment
->state
= 0;
1087 fragment
->count
= 1;
1088 fragment
->fragments
= wmem_tree_new(wmem_file_scope());
1090 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1091 data_fragment
->length
= length
;
1092 data_fragment
->data
= (guint8
*) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1093 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1095 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1098 key
[0].key
= &k_interface_id
;
1100 key
[1].key
= &k_adapter_id
;
1102 key
[2].key
= &k_chandle
;
1104 key
[3].key
= &k_psm
;
1108 key
[5].key
= &k_frame_number
;
1112 fragment
->interface_id
= interface_id
;
1113 fragment
->adapter_id
= adapter_id
;
1114 fragment
->chandle
= chandle
;
1115 fragment
->psm
= psm
;
1116 fragment
->op
= pdu_id
| (company_id
<< 8);
1118 wmem_tree_insert32_array(reassembling
, key
, fragment
);
1121 col_append_str(pinfo
->cinfo
, COL_INFO
, " [start]");
1123 } else if (packet_type
== PACKET_TYPE_CONTINUE
) {
1124 if (pinfo
->fd
->flags
.visited
== 0) {
1125 k_interface_id
= interface_id
;
1126 k_adapter_id
= adapter_id
;
1127 k_chandle
= chandle
;
1129 k_op
= pdu_id
| (company_id
<< 8);
1130 k_frame_number
= pinfo
->fd
->num
;
1133 key
[0].key
= &k_interface_id
;
1135 key
[1].key
= &k_adapter_id
;
1137 key
[2].key
= &k_chandle
;
1139 key
[3].key
= &k_psm
;
1143 key
[5].key
= &k_frame_number
;
1147 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1148 if (fragment
&& fragment
->interface_id
== interface_id
&&
1149 fragment
->adapter_id
== adapter_id
&&
1150 fragment
->chandle
== chandle
&&
1151 fragment
->psm
== psm
&&
1152 fragment
->op
== (pdu_id
| (company_id
<< 8)) &&
1153 fragment
->state
== 1) {
1154 fragment
->count
+= 1;
1155 fragment
->state
= 0;
1157 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1158 data_fragment
->length
= length
;
1159 data_fragment
->data
= (guint8
*) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1160 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1161 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1165 col_append_str(pinfo
->cinfo
, COL_INFO
, " [continue]");
1167 } else if (packet_type
== PACKET_TYPE_END
) {
1171 col_append_str(pinfo
->cinfo
, COL_INFO
, " [end]");
1173 k_interface_id
= interface_id
;
1174 k_adapter_id
= adapter_id
;
1175 k_chandle
= chandle
;
1177 k_op
= pdu_id
| (company_id
<< 8);
1178 k_frame_number
= pinfo
->fd
->num
;
1181 key
[0].key
= &k_interface_id
;
1183 key
[1].key
= &k_adapter_id
;
1185 key
[2].key
= &k_chandle
;
1187 key
[3].key
= &k_psm
;
1191 key
[5].key
= &k_frame_number
;
1195 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1196 if (fragment
&& fragment
->interface_id
== interface_id
&&
1197 fragment
->adapter_id
== adapter_id
&&
1198 fragment
->chandle
== chandle
&&
1199 fragment
->psm
== psm
&&
1200 fragment
->op
== (pdu_id
| (company_id
<< 8))) {
1203 if (fragment
->state
== 1 && pinfo
->fd
->flags
.visited
== 0) {
1204 fragment
->end_frame_number
= pinfo
->fd
->num
;
1205 fragment
->count
+= 1;
1206 fragment
->state
= 2;
1208 data_fragment
= wmem_new(wmem_file_scope(), data_fragment_t
);
1209 data_fragment
->length
= length
;
1210 data_fragment
->data
= (guint8
*) wmem_alloc(wmem_file_scope(), data_fragment
->length
);
1211 tvb_memcpy(tvb
, data_fragment
->data
, offset
, data_fragment
->length
);
1212 wmem_tree_insert32(fragment
->fragments
, fragment
->count
, data_fragment
);
1216 if (fragment
->state
== 2) {
1218 guint8
*reassembled
;
1220 for (i_frame
= 1; i_frame
<= fragment
->count
; ++i_frame
) {
1221 data_fragment
= (data_fragment_t
*)wmem_tree_lookup32_le(fragment
->fragments
, i_frame
);
1222 length
+= data_fragment
->length
;
1225 reassembled
= (guint8
*) wmem_alloc(wmem_file_scope(), length
);
1227 for (i_frame
= 1; i_frame
<= fragment
->count
; ++i_frame
) {
1228 data_fragment
= (data_fragment_t
*)wmem_tree_lookup32_le(fragment
->fragments
, i_frame
);
1229 memcpy(reassembled
+ i_length
,
1230 data_fragment
->data
,
1231 data_fragment
->length
);
1232 i_length
+= data_fragment
->length
;
1235 next_tvb
= tvb_new_child_real_data(tvb
, reassembled
, length
, length
);
1236 add_new_data_source(pinfo
, next_tvb
, "Reassembled AVRCP");
1241 pitem
= proto_tree_add_item(tree
, hf_btavrcp_reassembled
, tvb
, offset
, 0, ENC_NA
);
1242 PROTO_ITEM_SET_GENERATED(pitem
);
1247 if (ctype
== 0x0a) { /* REJECT */
1249 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1250 status
= tvb_get_guint8(tvb
, offset
);
1253 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1254 val_to_str_const(status
, status_vals
, "Unknown status"));
1255 } else switch(pdu_id
) {
1256 case PDU_GET_CAPABILITIES
:
1260 proto_tree_add_item(tree
, hf_btavrcp_capability
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1261 capability
= tvb_get_guint8(tvb
, offset
);
1262 *op_arg
= capability
;
1263 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(%s)",
1264 val_to_str_const(capability
, capability_vals
, "unknown"));
1268 guint capability_count
;
1271 proto_tree_add_item(tree
, hf_btavrcp_capability
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1272 capability
= tvb_get_guint8(tvb
, offset
);
1273 *op_arg
= capability
;
1275 proto_tree_add_item(tree
, hf_btavrcp_capability_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1276 capability_count
= tvb_get_guint8(tvb
, offset
);
1279 for (i_capability
= 0; i_capability
< capability_count
; ++i_capability
) {
1280 if (capability
== 0x02) {
1281 proto_tree_add_item(tree
, hf_btavrcp_company_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1283 } else if (capability
== 0x03) {
1284 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1289 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(%s) - Count: %u",
1290 val_to_str_const(capability
, capability_vals
, "unknown"), capability_count
);
1293 case PDU_LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES
:
1297 guint number_of_attributes
;
1300 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1301 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1304 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1305 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1310 case PDU_LIST_PLAYER_APPLICATION_SETTING_VALUE
:
1312 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1315 guint number_of_values
;
1318 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1319 number_of_values
= tvb_get_guint8(tvb
, offset
);
1322 for (i_value
= 0; i_value
< number_of_values
; ++i_value
) {
1323 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1328 case PDU_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE
:
1330 guint number_of_attributes
;
1333 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1334 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1337 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1338 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1342 guint number_of_settings
;
1345 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1346 number_of_settings
= tvb_get_guint8(tvb
, offset
);
1349 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1350 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1352 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1357 case PDU_SET_PLAYER_APPLICATION_SETTING_VALUE
:
1359 guint number_of_settings
;
1362 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1363 number_of_settings
= tvb_get_guint8(tvb
, offset
);
1366 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1367 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1369 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1376 case PDU_GET_PLAYER_APPLICATION_SETTING_ATTRIBUTE_TEXT
:
1378 guint number_of_attributes
;
1381 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1382 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1385 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1386 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1390 guint number_of_attributes
;
1392 guint attribute_name_length
;
1394 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1395 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1398 for (i_attribute
= 0; i_attribute
< number_of_attributes
; ++i_attribute
) {
1399 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1402 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1405 proto_tree_add_item(tree
, hf_btavrcp_attribute_name_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1406 attribute_name_length
= tvb_get_ntohs(tvb
, offset
);
1409 proto_tree_add_item(tree
, hf_btavrcp_attribute_name
, tvb
, offset
, attribute_name_length
, ENC_UTF_8
| ENC_NA
);
1410 offset
+= attribute_name_length
;
1414 case PDU_GET_PLAYER_APPLICATION_SETTING_VALUE_TEXT
:
1416 guint number_of_values
;
1419 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1421 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1422 number_of_values
= tvb_get_guint8(tvb
, offset
);
1425 for (i_value
= 0; i_value
< number_of_values
; ++i_value
) {
1426 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1430 guint number_of_values
;
1432 guint attribute_value_length
;
1434 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1435 number_of_values
= tvb_get_guint8(tvb
, offset
);
1438 for (i_attribute
= 0; i_attribute
< number_of_values
; ++i_attribute
) {
1439 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1442 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1445 proto_tree_add_item(tree
, hf_btavrcp_attribute_value_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1446 attribute_value_length
= tvb_get_ntohs(tvb
, offset
);
1449 proto_tree_add_item(tree
, hf_btavrcp_attribute_value
, tvb
, offset
, attribute_value_length
, ENC_UTF_8
| ENC_NA
);
1450 offset
+= attribute_value_length
;
1454 case PDU_INFORM_DISPLAYABLE_CHARACTER_SET
:
1456 guint number_of_character_set
;
1457 guint i_character_set
;
1459 proto_tree_add_item(tree
, hf_btavrcp_number_of_character_set
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1460 number_of_character_set
= tvb_get_guint8(tvb
, offset
);
1463 for (i_character_set
= 0; i_character_set
< number_of_character_set
; ++i_character_set
) {
1464 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1471 case PDU_INFORM_BATTERY_STATUS_OF_CT
:
1473 guint battery_status
;
1475 proto_tree_add_item(tree
, hf_btavrcp_battery_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1476 battery_status
= tvb_get_guint8(tvb
, offset
);
1478 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Battery: %s", val_to_str_const(battery_status
, battery_status_vals
, "unknown"));
1483 case PDU_GET_ELEMENT_ATTRIBUTES
:
1485 guint number_of_attributes
;
1488 proto_tree_add_item(tree
, hf_btavrcp_identifier
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1489 identifier
= tvb_get_ntoh64(tvb
, offset
);
1492 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - 0x%08X%08X", (guint
) (identifier
>> 32), (guint
) (identifier
& 0xFFFFFFFF));
1493 if (identifier
== 0x00) col_append_str(pinfo
->cinfo
, COL_INFO
, " (PLAYING)");
1495 pitem
= proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1496 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1497 if (number_of_attributes
== 0) proto_item_append_text(pitem
, " (All Supported Attributes)");
1499 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, number_of_attributes
);
1501 guint number_of_attributes
;
1503 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1504 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
1506 offset
= dissect_attribute_entries(tvb
, pinfo
, tree
, offset
, number_of_attributes
);
1509 case PDU_GET_PLAY_STATUS
:
1514 guint song_position
;
1517 proto_tree_add_item(tree
, hf_btavrcp_song_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1518 song_length
= tvb_get_ntohl(tvb
, offset
);
1520 proto_tree_add_item(tree
, hf_btavrcp_song_position
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1521 song_position
= tvb_get_ntohl(tvb
, offset
);
1523 proto_tree_add_item(tree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1524 play_status
= tvb_get_guint8(tvb
, offset
);
1527 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " PlayStatus: %s, SongPosition: %ums, SongLength: %ums",
1528 val_to_str_const(play_status
, play_status_vals
, "unknown"), song_length
, song_position
);
1531 case PDU_REGISTER_NOTIFICATION
:
1532 event_id
= tvb_get_guint8(tvb
, offset
);
1534 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1535 val_to_str_const(event_id
, notification_vals
, "Unknown Event ID"));
1538 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1540 proto_tree_add_item(tree
, hf_btavrcp_notification_interval
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1543 guint number_of_settings
;
1547 guint song_position
;
1548 guint battery_status
;
1551 guint system_status
;
1553 proto_tree_add_item(tree
, hf_btavrcp_event_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1556 if (ctype
== 0x0D || ctype
== 0x0F) switch(event_id
) {
1557 case EVENT_PLAYBACK_STATUS_CHANGED
:
1558 proto_tree_add_item(tree
, hf_btavrcp_play_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1559 play_status
= tvb_get_guint8(tvb
, offset
);
1561 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - PlayStatus: %s", val_to_str_const(play_status
, play_status_vals
, "unknown"));
1563 case EVENT_TRACK_CHANGED
:
1564 pitem
= proto_tree_add_item(tree
, hf_btavrcp_identifier
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1565 identifier
= tvb_get_ntoh64(tvb
, offset
);
1568 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - 0x%08X%08X", (guint
) (identifier
>> 32), (guint
) (identifier
& 0xFFFFFFFF));
1569 if (identifier
== G_GINT64_CONSTANT(0x0000000000000000)) {
1570 col_append_str(pinfo
->cinfo
, COL_INFO
, " (SELECTED)");
1571 proto_item_append_text(pitem
, " (SELECTED)");
1572 } else if (identifier
== G_GINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
1573 col_append_str(pinfo
->cinfo
, COL_INFO
, " (NOT SELECTED)");
1574 proto_item_append_text(pitem
, " (NOT SELECTED)");
1578 case EVENT_TRACK_REACHED_END
:
1581 case EVENT_TRACK_REACHED_START
:
1584 case EVENT_PLAYBACK_POSITION_CHANGED
:
1585 pitem
= proto_tree_add_item(tree
, hf_btavrcp_song_position
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1586 song_position
= tvb_get_ntohl(tvb
, offset
);
1588 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - SongPosition: %ums", song_position
);
1589 if (song_position
== 0xFFFFFFFF) {
1590 proto_item_append_text(pitem
, " (NOT SELECTED)");
1591 col_append_str(pinfo
->cinfo
, COL_INFO
, " (NOT SELECTED)");
1594 case EVENT_BATTERY_STATUS_CHANGED
:
1595 proto_tree_add_item(tree
, hf_btavrcp_battery_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1596 battery_status
= tvb_get_guint8(tvb
, offset
);
1598 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Battery: %s", val_to_str_const(battery_status
, battery_status_vals
, "unknown"));
1600 case EVENT_SYSTEM_STATUS_CHANGED
:
1601 proto_tree_add_item(tree
, hf_btavrcp_system_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1602 system_status
= tvb_get_guint8(tvb
, offset
);
1604 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - SystemStatus: %s", val_to_str_const(system_status
, system_status_vals
, "unknown"));
1606 case EVENT_PLAYER_APPLICATION_SETTING_CHANGED
:
1607 proto_tree_add_item(tree
, hf_btavrcp_number_of_settings
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1608 number_of_settings
= tvb_get_guint8(tvb
, offset
);
1611 for (i_setting
= 0; i_setting
< number_of_settings
; ++i_setting
) {
1612 proto_tree_add_item(tree
, hf_btavrcp_settings_attribute
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1614 proto_tree_add_item(tree
, hf_btavrcp_settings_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1618 case EVENT_NOWPLAYING_CONTENT_CHANGED
:
1621 case EVENT_AVAILABLE_PLAYERS_CHANGED
:
1624 case EVENT_ADDRESSEDPLAYER_CHANGED
:
1625 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1626 player_id
= tvb_get_ntohs(tvb
, offset
);
1628 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1629 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1631 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - PlayerID: %u, UidCounter: 0x%04x", player_id
, uid_counter
);
1633 case EVENT_UIDS_CHANGED
:
1634 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1635 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1637 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - UidCounter: 0x%04x", uid_counter
);
1639 case EVENT_VOLUME_CHANGED
:
1640 proto_tree_add_item(tree
, hf_btavrcp_absolute_volume_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1641 pitem
= proto_tree_add_item(tree
, hf_btavrcp_absolute_volume
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1643 volume
= tvb_get_guint8(tvb
, offset
) & 0x7F;
1644 volume_percent
= (guint
) ((double) volume
* 100 / (double) 0x7F);
1647 proto_item_append_text(pitem
, " (%u%%)", volume_percent
);
1648 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Volume: %u%%", volume_percent
);
1651 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, -1, ENC_NA
);
1652 offset
= tvb_reported_length(tvb
);
1658 case PDU_REQUEST_CONTINUING_RESPONSE
:
1660 guint continuing_op
;
1662 proto_tree_add_item(tree
, hf_btavrcp_bt_continuing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1663 continuing_op
= tvb_get_guint8(tvb
, offset
) | (company_id
<< 8);
1664 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1665 val_to_str_const(tvb_get_guint8(tvb
, offset
), pdu_id_vals
, "Unknown opcode"));
1668 if (pinfo
->fd
->flags
.visited
== 0) {
1669 k_interface_id
= interface_id
;
1670 k_adapter_id
= adapter_id
;
1671 k_chandle
= chandle
;
1673 k_op
= continuing_op
;
1674 k_frame_number
= pinfo
->fd
->num
;
1677 key
[0].key
= &k_interface_id
;
1679 key
[1].key
= &k_adapter_id
;
1681 key
[2].key
= &k_chandle
;
1683 key
[3].key
= &k_psm
;
1687 key
[5].key
= &k_frame_number
;
1691 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1692 if (fragment
&& fragment
->interface_id
== interface_id
&&
1693 fragment
->adapter_id
== adapter_id
&&
1694 fragment
->chandle
== chandle
&&
1695 fragment
->psm
== psm
&&
1696 fragment
->op
== continuing_op
&&
1697 fragment
->state
== 0) {
1698 fragment
->state
= 1;
1702 *op
= continuing_op
;
1707 case PDU_ABORT_CONTINUING_RESPONSE
:
1709 guint continuing_op
;
1711 proto_tree_add_item(tree
, hf_btavrcp_bt_continuing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1712 continuing_op
= tvb_get_guint8(tvb
, offset
) | (company_id
<< 8);
1713 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1714 val_to_str_const(tvb_get_guint8(tvb
, offset
), pdu_id_vals
, "Unknown opcode"));
1717 if (pinfo
->fd
->flags
.visited
== 0) {
1718 k_interface_id
= interface_id
;
1719 k_adapter_id
= adapter_id
;
1720 k_chandle
= chandle
;
1722 k_op
= continuing_op
;
1723 k_frame_number
= pinfo
->fd
->num
;
1726 key
[0].key
= &k_interface_id
;
1728 key
[1].key
= &k_adapter_id
;
1730 key
[2].key
= &k_chandle
;
1732 key
[3].key
= &k_psm
;
1736 key
[5].key
= &k_frame_number
;
1740 fragment
= (fragment_t
*)wmem_tree_lookup32_array_le(reassembling
, key
);
1741 if (fragment
&& fragment
->interface_id
== interface_id
&&
1742 fragment
->adapter_id
== adapter_id
&&
1743 fragment
->chandle
== chandle
&&
1744 fragment
->psm
== psm
&&
1745 fragment
->op
== continuing_op
&&
1746 fragment
->state
== 0) {
1747 fragment
->state
= 3;
1754 case PDU_SET_ABSOLUTE_VOLUME
:
1755 proto_tree_add_item(tree
, hf_btavrcp_absolute_volume_rfa
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1756 pitem
= proto_tree_add_item(tree
, hf_btavrcp_absolute_volume
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1757 volume
= tvb_get_guint8(tvb
, offset
) & 0x7F;
1758 volume_percent
= (guint
) ((double) volume
* 100 / (double) 0x7F);
1761 proto_item_append_text(pitem
, " (%u%%)", volume_percent
);
1762 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Volume: %u%%", volume_percent
);
1764 case PDU_SET_ADDRESSED_PLAYER
:
1768 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1769 player_id
= tvb_get_ntohs(tvb
, offset
);
1772 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Player ID: %u", player_id
);
1776 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1777 status
= tvb_get_guint8(tvb
, offset
);
1780 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1781 val_to_str_const(status
, status_vals
, "Unknown status"));
1790 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1791 scope
= tvb_get_guint8(tvb
, offset
);
1793 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1794 uid
= tvb_get_ntoh64(tvb
, offset
);
1796 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1797 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1800 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" G_GINT64_MODIFIER
"x, UidCounter: 0x%04x",
1801 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
1805 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1806 status
= tvb_get_guint8(tvb
, offset
);
1808 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1809 val_to_str_const(status
, status_vals
, "Unknown status"));
1812 case PDU_ADD_TO_NOW_PLAYING
:
1818 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1819 scope
= tvb_get_guint8(tvb
, offset
);
1821 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1822 uid
= tvb_get_ntoh64(tvb
, offset
);
1824 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1825 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1828 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" G_GINT64_MODIFIER
"x, UidCounter: 0x%04x",
1829 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
1833 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1834 status
= tvb_get_guint8(tvb
, offset
);
1836 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Status: %s",
1837 val_to_str_const(status
, status_vals
, "Unknown status"));
1847 dissect_browsing(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1848 gint offset
, gboolean is_command
)
1851 guint status
= 0x00;
1853 proto_tree_add_item(tree
, hf_btavrcp_browsing_pdu_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1854 pdu_id
= tvb_get_guint8(tvb
, offset
);
1857 proto_tree_add_item(tree
, hf_btavrcp_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1861 col_append_str(pinfo
->cinfo
, COL_INFO
, ": Command");
1863 /* common code "status" in response */
1864 proto_tree_add_item(tree
, hf_btavrcp_status
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1865 status
= tvb_get_guint8(tvb
, offset
);
1868 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s",
1869 val_to_str_const(status
, status_vals
, "Unknown status"));
1872 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - %s",
1873 val_to_str_const(pdu_id
, browsing_pdu_id_vals
, "Unknown opcode"));
1875 if (is_command
|| status
== STATUS_OK
) switch(pdu_id
) {
1876 case PDU_SET_BROWSED_PLAYER
:
1880 proto_tree_add_item(tree
, hf_btavrcp_player_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1881 player_id
= tvb_get_ntohs(tvb
, offset
);
1884 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Player ID: %u", player_id
);
1888 guint folder_name_length
;
1891 guint8
*folder_name
;
1893 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1895 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1897 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1899 proto_tree_add_item(tree
, hf_btavrcp_folder_depth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1900 folder_depth
= tvb_get_guint8(tvb
, offset
);
1903 pitem
= proto_tree_add_none_format(tree
, hf_btavrcp_currect_path
, tvb
, offset
, -1, "Current Path: /");
1904 col_append_str(pinfo
->cinfo
, COL_INFO
, "Current Path: /");
1905 ptree
= proto_item_add_subtree(pitem
, ett_btavrcp_path
);
1907 for (i_folder
= 0; i_folder
< folder_depth
; ++i_folder
) {
1908 proto_tree_add_item(ptree
, hf_btavrcp_folder_name_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1909 folder_name_length
= tvb_get_ntohs(tvb
, offset
);
1911 proto_tree_add_item(ptree
, hf_btavrcp_folder_name
, tvb
, offset
, folder_name_length
, ENC_NA
);
1912 folder_name
= tvb_get_string(NULL
, tvb
, offset
, folder_name_length
);
1913 offset
+= folder_name_length
;
1914 proto_item_append_text(pitem
, "%s/", folder_name
);
1915 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s/", folder_name
);
1919 case PDU_GET_FOLDER_ITEMS
:
1921 guint attribute_count
;
1926 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1927 scope
= tvb_get_guint8(tvb
, offset
);
1929 proto_tree_add_item(tree
, hf_btavrcp_start_item
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1930 start_item
= tvb_get_ntohl(tvb
, offset
);
1932 proto_tree_add_item(tree
, hf_btavrcp_end_item
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1933 end_item
= tvb_get_ntohl(tvb
, offset
);
1935 proto_tree_add_item(tree
, hf_btavrcp_attribute_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1936 attribute_count
= tvb_get_guint8(tvb
, offset
);
1938 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, attribute_count
);
1940 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, StartItem: 0x%04x, EndItem: 0x%04x",
1941 val_to_str_const(scope
, scope_vals
, "unknown"), start_item
, end_item
);
1943 guint number_of_items
;
1949 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1950 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1952 proto_tree_add_item(tree
, hf_btavrcp_number_of_items16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1953 number_of_items
= tvb_get_ntohs(tvb
, offset
);
1956 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - UidCounter: 0x%04x, NumberOfItems: %u",
1957 uid_counter
, number_of_items
);
1959 for (i_item
= 0; i_item
< number_of_items
; ++i_item
) {
1960 item_type
= tvb_get_guint8(tvb
, offset
);
1961 item_length
= tvb_get_ntohs(tvb
, offset
+ 1);
1963 if (item_type
== ITEM_MEDIAPLAYER
) {
1964 dissect_item_mediaplayer(tvb
, tree
, offset
);
1965 offset
+= 1 + 2 + item_length
;
1966 } else if (item_type
== ITEM_MEDIA_ELEMENT
) {
1967 dissect_item_media_element(tvb
, pinfo
, tree
, offset
);
1968 offset
+= 1 + 2 + item_length
;
1969 } else if (item_type
== ITEM_FOLDER
) {
1970 dissect_item_folder(tvb
, tree
, offset
);
1971 offset
+= 1 + 2 + item_length
;
1973 proto_tree_add_item(tree
, hf_btavrcp_data
, tvb
, offset
, item_length
, ENC_NA
);
1974 offset
+= 1 + 2 + item_length
;
1979 case PDU_CHANGE_PATH
:
1985 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1986 uid_counter
= tvb_get_ntohs(tvb
, offset
);
1988 proto_tree_add_item(tree
, hf_btavrcp_direction
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1989 direction
= tvb_get_guint8(tvb
, offset
);
1991 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1992 uid
= tvb_get_ntoh64(tvb
, offset
);
1995 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Direction: %s, Uid: 0x%016" G_GINT64_MODIFIER
"x, UidCounter: 0x%04x",
1996 val_to_str_const(direction
, direction_vals
, "unknown"), uid
, uid_counter
);
1998 guint number_of_items
;
2000 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2001 number_of_items
= tvb_get_ntohl(tvb
, offset
);
2003 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - NumberOfItems: %u", number_of_items
);
2006 case PDU_GET_ITEM_ATTRIBUTES
:
2008 guint number_of_attributes
;
2012 proto_item
*pitem
= NULL
;
2014 proto_tree_add_item(tree
, hf_btavrcp_scope
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2015 scope
= tvb_get_guint8(tvb
, offset
);
2017 proto_tree_add_item(tree
, hf_btavrcp_uid
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
2018 uid
= tvb_get_ntoh64(tvb
, offset
);
2020 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2021 uid_counter
= tvb_get_ntohs(tvb
, offset
);
2023 pitem
= proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2024 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
2026 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - Scope: %s, Uid: 0x%016" G_GINT64_MODIFIER
"x, UidCounter: 0x%04x",
2027 val_to_str_const(scope
, scope_vals
, "unknown"), uid
, uid_counter
);
2029 if (number_of_attributes
== 0) proto_item_append_text(pitem
, " (All Supported Attributes)");
2031 offset
= dissect_attribute_id_list(tvb
, tree
, offset
, number_of_attributes
);
2033 guint number_of_attributes
;
2035 proto_tree_add_item(tree
, hf_btavrcp_number_of_attributes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2036 number_of_attributes
= tvb_get_guint8(tvb
, offset
);
2038 offset
= dissect_attribute_entries(tvb
, pinfo
, tree
, offset
, number_of_attributes
);
2043 guint search_length
;
2045 proto_tree_add_item(tree
, hf_btavrcp_character_set
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2047 proto_tree_add_item(tree
, hf_btavrcp_search_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2048 search_length
= tvb_get_ntohs(tvb
, offset
);
2050 proto_tree_add_item(tree
, hf_btavrcp_search
, tvb
, offset
, search_length
, ENC_NA
);
2051 offset
+= search_length
;
2053 proto_tree_add_item(tree
, hf_btavrcp_uid_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2055 proto_tree_add_item(tree
, hf_btavrcp_number_of_items
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2059 case PDU_GENERAL_REJECT
:
2060 /* implemented in common code before switch() */
2069 dissect_btavrcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2072 proto_tree
*btavrcp_tree
;
2073 proto_item
*pitem
= NULL
;
2079 guint response_time
;
2080 guint max_response_time
;
2082 timing_info_t
*timing_info
;
2083 wmem_tree_key_t key
[9];
2084 guint32 k_interface_id
;
2085 guint32 k_adapter_id
;
2091 guint32 k_frame_number
;
2092 guint32 interface_id
;
2096 btavctp_data_t
*avctp_data
;
2098 ti
= proto_tree_add_item(tree
, proto_btavrcp
, tvb
, offset
, -1, 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_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown direction %d ",
2116 avctp_data
= (btavctp_data_t
*) data
;
2117 DISSECTOR_ASSERT(avctp_data
);
2119 is_command
= !avctp_data
->cr
;
2121 interface_id
= avctp_data
->interface_id
;
2122 adapter_id
= avctp_data
->adapter_id
;
2123 chandle
= avctp_data
->chandle
;
2124 psm
= avctp_data
->psm
;
2126 if (avctp_data
->psm
== BTL2CAP_PSM_AVCTP_BRWS
) {
2127 col_append_str(pinfo
->cinfo
, COL_INFO
, "Browsing");
2128 offset
= dissect_browsing(tvb
, pinfo
, btavrcp_tree
, offset
, is_command
);
2130 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2131 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_ctype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2132 ctype
= tvb_get_guint8(tvb
, offset
) & 0x0F;
2134 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_subunit_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2135 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_subunit_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2137 proto_tree_add_item(btavrcp_tree
, hf_btavrcp_opcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2138 opcode
= tvb_get_guint8(tvb
, offset
);
2141 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s: %s",
2142 val_to_str_const(opcode
, opcode_vals
, "Unknown opcode"),
2143 val_to_str_const(ctype
, ctype_vals
, "Unknown ctype"));
2146 case OPCODE_PASSTHROUGH
:
2147 offset
= dissect_passthrough(tvb
, pinfo
, btavrcp_tree
, offset
,
2151 offset
= dissect_unit(tvb
, btavrcp_tree
, offset
, is_command
);
2153 case OPCODE_SUBUNIT
:
2154 offset
= dissect_subunit(tvb
, btavrcp_tree
, offset
, is_command
);
2156 case OPCODE_VENDOR_DEPENDANT
:
2157 offset
= dissect_vendor_dependant(tvb
, pinfo
, btavrcp_tree
,
2158 offset
, ctype
, &op
, &op_arg
, is_command
, avctp_data
);
2162 k_interface_id
= interface_id
;
2163 k_adapter_id
= adapter_id
;
2164 k_chandle
= chandle
;
2168 k_op_arg
= (ctype
== 0x0a) ? G_MAXUINT32
: op_arg
;
2169 k_frame_number
= pinfo
->fd
->num
;
2172 key
[0].key
= &k_interface_id
;
2174 key
[1].key
= &k_adapter_id
;
2176 key
[2].key
= &k_chandle
;
2178 key
[3].key
= &k_psm
;
2180 key
[4].key
= &k_opcode
;
2184 key
[6].key
= &k_op_arg
;
2186 key
[7].key
= &k_frame_number
;
2190 if (pinfo
->fd
->flags
.visited
== 0) {
2192 if (ctype
== 0x00) { /* MTC is for CONTROL */
2193 max_response_time
= 200;
2194 } else if (ctype
== 0x01 || ctype
== 0x03) {
2195 /* MTP is for STATUS, NOTIFY */
2196 max_response_time
= 1000;
2198 max_response_time
= 100;
2201 timing_info
= wmem_new(wmem_file_scope(), timing_info_t
);
2202 timing_info
->command_frame_number
= pinfo
->fd
->num
;
2203 timing_info
->command_timestamp
= pinfo
->fd
->abs_ts
;
2204 timing_info
->response_frame_number
= 0;
2205 timing_info
->response_timestamp
.secs
= 0;
2206 timing_info
->response_timestamp
.nsecs
= 0;
2207 timing_info
->max_response_time
= max_response_time
;
2209 timing_info
->interface_id
= interface_id
;
2210 timing_info
->adapter_id
= adapter_id
;
2211 timing_info
->chandle
= chandle
;
2212 timing_info
->psm
= psm
;
2213 timing_info
->opcode
= opcode
;
2214 timing_info
->op
= op
;
2215 timing_info
->op_arg
= op_arg
;
2216 timing_info
->used
= 0;
2218 wmem_tree_insert32_array(timing
, key
, timing_info
);
2220 timing_info
= (timing_info_t
*)wmem_tree_lookup32_array_le(timing
, key
);
2221 if (timing_info
&& timing_info
->interface_id
== interface_id
&&
2222 timing_info
->adapter_id
== adapter_id
&&
2223 timing_info
->chandle
== chandle
&&
2224 timing_info
->psm
== psm
&&
2225 timing_info
->opcode
== opcode
&&
2226 timing_info
->op
== op
&&
2227 ((ctype
== 0x0a) ? 1 : (timing_info
->op_arg
== op_arg
)) &&
2228 timing_info
->used
== 0) {
2229 timing_info
->response_frame_number
= pinfo
->fd
->num
;
2230 timing_info
->response_timestamp
= pinfo
->fd
->abs_ts
;
2231 timing_info
->used
= 1;
2235 k_interface_id
= interface_id
;
2236 k_adapter_id
= adapter_id
;
2237 k_chandle
= chandle
;
2241 k_op_arg
= (ctype
== 0x0a) ? G_MAXUINT32
: op_arg
;
2242 k_frame_number
= pinfo
->fd
->num
;
2245 key
[0].key
= &k_interface_id
;
2247 key
[1].key
= &k_adapter_id
;
2249 key
[2].key
= &k_chandle
;
2251 key
[3].key
= &k_psm
;
2253 key
[4].key
= &k_opcode
;
2257 key
[6].key
= &k_op_arg
;
2259 key
[7].key
= &k_frame_number
;
2265 timing_info
= (timing_info_t
*)wmem_tree_lookup32_array_le(timing
, key
);
2266 if (timing_info
&& timing_info
->interface_id
== interface_id
&&
2267 timing_info
->adapter_id
== adapter_id
&&
2268 timing_info
->chandle
== chandle
&&
2269 timing_info
->psm
== psm
&&
2270 timing_info
->opcode
== opcode
&&
2271 timing_info
->op
== op
&&
2272 ((ctype
== 0x0a) ? 1 : (timing_info
->op_arg
== op_arg
))) {
2274 if (timing_info
->command_timestamp
.nsecs
> timing_info
->response_timestamp
.nsecs
) {
2275 response_time
= timing_info
->response_timestamp
.nsecs
+ (1000000000 - timing_info
->command_timestamp
.nsecs
);
2276 response_time
/= 1000000;
2277 response_time
+= ((guint
)timing_info
->response_timestamp
.secs
- 1 - (guint
)timing_info
->command_timestamp
.secs
) / 1000;
2279 response_time
= timing_info
->response_timestamp
.nsecs
- timing_info
->command_timestamp
.nsecs
;
2280 response_time
/= 1000000;
2281 response_time
+= ((guint
)timing_info
->response_timestamp
.secs
- (guint
)timing_info
->command_timestamp
.secs
) / 1000;
2284 if (timing_info
->response_frame_number
== 0) {
2285 response_time
= UINT_MAX
;
2288 pitem
= proto_tree_add_uint(btavrcp_tree
, hf_btavrcp_response_time
, tvb
, 0, 0, response_time
);
2289 proto_item_append_text(pitem
, "/%ums", timing_info
->max_response_time
);
2290 if (response_time
> timing_info
->max_response_time
) {
2291 proto_item_append_text(pitem
, "; TIME EXCEEDED");
2294 if (timing_info
->response_frame_number
== 0) {
2295 proto_item_append_text(pitem
, "; There is no response");
2298 proto_item_append_text(pitem
, "; Response is at frame: %u", timing_info
->response_frame_number
);
2300 proto_item_append_text(pitem
, "; Command is at frame: %u", timing_info
->command_frame_number
);
2303 PROTO_ITEM_SET_GENERATED(pitem
);
2309 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2310 pitem
= proto_tree_add_item(btavrcp_tree
, hf_btavrcp_data
, tvb
, offset
, -1, ENC_NA
);
2311 expert_add_info(pinfo
, pitem
, &ei_btavrcp_unexpected_data
);
2319 proto_register_btavrcp(void)
2322 expert_module_t
* expert_btavrcp
;
2324 static hf_register_info hf
[] = {
2325 { &hf_btavrcp_reserved
,
2326 { "Reserved", "btavrcp.reserved",
2327 FT_UINT8
, BASE_HEX
, NULL
, 0xF0,
2330 { &hf_btavrcp_ctype
,
2331 { "Ctype", "btavrcp.ctype",
2332 FT_UINT8
, BASE_HEX
, VALS(ctype_vals
), 0x0F,
2335 { &hf_btavrcp_subunit_type
,
2336 { "Subunit Type", "btavrcp.subunit_type",
2337 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2340 { &hf_btavrcp_subunit_id
,
2341 { "Subunit ID", "btavrcp.subunit_id",
2342 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2345 { &hf_btavrcp_opcode
,
2346 { "Opcode", "btavrcp.opcode",
2347 FT_UINT8
, BASE_HEX
, VALS(opcode_vals
), 0x00,
2350 { &hf_btavrcp_company_id
,
2351 { "Company ID", "btavrcp.company_id",
2352 FT_UINT24
, BASE_HEX
, VALS(oui_vals
), 0x00,
2355 { &hf_btavrcp_passthrough_state
,
2356 { "State", "btavrcp.passthrough.state",
2357 FT_UINT8
, BASE_HEX
, VALS(passthrough_state_vals
), 0x80,
2360 { &hf_btavrcp_passthrough_operation
,
2361 { "Operation ID", "btavrcp.passthrough.operation",
2362 FT_UINT8
, BASE_HEX
, VALS(passthrough_operation_vals
), 0x7F,
2365 { &hf_btavrcp_passthrough_data_length
,
2366 { "Data Length", "btavrcp.passthrough.length",
2367 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2370 { &hf_btavrcp_passthrough_vendor_unique_id
,
2371 { "Vendor Unique ID", "btavrcp.passthrough.vendor_unique_id",
2372 FT_UINT16
, BASE_HEX
, VALS(vendor_unique_id_vals
), 0x00,
2375 { &hf_btavrcp_passthrough_company_id
,
2376 { "Company ID", "btavrcp.passthrough.company_id",
2377 FT_UINT24
, BASE_HEX
, VALS(oui_vals
), 0x00,
2380 { &hf_btavrcp_unit_unknown
,
2381 { "Unknown", "btavrcp.unit.unknown",
2382 FT_UINT8
, BASE_HEX
, NULL
, 0xFF,
2385 { &hf_btavrcp_unit_type
,
2386 { "Unit Type", "btavrcp.unit.type",
2387 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2390 { &hf_btavrcp_unit_id
,
2391 { "Subunit ID", "btavrcp.unit.id",
2392 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2395 { &hf_btavrcp_subunit_page
,
2396 { "Page", "btavrcp.subunit.page",
2397 FT_UINT8
, BASE_HEX
, VALS(subunit_type_vals
), 0xF8,
2400 { &hf_btavrcp_subunit_extention_code
,
2401 { "Extention Code", "btavrcp.subunit.extention_code",
2402 FT_UINT8
, BASE_HEX
, NULL
, 0x07,
2405 { &hf_btavrcp_bt_pdu_id
,
2406 { "PDU ID", "btavrcp.pdu_id",
2407 FT_UINT8
, BASE_HEX
, VALS(pdu_id_vals
), 0x00,
2410 { &hf_btavrcp_pdu_id
,
2411 { "PDU ID", "btavrcp.pdu_id",
2412 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2415 { &hf_btavrcp_bt_continuing_pdu_id
,
2416 { "Continuing PDU ID", "btavrcp.pdu_id",
2417 FT_UINT8
, BASE_HEX
, VALS(pdu_id_vals
), 0x00,
2420 { &hf_btavrcp_browsing_pdu_id
,
2421 { "PDU ID", "btavrcp.pdu_id",
2422 FT_UINT8
, BASE_HEX
, VALS(browsing_pdu_id_vals
), 0x00,
2426 { "RFA", "btavrcp.rfa",
2427 FT_UINT8
, BASE_HEX
, NULL
, 0xFC,
2430 { &hf_btavrcp_packet_type
,
2431 { "Packet Type", "btavrcp.packet_type",
2432 FT_UINT8
, BASE_HEX
, VALS(packet_type_vals
), 0x03,
2435 { &hf_btavrcp_length
,
2436 { "Parameter Length", "btavrcp.length",
2437 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2440 { &hf_btavrcp_player_id
,
2441 { "Player ID", "btavrcp.player_id",
2442 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2445 { &hf_btavrcp_status
,
2446 { "Status", "btavrcp.status",
2447 FT_UINT8
, BASE_HEX
, VALS(status_vals
), 0x00,
2450 { &hf_btavrcp_uid_counter
,
2451 { "UID Counter", "btavrcp.uid_counter",
2452 FT_UINT16
, BASE_HEX
, NULL
, 0x00,
2455 { &hf_btavrcp_character_set
,
2456 { "Character Set", "btavrcp.character_set",
2457 FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &wap_mib_enum_vals_character_sets_ext
, 0x00,
2460 { &hf_btavrcp_number_of_items
,
2461 { "Number Of Items", "btavrcp.number_of_items",
2462 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2463 "32bit number of items", HFILL
}
2465 { &hf_btavrcp_number_of_items16
,
2466 { "Number Of Items", "btavrcp.number_of_items",
2467 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2468 "16bit number of items", HFILL
}
2470 { &hf_btavrcp_folder_depth
,
2471 { "Folder Depth", "btavrcp.folder_depth",
2472 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2475 { &hf_btavrcp_folder_name_length
,
2476 { "Folder Name Length", "btavrcp.folder_name_length",
2477 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2480 { &hf_btavrcp_folder_name
,
2481 { "Folder Name", "btavrcp.folder_name",
2482 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2485 { &hf_btavrcp_search_length
,
2486 { "Search String Length", "btavrcp.search_length",
2487 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2490 { &hf_btavrcp_search
,
2491 { "Search String", "btavrcp.search",
2492 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2495 { &hf_btavrcp_number_of_attributes
,
2496 { "Number of Attributes", "btavrcp.number_of_attributes",
2497 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2500 { &hf_btavrcp_attribute_count
,
2501 { "Attribute Count", "btavrcp.attribute_count",
2502 FT_UINT8
, BASE_DEC
, VALS(attribute_count_vals
), 0x00,
2505 { &hf_btavrcp_direction
,
2506 { "Direction", "btavrcp.direction",
2507 FT_UINT8
, BASE_HEX
, VALS(direction_vals
), 0x00,
2510 { &hf_btavrcp_scope
,
2511 { "Scope", "btavrcp.scope",
2512 FT_UINT8
, BASE_HEX
, VALS(scope_vals
), 0x00,
2515 { &hf_btavrcp_start_item
,
2516 { "StartItem", "btavrcp.start_item",
2517 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2520 { &hf_btavrcp_end_item
,
2521 { "EndItem", "btavrcp.end_item",
2522 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2526 { "UID", "btavrcp.uid",
2527 FT_UINT64
, BASE_HEX
, NULL
, 0x00,
2530 { &hf_btavrcp_identifier
,
2531 { "Identifier", "btavrcp.identifier",
2532 FT_UINT64
, BASE_HEX
, NULL
, 0x00,
2535 { &hf_btavrcp_play_status
,
2536 { "Play Status", "btavrcp.play_status",
2537 FT_UINT8
, BASE_HEX
, VALS(play_status_vals
), 0x00,
2540 { &hf_btavrcp_song_length
,
2541 { "Song Length", "btavrcp.song_length",
2542 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2545 { &hf_btavrcp_song_position
,
2546 { "Song Position", "btavrcp.song_position",
2547 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2550 { &hf_btavrcp_notification_interval
,
2551 { "Interval", "btavrcp.notification.interval",
2552 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2555 { &hf_btavrcp_event_id
,
2556 { "Event ID", "btavrcp.notification.event_id",
2557 FT_UINT8
, BASE_HEX
, VALS(notification_vals
), 0x00,
2560 { &hf_btavrcp_battery_status
,
2561 { "Battery Status", "btavrcp.battery_status",
2562 FT_UINT8
, BASE_HEX
, VALS(battery_status_vals
), 0x00,
2565 { &hf_btavrcp_number_of_character_set
,
2566 { "Number of Character Set", "btavrcp.number_of_character_set",
2567 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2570 { &hf_btavrcp_absolute_volume_rfa
,
2571 { "RFA", "btavrcp.absoluter_volume_rfa",
2572 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2575 { &hf_btavrcp_absolute_volume
,
2576 { "Volume", "btavrcp.volume",
2577 FT_UINT8
, BASE_HEX
, NULL
, 0x7F,
2580 { &hf_btavrcp_capability
,
2581 { "Capability", "btavrcp.capability",
2582 FT_UINT8
, BASE_HEX
, VALS(capability_vals
), 0x00,
2585 { &hf_btavrcp_capability_count
,
2586 { "Capability Count", "btavrcp.capability.count",
2587 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2590 { &hf_btavrcp_item_type
,
2591 { "Item Type", "btavrcp.item.type",
2592 FT_UINT8
, BASE_HEX
, VALS(item_type_vals
), 0x00,
2595 { &hf_btavrcp_item_length
,
2596 { "Item Length", "btavrcp.item.length",
2597 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2601 { &hf_btavrcp_number_of_settings
,
2602 { "Number of Settings", "btavrcp.number_of_settings",
2603 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2606 { &hf_btavrcp_settings_attribute
,
2607 { "Setting Attribute", "btavrcp.settings.attribute",
2608 FT_UINT8
, BASE_HEX
, VALS(settings_vals
), 0x00,
2611 { &hf_btavrcp_settings_value
,
2612 { "Setting Value", "btavrcp.settings.value",
2613 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2616 { &hf_btavrcp_system_status
,
2617 { "System Status", "btavrcp.system_status",
2618 FT_UINT8
, BASE_HEX
, VALS(system_status_vals
), 0x00,
2621 { &hf_btavrcp_player_item
,
2622 { "Player", "btavrcp.player_item",
2623 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2626 { &hf_btavrcp_folder
,
2627 { "Folder", "btavrcp.folder",
2628 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2632 { "Item", "btavrcp.item",
2633 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2636 { &hf_btavrcp_features
,
2637 { "Features", "btavrcp.features",
2638 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2641 { &hf_btavrcp_not_used_features
,
2642 { "Not Used Features", "btavrcp.not_used_features",
2643 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2646 { &hf_btavrcp_attribute_list
,
2647 { "Attribute List", "btavrcp.attribute_list",
2648 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2651 { &hf_btavrcp_attribute_item
,
2652 { "Attribute", "btavrcp.attribute_item",
2653 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2656 { &hf_btavrcp_attribute_entries
,
2657 { "Attribute Entries", "btavrcp.attribute_entries",
2658 FT_NONE
, BASE_NONE
, NULL
, 0x00,
2661 { &hf_btavrcp_attribute
,
2662 { "Attribute ID", "btavrcp.attribute",
2663 FT_UINT32
, BASE_HEX
, VALS(attribute_id_vals
), 0x00,
2666 { &hf_btavrcp_attribute_value_length
,
2667 { "Value Length", "btavrcp.value.length",
2668 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2671 { &hf_btavrcp_attribute_value
,
2672 { "Value", "btavrcp.value",
2673 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2676 { &hf_btavrcp_displayable_name_length
,
2677 { "Displayable Name Length", "btavrcp.displayable_name_length",
2678 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2681 { &hf_btavrcp_displayable_name
,
2682 { "Displayable Name", "btavrcp.displayable_name",
2683 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2686 { &hf_btavrcp_media_type
,
2687 { "Media Type", "btavrcp.media_type",
2688 FT_UINT8
, BASE_HEX
, VALS(media_type_vals
), 0x00,
2691 { &hf_btavrcp_folder_type
,
2692 { "Folder Type", "btavrcp.folder_type",
2693 FT_UINT8
, BASE_HEX
, VALS(folder_type_vals
), 0x00,
2696 { &hf_btavrcp_folder_playable
,
2697 { "Folder Playable", "btavrcp.folder_playable",
2698 FT_UINT8
, BASE_HEX
, VALS(folder_playable_vals
), 0x00,
2701 { &hf_btavrcp_major_player_type
,
2702 { "Major Player Type", "btavrcp.major_player_type",
2703 FT_UINT8
, BASE_HEX
, VALS(major_player_type_vals
), 0x00,
2706 { &hf_btavrcp_player_subtype
,
2707 { "Player SubType", "btavrcp.player_subtype",
2708 FT_UINT8
, BASE_HEX
, VALS(player_subtype_vals
), 0x00,
2711 { &hf_btavrcp_setting_value_length
,
2712 { "Value Length", "btavrcp.setting_value.length",
2713 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2716 { &hf_btavrcp_setting_value
,
2717 { "Value", "btavrcp.setting_value",
2718 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2721 { &hf_btavrcp_attribute_name_length
,
2722 { "Value Length", "btavrcp.attribute_name.length",
2723 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2726 { &hf_btavrcp_attribute_name
,
2727 { "Value", "btavrcp.attribute_name",
2728 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2732 { &hf_btavrcp_feature_reserved_0
,
2733 { "Feature Reserved", "btavrcp.feature.reserved",
2734 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2737 { &hf_btavrcp_feature_reserved_1
,
2738 { "Feature Reserved", "btavrcp.feature.reserved",
2739 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2742 { &hf_btavrcp_feature_reserved_2
,
2743 { "Feature Reserved", "btavrcp.feature.reserved",
2744 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2747 { &hf_btavrcp_feature_reserved_3
,
2748 { "Feature Reserved", "btavrcp.feature.reserved",
2749 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2752 { &hf_btavrcp_feature_reserved_4
,
2753 { "Feature Reserved", "btavrcp.feature.reserved",
2754 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2757 { &hf_btavrcp_feature_reserved_5
,
2758 { "Feature Reserved", "btavrcp.feature.reserved",
2759 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2762 { &hf_btavrcp_feature_reserved_6
,
2763 { "Feature Reserved", "btavrcp.feature.reserved",
2764 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2767 { &hf_btavrcp_feature_reserved_7
,
2768 { "Feature Reserved", "btavrcp.feature.reserved",
2769 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2772 { &hf_btavrcp_feature_passthrough_select
,
2773 { "PASSTHROUGH Select", "btavrcp.feature.passthrough.select",
2774 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2777 { &hf_btavrcp_feature_passthrough_up
,
2778 { "PASSTHROUGH Up", "btavrcp.feature.passthrough.up",
2779 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2782 { &hf_btavrcp_feature_passthrough_down
,
2783 { "PASSTHROUGH Down", "btavrcp.feature.passthrough.down",
2784 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2787 { &hf_btavrcp_feature_passthrough_left
,
2788 { "PASSTHROUGH Left", "btavrcp.feature.passthrough.left",
2789 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2792 { &hf_btavrcp_feature_passthrough_right
,
2793 { "PASSTHROUGH Right", "btavrcp.feature.passthrough.right",
2794 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2797 { &hf_btavrcp_feature_passthrough_right_up
,
2798 { "PASSTHROUGH Right Up", "btavrcp.feature.passthrough.right_up",
2799 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2802 { &hf_btavrcp_feature_passthrough_right_down
,
2803 { "PASSTHROUGH Right Down", "btavrcp.feature.passthrough.right_down",
2804 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2807 { &hf_btavrcp_feature_passthrough_left_up
,
2808 { "PASSTHROUGH Left Up", "btavrcp.feature.passthrough.left_up",
2809 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2812 { &hf_btavrcp_feature_passthrough_left_down
,
2813 { "PASSTHROUGH Left Down", "btavrcp.feature.passthrough.left_down",
2814 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2817 { &hf_btavrcp_feature_passthrough_root_menu
,
2818 { "PASSTHROUGH Root Menu", "btavrcp.feature.passthrough.root_menu",
2819 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2822 { &hf_btavrcp_feature_passthrough_setup_menu
,
2823 { "PASSTHROUGH Setup Menu", "btavrcp.feature.passthrough.setup_menu",
2824 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2827 { &hf_btavrcp_feature_passthrough_contents_menu
,
2828 { "PASSTHROUGH Contents Menu", "btavrcp.feature.passthrough.contents_menu",
2829 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2832 { &hf_btavrcp_feature_passthrough_favorite_menu
,
2833 { "PASSTHROUGH Favorite Menu", "btavrcp.feature.passthrough.favorite_menu",
2834 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2837 { &hf_btavrcp_feature_passthrough_exit
,
2838 { "PASSTHROUGH Exit", "btavrcp.feature.passthrough.exit",
2839 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2842 { &hf_btavrcp_feature_passthrough_0
,
2843 { "PASSTHROUGH 0", "btavrcp.feature.passthrough.0",
2844 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2847 { &hf_btavrcp_feature_passthrough_1
,
2848 { "PASSTHROUGH 1", "btavrcp.feature.passthrough.1",
2849 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2852 { &hf_btavrcp_feature_passthrough_2
,
2853 { "PASSTHROUGH 2", "btavrcp.feature.passthrough.2",
2854 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2857 { &hf_btavrcp_feature_passthrough_3
,
2858 { "PASSTHROUGH 3", "btavrcp.feature.passthrough.3",
2859 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2862 { &hf_btavrcp_feature_passthrough_4
,
2863 { "PASSTHROUGH 4", "btavrcp.feature.passthrough.4",
2864 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2867 { &hf_btavrcp_feature_passthrough_5
,
2868 { "PASSTHROUGH 5", "btavrcp.feature.passthrough.5",
2869 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2872 { &hf_btavrcp_feature_passthrough_6
,
2873 { "PASSTHROUGH 6", "btavrcp.feature.passthrough.6",
2874 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2877 { &hf_btavrcp_feature_passthrough_7
,
2878 { "PASSTHROUGH 7", "btavrcp.feature.passthrough.7",
2879 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2882 { &hf_btavrcp_feature_passthrough_8
,
2883 { "PASSTHROUGH 8", "btavrcp.feature.passthrough.8",
2884 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2887 { &hf_btavrcp_feature_passthrough_9
,
2888 { "PASSTHROUGH 9", "btavrcp.feature.passthrough.9",
2889 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2892 { &hf_btavrcp_feature_passthrough_dot
,
2893 { "PASSTHROUGH Dot", "btavrcp.feature.passthrough.dot",
2894 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2897 { &hf_btavrcp_feature_passthrough_enter
,
2898 { "PASSTHROUGH Enter", "btavrcp.feature.passthrough.enter",
2899 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2902 { &hf_btavrcp_feature_passthrough_clear
,
2903 { "PASSTHROUGH Clear", "btavrcp.feature.passthrough.clear",
2904 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2907 { &hf_btavrcp_feature_passthrough_channel_up
,
2908 { "PASSTHROUGH Channel Up", "btavrcp.feature.passthrough.channel_up",
2909 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2912 { &hf_btavrcp_feature_passthrough_channel_down
,
2913 { "PASSTHROUGH Channel Down", "btavrcp.feature.passthrough.channel_down",
2914 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2917 { &hf_btavrcp_feature_passthrough_previous_channel
,
2918 { "PASSTHROUGH Previous Channel", "btavrcp.feature.passthrough.previous_channel",
2919 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2922 { &hf_btavrcp_feature_passthrough_sound_select
,
2923 { "PASSTHROUGH Sound Select", "btavrcp.feature.passthrough.sound_select",
2924 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2927 { &hf_btavrcp_feature_passthrough_input_select
,
2928 { "PASSTHROUGH Input Select", "btavrcp.feature.passthrough.input_select",
2929 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2932 { &hf_btavrcp_feature_passthrough_display_information
,
2933 { "PASSTHROUGH Display Information", "btavrcp.feature.passthrough.display_information",
2934 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2937 { &hf_btavrcp_feature_passthrough_help
,
2938 { "PASSTHROUGH Help", "btavrcp.feature.passthrough.help",
2939 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2942 { &hf_btavrcp_feature_passthrough_page_up
,
2943 { "PASSTHROUGH Page Up", "btavrcp.feature.passthrough.page_up",
2944 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2947 { &hf_btavrcp_feature_passthrough_page_down
,
2948 { "PASSTHROUGH Page Down", "btavrcp.feature.passthrough.page_down",
2949 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2952 { &hf_btavrcp_feature_passthrough_power
,
2953 { "PASSTHROUGH Power", "btavrcp.feature.passthrough.power",
2954 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2957 { &hf_btavrcp_feature_passthrough_volume_up
,
2958 { "PASSTHROUGH Volume Up", "btavrcp.feature.passthrough.volume_up",
2959 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
2962 { &hf_btavrcp_feature_passthrough_volume_down
,
2963 { "PASSTHROUGH Volume Down", "btavrcp.feature.passthrough.volume_down",
2964 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
2967 { &hf_btavrcp_feature_passthrough_mute
,
2968 { "PASSTHROUGH Mute", "btavrcp.feature.passthrough.mute",
2969 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
2972 { &hf_btavrcp_feature_passthrough_play
,
2973 { "PASSTHROUGH Play", "btavrcp.feature.passthrough.play",
2974 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
2977 { &hf_btavrcp_feature_passthrough_stop
,
2978 { "PASSTHROUGH Stop", "btavrcp.feature.passthrough.stop",
2979 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
2982 { &hf_btavrcp_feature_passthrough_pause
,
2983 { "PASSTHROUGH Pause", "btavrcp.feature.passthrough.pause",
2984 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
2987 { &hf_btavrcp_feature_passthrough_record
,
2988 { "PASSTHROUGH Record", "btavrcp.feature.passthrough.record",
2989 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
2992 { &hf_btavrcp_feature_passthrough_rewind
,
2993 { "PASSTHROUGH Rewind", "btavrcp.feature.passthrough.rewind",
2994 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
2997 { &hf_btavrcp_feature_passthrough_fast_forward
,
2998 { "PASSTHROUGH FastForward", "btavrcp.feature.passthrough.fast_forward",
2999 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
3002 { &hf_btavrcp_feature_passthrough_eject
,
3003 { "PASSTHROUGH Eject", "btavrcp.feature.passthrough.eject",
3004 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
3007 { &hf_btavrcp_feature_passthrough_forward
,
3008 { "PASSTHROUGH Forward", "btavrcp.feature.passthrough.forward",
3009 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
3012 { &hf_btavrcp_feature_passthrough_backward
,
3013 { "PASSTHROUGH Backward", "btavrcp.feature.passthrough.backward",
3014 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
3017 { &hf_btavrcp_feature_passthrough_angle
,
3018 { "PASSTHROUGH Angle", "btavrcp.feature.passthrough.angle",
3019 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3022 { &hf_btavrcp_feature_passthrough_subpicture
,
3023 { "PASSTHROUGH SubPicture", "btavrcp.feature.passthrough.subpicture",
3024 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3027 { &hf_btavrcp_feature_passthrough_f1
,
3028 { "PASSTHROUGH F1", "btavrcp.feature.passthrough.f1",
3029 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
3032 { &hf_btavrcp_feature_passthrough_f2
,
3033 { "PASSTHROUGH F2", "btavrcp.feature.passthrough.f2",
3034 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
3037 { &hf_btavrcp_feature_passthrough_f3
,
3038 { "PASSTHROUGH F3", "btavrcp.feature.passthrough.f3",
3039 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
3042 { &hf_btavrcp_feature_passthrough_f4
,
3043 { "PASSTHROUGH F4", "btavrcp.feature.passthrough.f4",
3044 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
3047 { &hf_btavrcp_feature_passthrough_f5
,
3048 { "PASSTHROUGH F5", "btavrcp.feature.passthrough.f5",
3049 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
3052 { &hf_btavrcp_feature_vendor_unique
,
3053 { "Vendor Unique", "btavrcp.feature.vendor_unique",
3054 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
3057 { &hf_btavrcp_feature_basic_group_navigation
,
3058 { "Basic Group Navigation", "btavrcp.feature.basic_group_navigation",
3059 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3062 { &hf_btavrcp_feature_advanced_control_player
,
3063 { "Advanced Control Player", "btavrcp.feature.advanced_control_player",
3064 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3067 { &hf_btavrcp_feature_browsing
,
3068 { "Browsing", "btavrcp.feature.browsing",
3069 FT_UINT8
, BASE_HEX
, NULL
, 0x08,
3072 { &hf_btavrcp_feature_searching
,
3073 { "Searching", "btavrcp.feature.searching",
3074 FT_UINT8
, BASE_HEX
, NULL
, 0x10,
3077 { &hf_btavrcp_feature_addtonowplayer
,
3078 { "AddToNowPlaying", "btavrcp.feature.addtonowplaying",
3079 FT_UINT8
, BASE_HEX
, NULL
, 0x20,
3082 { &hf_btavrcp_feature_uid_unique
,
3083 { "UID Unique", "btavrcp.feature.uid_unique",
3084 FT_UINT8
, BASE_HEX
, NULL
, 0x40,
3087 { &hf_btavrcp_feature_only_browsable_when_addressed
,
3088 { "Only Browsable When Addressed", "btavrcp.feature.only_browsable_when_addressed",
3089 FT_UINT8
, BASE_HEX
, NULL
, 0x80,
3092 { &hf_btavrcp_feature_only_searchable_when_addressed
,
3093 { "Only Searchable When Addressed", "btavrcp.feature.only_searchable_when_addressed",
3094 FT_UINT8
, BASE_HEX
, NULL
, 0x01,
3097 { &hf_btavrcp_feature_nowplaying
,
3098 { "Nowplaying", "btavrcp.feature.nowplaying",
3099 FT_UINT8
, BASE_HEX
, NULL
, 0x02,
3102 { &hf_btavrcp_feature_uid_persistency
,
3103 { "UID Persistency", "btavrcp.feature.uid_persistency",
3104 FT_UINT8
, BASE_HEX
, NULL
, 0x04,
3107 /* end of features */
3108 { &hf_btavrcp_currect_path
,
3109 { "Currect Path", "btavrcp.currect_path",
3110 FT_NONE
, BASE_NONE
, NULL
, 0x00,
3113 { &hf_btavrcp_reassembled
,
3114 { "Reassembled", "btavrcp.reassembled",
3115 FT_NONE
, BASE_NONE
, NULL
, 0x00,
3118 { &hf_btavrcp_response_time
,
3119 { "Response Time", "btavrcp.response_time",
3120 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
3124 { "Data", "btavrcp.data",
3125 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3130 static gint
*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_folder
,
3141 static ei_register_info ei
[] = {
3142 { &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
}},
3143 { &ei_btavrcp_unexpected_data
, { "btavrcp.unexpected_data", PI_PROTOCOL
, PI_WARN
, "Unexpected data", EXPFILL
}},
3146 reassembling
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3147 timing
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3149 proto_btavrcp
= proto_register_protocol("Bluetooth AVRCP Profile", "BT AVRCP", "btavrcp");
3150 new_register_dissector("btavrcp", dissect_btavrcp
, proto_btavrcp
);
3152 proto_register_field_array(proto_btavrcp
, hf
, array_length(hf
));
3153 proto_register_subtree_array(ett
, array_length(ett
));
3154 expert_btavrcp
= expert_register_protocol(proto_btavrcp
);
3155 expert_register_field_array(expert_btavrcp
, ei
, array_length(ei
));
3157 module
= prefs_register_protocol(proto_btavrcp
, NULL
);
3158 prefs_register_static_text_preference(module
, "avrcp.version",
3159 "Bluetooth Profile AVRCP version: 1.5",
3160 "Version of profile supported by this dissector.");
3164 proto_reg_handoff_btavrcp(void)
3166 dissector_handle_t btavrcp_handle
;
3168 btavrcp_handle
= find_dissector("btavrcp");
3170 dissector_add_uint("btavctp.service", BTSDP_AVRCP_TG_SERVICE_UUID
, btavrcp_handle
);
3171 dissector_add_uint("btavctp.service", BTSDP_AVRCP_CT_SERVICE_UUID
, btavrcp_handle
);
3172 dissector_add_uint("btavctp.service", BTSDP_AVRCP_SERVICE_UUID
, btavrcp_handle
);
3177 * Editor modelines - http://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: