3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2011 Intel Corporation.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
39 #define AVC_CTYPE_CONTROL 0x0
40 #define AVC_CTYPE_STATUS 0x1
41 #define AVC_CTYPE_SPECIFIC_INQUIRY 0x2
42 #define AVC_CTYPE_NOTIFY 0x3
43 #define AVC_CTYPE_GENERAL_INQUIRY 0x4
44 #define AVC_CTYPE_NOT_IMPLEMENTED 0x8
45 #define AVC_CTYPE_ACCEPTED 0x9
46 #define AVC_CTYPE_REJECTED 0xA
47 #define AVC_CTYPE_IN_TRANSITION 0xB
48 #define AVC_CTYPE_STABLE 0xC
49 #define AVC_CTYPE_CHANGED 0xD
50 #define AVC_CTYPE_INTERIM 0xF
53 #define AVC_SUBUNIT_MONITOR 0x00
54 #define AVC_SUBUNIT_AUDIO 0x01
55 #define AVC_SUBUNIT_PRINTER 0x02
56 #define AVC_SUBUNIT_DISC 0x03
57 #define AVC_SUBUNIT_TAPE 0x04
58 #define AVC_SUBUNIT_TURNER 0x05
59 #define AVC_SUBUNIT_CA 0x06
60 #define AVC_SUBUNIT_CAMERA 0x07
61 #define AVC_SUBUNIT_PANEL 0x09
62 #define AVC_SUBUNIT_BULLETIN_BOARD 0x0a
63 #define AVC_SUBUNIT_CAMERA_STORAGE 0x0b
64 #define AVC_SUBUNIT_VENDOR_UNIQUE 0x0c
65 #define AVC_SUBUNIT_EXTENDED 0x1e
66 #define AVC_SUBUNIT_UNIT 0x1f
69 #define AVC_OP_VENDORDEP 0x00
70 #define AVC_OP_UNITINFO 0x30
71 #define AVC_OP_SUBUNITINFO 0x31
72 #define AVC_OP_PASSTHROUGH 0x7c
74 /* operands in passthrough commands */
75 #define AVC_PANEL_VOLUME_UP 0x41
76 #define AVC_PANEL_VOLUME_DOWN 0x42
77 #define AVC_PANEL_MUTE 0x43
78 #define AVC_PANEL_PLAY 0x44
79 #define AVC_PANEL_STOP 0x45
80 #define AVC_PANEL_PAUSE 0x46
81 #define AVC_PANEL_RECORD 0x47
82 #define AVC_PANEL_REWIND 0x48
83 #define AVC_PANEL_FAST_FORWARD 0x49
84 #define AVC_PANEL_EJECT 0x4a
85 #define AVC_PANEL_FORWARD 0x4b
86 #define AVC_PANEL_BACKWARD 0x4c
89 #define AVRCP_PACKET_TYPE_SINGLE 0x00
90 #define AVRCP_PACKET_TYPE_START 0x01
91 #define AVRCP_PACKET_TYPE_CONTINUING 0x02
92 #define AVRCP_PACKET_TYPE_END 0x03
95 #define AVRCP_GET_CAPABILITIES 0x10
96 #define AVRCP_LIST_PLAYER_ATTRIBUTES 0x11
97 #define AVRCP_LIST_PLAYER_VALUES 0x12
98 #define AVRCP_GET_CURRENT_PLAYER_VALUE 0x13
99 #define AVRCP_SET_PLAYER_VALUE 0x14
100 #define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15
101 #define AVRCP_GET_PLAYER_VALUE_TEXT 0x16
102 #define AVRCP_DISPLAYABLE_CHARSET 0x17
103 #define AVRCP_CT_BATTERY_STATUS 0x18
104 #define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20
105 #define AVRCP_GET_PLAY_STATUS 0x30
106 #define AVRCP_REGISTER_NOTIFICATION 0x31
107 #define AVRCP_REQUEST_CONTINUING 0x40
108 #define AVRCP_ABORT_CONTINUING 0x41
109 #define AVRCP_SET_ABSOLUTE_VOLUME 0x50
110 #define AVRCP_SET_ADDRESSED_PLAYER 0x60
111 #define AVRCP_SET_BROWSED_PLAYER 0x70
112 #define AVRCP_GET_FOLDER_ITEMS 0x71
113 #define AVRCP_CHANGE_PATH 0x72
114 #define AVRCP_GET_ITEM_ATTRIBUTES 0x73
115 #define AVRCP_PLAY_ITEM 0x74
116 #define AVRCP_SEARCH 0x80
117 #define AVRCP_ADD_TO_NOW_PLAYING 0x90
118 #define AVRCP_GENERAL_REJECT 0xA0
120 /* notification events */
121 #define AVRCP_EVENT_PLAYBACK_STATUS_CHANGED 0x01
122 #define AVRCP_EVENT_TRACK_CHANGED 0x02
123 #define AVRCP_EVENT_TRACK_REACHED_END 0x03
124 #define AVRCP_EVENT_TRACK_REACHED_START 0x04
125 #define AVRCP_EVENT_PLAYBACK_POS_CHANGED 0x05
126 #define AVRCP_EVENT_BATT_STATUS_CHANGED 0x06
127 #define AVRCP_EVENT_SYSTEM_STATUS_CHANGED 0x07
128 #define AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED 0x08
129 #define AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED 0x09
130 #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a
131 #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b
132 #define AVRCP_EVENT_UIDS_CHANGED 0x0c
133 #define AVRCP_EVENT_VOLUME_CHANGED 0x0d
136 #define AVRCP_STATUS_INVALID_COMMAND 0x00
137 #define AVRCP_STATUS_INVALID_PARAMETER 0x01
138 #define AVRCP_STATUS_NOT_FOUND 0x02
139 #define AVRCP_STATUS_INTERNAL_ERROR 0x03
140 #define AVRCP_STATUS_SUCCESS 0x04
141 #define AVRCP_STATUS_UID_CHANGED 0x05
142 #define AVRCP_STATUS_INVALID_DIRECTION 0x07
143 #define AVRCP_STATUS_NOT_DIRECTORY 0x08
144 #define AVRCP_STATUS_DOES_NOT_EXIST 0x09
145 #define AVRCP_STATUS_INVALID_SCOPE 0x0a
146 #define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b
147 #define AVRCP_STATUS_IS_DIRECTORY 0x0c
148 #define AVRCP_STATUS_MEDIA_IN_USE 0x0d
149 #define AVRCP_STATUS_NOW_PLAYING_LIST_FULL 0x0e
150 #define AVRCP_STATUS_SEARCH_NOT_SUPPORTED 0x0f
151 #define AVRCP_STATUS_SEARCH_IN_PROGRESS 0x10
152 #define AVRCP_STATUS_INVALID_PLAYER_ID 0x11
153 #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12
154 #define AVRCP_STATUS_PLAYER_NOT_ADDRESSED 0x13
155 #define AVRCP_STATUS_NO_VALID_SEARCH_RESULTS 0x14
156 #define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15
157 #define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16
159 /* player attributes */
160 #define AVRCP_ATTRIBUTE_ILEGAL 0x00
161 #define AVRCP_ATTRIBUTE_EQUALIZER 0x01
162 #define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02
163 #define AVRCP_ATTRIBUTE_SHUFFLE 0x03
164 #define AVRCP_ATTRIBUTE_SCAN 0x04
166 /* media attributes */
167 #define AVRCP_MEDIA_ATTRIBUTE_ILLEGAL 0x0
168 #define AVRCP_MEDIA_ATTRIBUTE_TITLE 0x1
169 #define AVRCP_MEDIA_ATTRIBUTE_ARTIST 0x2
170 #define AVRCP_MEDIA_ATTRIBUTE_ALBUM 0x3
171 #define AVRCP_MEDIA_ATTRIBUTE_TRACK 0x4
172 #define AVRCP_MEDIA_ATTRIBUTE_TOTAL 0x5
173 #define AVRCP_MEDIA_ATTRIBUTE_GENRE 0x6
174 #define AVRCP_MEDIA_ATTRIBUTE_DURATION 0x7
177 #define AVRCP_PLAY_STATUS_STOPPED 0x00
178 #define AVRCP_PLAY_STATUS_PLAYING 0x01
179 #define AVRCP_PLAY_STATUS_PAUSED 0x02
180 #define AVRCP_PLAY_STATUS_FWD_SEEK 0x03
181 #define AVRCP_PLAY_STATUS_REV_SEEK 0x04
182 #define AVRCP_PLAY_STATUS_ERROR 0xFF
185 #define AVRCP_MEDIA_PLAYER_LIST 0x00
186 #define AVRCP_MEDIA_PLAYER_VFS 0x01
187 #define AVRCP_MEDIA_SEARCH 0x02
188 #define AVRCP_MEDIA_NOW_PLAYING 0x03
190 static struct avrcp_continuing {
195 static const char *ctype2str(uint8_t ctype)
197 switch (ctype & 0x0f) {
198 case AVC_CTYPE_CONTROL:
200 case AVC_CTYPE_STATUS:
202 case AVC_CTYPE_SPECIFIC_INQUIRY:
203 return "Specific Inquiry";
204 case AVC_CTYPE_NOTIFY:
206 case AVC_CTYPE_GENERAL_INQUIRY:
207 return "General Inquiry";
208 case AVC_CTYPE_NOT_IMPLEMENTED:
209 return "Not Implemented";
210 case AVC_CTYPE_ACCEPTED:
212 case AVC_CTYPE_REJECTED:
214 case AVC_CTYPE_IN_TRANSITION:
215 return "In Transition";
216 case AVC_CTYPE_STABLE:
218 case AVC_CTYPE_CHANGED:
220 case AVC_CTYPE_INTERIM:
227 static const char *opcode2str(uint8_t opcode)
230 case AVC_OP_VENDORDEP:
231 return "Vendor Dependent";
232 case AVC_OP_UNITINFO:
234 case AVC_OP_SUBUNITINFO:
235 return "Subunit Info";
236 case AVC_OP_PASSTHROUGH:
237 return "Passthrough";
243 static const char *pt2str(uint8_t pt)
246 case AVRCP_PACKET_TYPE_SINGLE:
248 case AVRCP_PACKET_TYPE_START:
250 case AVRCP_PACKET_TYPE_CONTINUING:
252 case AVRCP_PACKET_TYPE_END:
259 static const char *pdu2str(uint8_t pduid)
262 case AVRCP_GET_CAPABILITIES:
263 return "GetCapabilities";
264 case AVRCP_LIST_PLAYER_ATTRIBUTES:
265 return "ListPlayerApplicationSettingAttributes";
266 case AVRCP_LIST_PLAYER_VALUES:
267 return "ListPlayerApplicationSettingValues";
268 case AVRCP_GET_CURRENT_PLAYER_VALUE:
269 return "GetCurrentPlayerApplicationSettingValue";
270 case AVRCP_SET_PLAYER_VALUE:
271 return "SetPlayerApplicationSettingValue";
272 case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
273 return "GetPlayerApplicationSettingAttributeText";
274 case AVRCP_GET_PLAYER_VALUE_TEXT:
275 return "GetPlayerApplicationSettingValueText";
276 case AVRCP_DISPLAYABLE_CHARSET:
277 return "InformDisplayableCharacterSet";
278 case AVRCP_CT_BATTERY_STATUS:
279 return "InformBatteryStatusOfCT";
280 case AVRCP_GET_ELEMENT_ATTRIBUTES:
281 return "GetElementAttributes";
282 case AVRCP_GET_PLAY_STATUS:
283 return "GetPlayStatus";
284 case AVRCP_REGISTER_NOTIFICATION:
285 return "RegisterNotification";
286 case AVRCP_REQUEST_CONTINUING:
287 return "RequestContinuingResponse";
288 case AVRCP_ABORT_CONTINUING:
289 return "AbortContinuingResponse";
290 case AVRCP_SET_ABSOLUTE_VOLUME:
291 return "SetAbsoluteVolume";
292 case AVRCP_SET_ADDRESSED_PLAYER:
293 return "SetAddressedPlayer";
294 case AVRCP_SET_BROWSED_PLAYER:
295 return "SetBrowsedPlayer";
296 case AVRCP_GET_FOLDER_ITEMS:
297 return "GetFolderItems";
298 case AVRCP_CHANGE_PATH:
300 case AVRCP_GET_ITEM_ATTRIBUTES:
301 return "GetItemAttributes";
302 case AVRCP_PLAY_ITEM:
306 case AVRCP_ADD_TO_NOW_PLAYING:
307 return "AddToNowPlaying";
308 case AVRCP_GENERAL_REJECT:
309 return "GeneralReject";
315 static char *cap2str(uint8_t cap)
327 static char *event2str(uint8_t event)
330 case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
331 return "EVENT_PLAYBACK_STATUS_CHANGED";
332 case AVRCP_EVENT_TRACK_CHANGED:
333 return "EVENT_TRACK_CHANGED";
334 case AVRCP_EVENT_TRACK_REACHED_END:
335 return "EVENT_TRACK_REACHED_END";
336 case AVRCP_EVENT_TRACK_REACHED_START:
337 return "EVENT_TRACK_REACHED_START";
338 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
339 return "EVENT_PLAYBACK_POS_CHANGED";
340 case AVRCP_EVENT_BATT_STATUS_CHANGED:
341 return "EVENT_BATT_STATUS_CHANGED";
342 case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
343 return "EVENT_SYSTEM_STATUS_CHANGED";
344 case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
345 return "EVENT_PLAYER_APPLICATION_SETTING_CHANGED";
346 case AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED:
347 return "EVENT_NOW_PLAYING_CONTENT_CHANGED";
348 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
349 return "EVENT_AVAILABLE_PLAYERS_CHANGED";
350 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
351 return "EVENT_ADDRESSED_PLAYER_CHANGED";
352 case AVRCP_EVENT_UIDS_CHANGED:
353 return "EVENT_UIDS_CHANGED";
354 case AVRCP_EVENT_VOLUME_CHANGED:
355 return "EVENT_VOLUME_CHANGED";
361 static const char *error2str(uint8_t status)
364 case AVRCP_STATUS_INVALID_COMMAND:
365 return "Invalid Command";
366 case AVRCP_STATUS_INVALID_PARAMETER:
367 return "Invalid Parameter";
368 case AVRCP_STATUS_NOT_FOUND:
370 case AVRCP_STATUS_INTERNAL_ERROR:
371 return "Internal Error";
372 case AVRCP_STATUS_SUCCESS:
374 case AVRCP_STATUS_UID_CHANGED:
375 return "UID Changed";
376 case AVRCP_STATUS_INVALID_DIRECTION:
377 return "Invalid Direction";
378 case AVRCP_STATUS_NOT_DIRECTORY:
379 return "Not a Directory";
380 case AVRCP_STATUS_DOES_NOT_EXIST:
381 return "Does Not Exist";
382 case AVRCP_STATUS_INVALID_SCOPE:
383 return "Invalid Scope";
384 case AVRCP_STATUS_OUT_OF_BOUNDS:
385 return "Range Out of Bonds";
386 case AVRCP_STATUS_MEDIA_IN_USE:
387 return "Media in Use";
388 case AVRCP_STATUS_IS_DIRECTORY:
389 return "UID is a Directory";
390 case AVRCP_STATUS_NOW_PLAYING_LIST_FULL:
391 return "Now Playing List Full";
392 case AVRCP_STATUS_SEARCH_NOT_SUPPORTED:
393 return "Seach Not Supported";
394 case AVRCP_STATUS_SEARCH_IN_PROGRESS:
395 return "Search in Progress";
396 case AVRCP_STATUS_INVALID_PLAYER_ID:
397 return "Invalid Player ID";
398 case AVRCP_STATUS_PLAYER_NOT_BROWSABLE:
399 return "Player Not Browsable";
400 case AVRCP_STATUS_PLAYER_NOT_ADDRESSED:
401 return "Player Not Addressed";
402 case AVRCP_STATUS_NO_VALID_SEARCH_RESULTS:
403 return "No Valid Search Result";
404 case AVRCP_STATUS_NO_AVAILABLE_PLAYERS:
405 return "No Available Players";
406 case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED:
407 return "Addressed Player Changed";
413 static void avrcp_rejected_dump(int level, struct frame *frm, uint16_t len)
417 p_indent(level, frm);
420 printf("PDU Malformed\n");
421 raw_dump(level, frm);
425 status = get_u8(frm);
426 printf("Error: 0x%02x (%s)\n", status, error2str(status));
429 static void avrcp_get_capabilities_dump(int level, struct frame *frm, uint16_t len)
434 p_indent(level, frm);
437 printf("PDU Malformed\n");
438 raw_dump(level, frm);
443 printf("CapabilityID: 0x%02x (%s)\n", cap, cap2str(cap));
448 p_indent(level, frm);
451 printf("CapabilityCount: 0x%02x\n", count);
455 for (; count > 0; count--) {
458 p_indent(level, frm);
460 printf("%s: 0x", cap2str(cap));
461 for (i = 0; i < 3; i++)
462 printf("%02x", get_u8(frm));
467 for (; count > 0; count--) {
470 p_indent(level, frm);
473 printf("%s: 0x%02x (%s)\n", cap2str(cap), event,
478 raw_dump(level, frm);
482 static const char *attr2str(uint8_t attr)
485 case AVRCP_ATTRIBUTE_ILEGAL:
487 case AVRCP_ATTRIBUTE_EQUALIZER:
488 return "Equalizer ON/OFF Status";
489 case AVRCP_ATTRIBUTE_REPEAT_MODE:
490 return "Repeat Mode Status";
491 case AVRCP_ATTRIBUTE_SHUFFLE:
492 return "Shuffle ON/OFF Status";
493 case AVRCP_ATTRIBUTE_SCAN:
494 return "Scan ON/OFF Status";
500 static void avrcp_list_player_attributes_dump(int level, struct frame *frm,
508 p_indent(level, frm);
511 printf("AttributeCount: 0x%02x\n", num);
513 for (; num > 0; num--) {
516 p_indent(level, frm);
519 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
523 static const char *value2str(uint8_t attr, uint8_t value)
526 case AVRCP_ATTRIBUTE_ILEGAL:
528 case AVRCP_ATTRIBUTE_EQUALIZER:
537 case AVRCP_ATTRIBUTE_REPEAT_MODE:
542 return "Single Track Repeat";
544 return "All Track Repeat";
546 return "Group Repeat";
550 case AVRCP_ATTRIBUTE_SHUFFLE:
555 return "All Track Suffle";
557 return "Group Suffle";
561 case AVRCP_ATTRIBUTE_SCAN:
566 return "All Track Scan";
577 static void avrcp_list_player_values_dump(int level, struct frame *frm,
578 uint8_t ctype, uint16_t len)
580 static uint8_t attr = 0; /* Remember attribute */
583 p_indent(level, frm);
586 printf("PDU Malformed\n");
587 raw_dump(level, frm);
591 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
595 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
601 printf("ValueCount: 0x%02x\n", num);
603 for (; num > 0; num--) {
606 p_indent(level, frm);
609 printf("ValueID: 0x%02x (%s)\n", value,
610 value2str(attr, value));
614 static void avrcp_get_current_player_value_dump(int level, struct frame *frm,
615 uint8_t ctype, uint16_t len)
619 p_indent(level, frm);
622 printf("PDU Malformed\n");
623 raw_dump(level, frm);
627 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
631 printf("AttributeCount: 0x%02x\n", num);
633 for (; num > 0; num--) {
636 p_indent(level, frm);
639 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
646 printf("ValueCount: 0x%02x\n", num);
648 for (; num > 0; num--) {
651 p_indent(level, frm);
654 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
656 p_indent(level, frm);
659 printf("ValueID: 0x%02x (%s)\n", value,
660 value2str(attr, value));
664 static void avrcp_set_player_value_dump(int level, struct frame *frm,
665 uint8_t ctype, uint16_t len)
669 p_indent(level, frm);
671 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
675 printf("PDU Malformed\n");
676 raw_dump(level, frm);
681 printf("AttributeCount: 0x%02x\n", num);
683 for (; num > 0; num--) {
686 p_indent(level, frm);
689 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
691 p_indent(level, frm);
694 printf("ValueID: 0x%02x (%s)\n", value,
695 value2str(attr, value));
699 static const char *charset2str(uint16_t charset)
732 static void avrcp_get_player_attribute_text_dump(int level, struct frame *frm,
733 uint8_t ctype, uint16_t len)
737 p_indent(level, frm);
740 printf("PDU Malformed\n");
741 raw_dump(level, frm);
746 printf("AttributeCount: 0x%02x\n", num);
748 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
751 for (; num > 0; num--) {
754 p_indent(level, frm);
757 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
763 for (; num > 0; num--) {
767 p_indent(level, frm);
770 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
772 p_indent(level, frm);
774 charset = get_u16(frm);
775 printf("CharsetID: 0x%04x (%s)\n", charset,
776 charset2str(charset));
778 p_indent(level, frm);
781 printf("StringLength: 0x%02x\n", len);
783 p_indent(level, frm);
786 for (; len > 0; len--) {
787 uint8_t c = get_u8(frm);
788 printf("%1c", isprint(c) ? c : '.');
794 static void avrcp_get_player_value_text_dump(int level, struct frame *frm,
795 uint8_t ctype, uint16_t len)
797 static uint8_t attr = 0; /* Remember attribute */
800 p_indent(level, frm);
803 printf("PDU Malformed\n");
804 raw_dump(level, frm);
808 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
812 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
814 p_indent(level, frm);
817 printf("ValueCount: 0x%02x\n", num);
819 for (; num > 0; num--) {
822 p_indent(level, frm);
825 printf("ValueID: 0x%02x (%s)\n", value,
826 value2str(attr, value));
833 printf("ValueCount: 0x%02x\n", num);
835 for (; num > 0; num--) {
839 p_indent(level, frm);
842 printf("ValueID: 0x%02x (%s)\n", value,
843 value2str(attr, value));
845 p_indent(level, frm);
847 charset = get_u16(frm);
848 printf("CharsetID: 0x%04x (%s)\n", charset,
849 charset2str(charset));
851 p_indent(level, frm);
854 printf("StringLength: 0x%02x\n", len);
856 p_indent(level, frm);
859 for (; len > 0; len--) {
860 uint8_t c = get_u8(frm);
861 printf("%1c", isprint(c) ? c : '.');
867 static void avrcp_displayable_charset(int level, struct frame *frm,
868 uint8_t ctype, uint16_t len)
872 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
875 p_indent(level, frm);
878 printf("PDU Malformed\n");
879 raw_dump(level, frm);
884 printf("CharsetCount: 0x%02x\n", num);
886 for (; num > 0; num--) {
889 p_indent(level, frm);
891 charset = get_u16(frm);
892 printf("CharsetID: 0x%04x (%s)\n", charset,
893 charset2str(charset));
897 static const char *status2str(uint8_t status)
909 return "FULL_CHARGE";
915 static void avrcp_ct_battery_status_dump(int level, struct frame *frm,
916 uint8_t ctype, uint16_t len)
920 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
923 p_indent(level, frm);
925 status = get_u8(frm);
926 printf("BatteryStatus: 0x%02x (%s)\n", status, status2str(status));
929 static const char *mediattr2str(uint32_t attr)
932 case AVRCP_MEDIA_ATTRIBUTE_ILLEGAL:
934 case AVRCP_MEDIA_ATTRIBUTE_TITLE:
936 case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
938 case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
940 case AVRCP_MEDIA_ATTRIBUTE_TRACK:
942 case AVRCP_MEDIA_ATTRIBUTE_TOTAL:
943 return "Track Total";
944 case AVRCP_MEDIA_ATTRIBUTE_GENRE:
946 case AVRCP_MEDIA_ATTRIBUTE_DURATION:
947 return "Track duration";
953 static void avrcp_get_element_attributes_dump(int level, struct frame *frm,
954 uint8_t ctype, uint16_t len,
960 p_indent(level, frm);
962 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
966 printf("PDU Malformed\n");
967 raw_dump(level, frm);
972 printf("Identifier: 0x%jx (%s)\n", id, id ? "Reserved" : "PLAYING");
974 p_indent(level, frm);
977 printf("AttributeCount: 0x%02x\n", num);
979 for (; num > 0; num--) {
982 p_indent(level, frm);
985 printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
991 if (pt == AVRCP_PACKET_TYPE_SINGLE || pt == AVRCP_PACKET_TYPE_START) {
993 printf("PDU Malformed\n");
994 raw_dump(level, frm);
999 avrcp_continuing.num = num;
1000 printf("AttributeCount: 0x%02x\n", num);
1003 num = avrcp_continuing.num;
1005 if (avrcp_continuing.size > 0) {
1008 if (avrcp_continuing.size > len) {
1010 avrcp_continuing.size -= len;
1012 size = avrcp_continuing.size;
1013 avrcp_continuing.size = 0;
1016 printf("ContinuingAttributeValue: ");
1017 for (; size > 0; size--) {
1018 uint8_t c = get_u8(frm);
1019 printf("%1c", isprint(c) ? c : '.');
1027 while (num > 0 && len > 0) {
1029 uint16_t charset, attrlen;
1031 p_indent(level, frm);
1033 attr = get_u32(frm);
1034 printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
1036 p_indent(level, frm);
1038 charset = get_u16(frm);
1039 printf("CharsetID: 0x%04x (%s)\n", charset,
1040 charset2str(charset));
1042 p_indent(level, frm);
1043 attrlen = get_u16(frm);
1044 printf("AttributeValueLength: 0x%04x\n", attrlen);
1046 len -= sizeof(attr) + sizeof(charset) + sizeof(attrlen);
1049 p_indent(level, frm);
1051 printf("AttributeValue: ");
1052 for (; attrlen > 0 && len > 0; attrlen--, len--) {
1053 uint8_t c = get_u8(frm);
1054 printf("%1c", isprint(c) ? c : '.');
1059 avrcp_continuing.size = attrlen;
1062 avrcp_continuing.num = num;
1065 static const char *playstatus2str(uint8_t status)
1068 case AVRCP_PLAY_STATUS_STOPPED:
1070 case AVRCP_PLAY_STATUS_PLAYING:
1072 case AVRCP_PLAY_STATUS_PAUSED:
1074 case AVRCP_PLAY_STATUS_FWD_SEEK:
1076 case AVRCP_PLAY_STATUS_REV_SEEK:
1078 case AVRCP_PLAY_STATUS_ERROR:
1085 static void avrcp_get_play_status_dump(int level, struct frame *frm,
1086 uint8_t ctype, uint16_t len)
1091 if (ctype <= AVC_CTYPE_GENERAL_INQUIRY)
1094 p_indent(level, frm);
1097 printf("PDU Malformed\n");
1098 raw_dump(level, frm);
1102 interval = get_u32(frm);
1103 printf("SongLength: 0x%08x (%u miliseconds)\n", interval, interval);
1105 p_indent(level, frm);
1107 interval = get_u32(frm);
1108 printf("SongPosition: 0x%08x (%u miliconds)\n", interval, interval);
1110 p_indent(level, frm);
1112 status = get_u8(frm);
1113 printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
1116 static void avrcp_register_notification_dump(int level, struct frame *frm,
1117 uint8_t ctype, uint16_t len)
1119 uint8_t event, status;
1124 p_indent(level, frm);
1126 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1130 printf("PDU Malformed\n");
1131 raw_dump(level, frm);
1135 event = get_u8(frm);
1136 printf("EventID: 0x%02x (%s)\n", event, event2str(event));
1138 p_indent(level, frm);
1140 interval = get_u32(frm);
1141 printf("Interval: 0x%08x (%u seconds)\n", interval, interval);
1147 printf("PDU Malformed\n");
1148 raw_dump(level, frm);
1152 event = get_u8(frm);
1153 printf("EventID: 0x%02x (%s)\n", event, event2str(event));
1155 p_indent(level, frm);
1158 case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
1159 status = get_u8(frm);
1160 printf("PlayStatus: 0x%02x (%s)\n", status,
1161 playstatus2str(status));
1163 case AVRCP_EVENT_TRACK_CHANGED:
1165 printf("Identifier: 0x%16" PRIx64 " (%" PRIu64 ")\n", id, id);
1167 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
1168 interval = get_u32(frm);
1169 printf("Position: 0x%08x (%u miliseconds)\n", interval,
1172 case AVRCP_EVENT_BATT_STATUS_CHANGED:
1173 status = get_u8(frm);
1174 printf("BatteryStatus: 0x%02x (%s)\n", status,
1175 status2str(status));
1177 case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
1178 status = get_u8(frm);
1179 printf("SystemStatus: 0x%02x ", status);
1182 printf("(POWER_ON)\n");
1185 printf("(POWER_OFF)\n");
1188 printf("(UNPLUGGED)\n");
1191 printf("(UNKOWN)\n");
1195 case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
1196 status = get_u8(frm);
1197 printf("AttributeCount: 0x%02x\n", status);
1199 for (; status > 0; status--) {
1200 uint8_t attr, value;
1202 p_indent(level, frm);
1205 printf("AttributeID: 0x%02x (%s)\n", attr,
1208 p_indent(level, frm);
1210 value = get_u8(frm);
1211 printf("ValueID: 0x%02x (%s)\n", value,
1212 value2str(attr, value));
1215 case AVRCP_EVENT_VOLUME_CHANGED:
1216 status = get_u8(frm) & 0x7F;
1217 printf("Volume: %.2f%% (%d/127)\n", status/1.27, status);
1219 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
1221 printf("PlayerID: 0x%04x (%u)\n", uid, uid);
1224 p_indent(level, frm);
1227 printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1229 case AVRCP_EVENT_UIDS_CHANGED:
1231 printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1236 static void avrcp_set_absolute_volume_dump(int level, struct frame *frm,
1237 uint8_t ctype, uint16_t len)
1241 p_indent(level, frm);
1244 printf("PDU Malformed\n");
1245 raw_dump(level, frm);
1249 value = get_u8(frm) & 0x7F;
1250 printf("Volume: %.2f%% (%d/127)\n", value/1.27, value);
1253 static void avrcp_set_addressed_player(int level, struct frame *frm,
1254 uint8_t ctype, uint16_t len)
1259 p_indent(level, frm);
1261 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1265 printf("PDU Malformed\n");
1266 raw_dump(level, frm);
1271 printf("PlayerID: 0x%04x (%u)\n", id, id);
1276 printf("PDU Malformed\n");
1277 raw_dump(level, frm);
1281 status = get_u8(frm);
1282 printf("Status: 0x%02x (%s)\n", status, error2str(status));
1285 static void avrcp_set_browsed_player_dump(int level, struct frame *frm,
1286 uint8_t hdr, uint16_t len)
1289 uint16_t id, uids, charset;
1290 uint8_t status, folders;
1292 p_indent(level, frm);
1298 printf("PDU Malformed\n");
1299 raw_dump(level, frm);
1304 printf("PlayerID: 0x%04x (%u)\n", id, id);
1308 if (len != 1 && len < 10) {
1309 printf("PDU Malformed\n");
1310 raw_dump(level, frm);
1314 status = get_u8(frm);
1315 printf("Status: 0x%02x (%s)\n", status, error2str(status));
1320 p_indent(level, frm);
1322 uids = get_u16(frm);
1323 printf("UIDCounter: 0x%04x (%u)\n", uids, uids);
1325 p_indent(level, frm);
1327 items = get_u32(frm);
1328 printf("Number of Items: 0x%08x (%u)\n", items, items);
1330 p_indent(level, frm);
1332 charset = get_u16(frm);
1333 printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1335 p_indent(level, frm);
1337 folders = get_u8(frm);
1338 printf("Folder Depth: 0x%02x (%u)\n", folders, folders);
1340 for (; folders > 0; folders--) {
1343 p_indent(level, frm);
1347 for (; len > 0; len--) {
1348 uint8_t c = get_u8(frm);
1349 printf("%1c", isprint(c) ? c : '.');
1355 static const char *scope2str(uint8_t scope)
1358 case AVRCP_MEDIA_PLAYER_LIST:
1359 return "Media Player List";
1360 case AVRCP_MEDIA_PLAYER_VFS:
1361 return "Media Player Virtual Filesystem";
1362 case AVRCP_MEDIA_SEARCH:
1364 case AVRCP_MEDIA_NOW_PLAYING:
1365 return "Now Playing";
1371 static void avrcp_play_item_dump(int level, struct frame *frm,
1372 uint8_t ctype, uint16_t len)
1375 uint32_t uidcounter;
1376 uint8_t scope, status;
1378 p_indent(level, frm);
1380 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1384 printf("PDU Malformed\n");
1385 raw_dump(level, frm);
1389 scope = get_u8(frm);
1390 printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1392 p_indent(level, frm);
1395 printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1397 p_indent(level, frm);
1399 uidcounter = get_u16(frm);
1400 printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
1405 status = get_u8(frm);
1406 printf("Status: 0x%02x (%s)\n", status, error2str(status));
1409 static void avrcp_add_to_now_playing_dump(int level, struct frame *frm,
1410 uint8_t ctype, uint16_t len)
1413 uint32_t uidcounter;
1414 uint8_t scope, status;
1416 p_indent(level, frm);
1418 if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1422 printf("PDU Malformed\n");
1423 raw_dump(level, frm);
1427 scope = get_u8(frm);
1428 printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1430 p_indent(level, frm);
1433 printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1435 p_indent(level, frm);
1437 uidcounter = get_u16(frm);
1438 printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
1443 status = get_u8(frm);
1444 printf("Status: 0x%02x (%s)\n", status, error2str(status));
1447 static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
1452 p_indent(level, frm);
1454 pduid = get_u8(frm);
1458 printf("AVRCP: %s: pt %s len 0x%04x\n", pdu2str(pduid),
1461 if (len != frm->len) {
1462 p_indent(level, frm);
1463 printf("PDU Malformed\n");
1464 raw_dump(level, frm);
1468 if (ctype == AVC_CTYPE_REJECTED) {
1469 avrcp_rejected_dump(level + 1, frm, len);
1474 case AVRCP_GET_CAPABILITIES:
1475 avrcp_get_capabilities_dump(level + 1, frm, len);
1477 case AVRCP_LIST_PLAYER_ATTRIBUTES:
1478 avrcp_list_player_attributes_dump(level + 1, frm, len);
1480 case AVRCP_LIST_PLAYER_VALUES:
1481 avrcp_list_player_values_dump(level + 1, frm, ctype, len);
1483 case AVRCP_GET_CURRENT_PLAYER_VALUE:
1484 avrcp_get_current_player_value_dump(level + 1, frm, ctype,
1487 case AVRCP_SET_PLAYER_VALUE:
1488 avrcp_set_player_value_dump(level + 1, frm, ctype, len);
1490 case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
1491 avrcp_get_player_attribute_text_dump(level + 1, frm, ctype,
1494 case AVRCP_GET_PLAYER_VALUE_TEXT:
1495 avrcp_get_player_value_text_dump(level + 1, frm, ctype, len);
1497 case AVRCP_DISPLAYABLE_CHARSET:
1498 avrcp_displayable_charset(level + 1, frm, ctype, len);
1500 case AVRCP_CT_BATTERY_STATUS:
1501 avrcp_ct_battery_status_dump(level + 1, frm, ctype, len);
1503 case AVRCP_GET_ELEMENT_ATTRIBUTES:
1504 avrcp_get_element_attributes_dump(level + 1, frm, ctype, len,
1507 case AVRCP_GET_PLAY_STATUS:
1508 avrcp_get_play_status_dump(level + 1, frm, ctype, len);
1510 case AVRCP_REGISTER_NOTIFICATION:
1511 avrcp_register_notification_dump(level + 1, frm, ctype, len);
1513 case AVRCP_SET_ABSOLUTE_VOLUME:
1514 avrcp_set_absolute_volume_dump(level + 1, frm, ctype, len);
1516 case AVRCP_SET_ADDRESSED_PLAYER:
1517 avrcp_set_addressed_player(level + 1, frm, ctype, len);
1519 case AVRCP_PLAY_ITEM:
1520 avrcp_play_item_dump(level + 1, frm, ctype, len);
1522 case AVRCP_ADD_TO_NOW_PLAYING:
1523 avrcp_add_to_now_playing_dump(level + 1, frm, ctype, len);
1526 raw_dump(level, frm);
1530 static char *op2str(uint8_t op)
1532 switch (op & 0x7f) {
1533 case AVC_PANEL_VOLUME_UP:
1535 case AVC_PANEL_VOLUME_DOWN:
1536 return "VOLUME DOWN";
1537 case AVC_PANEL_MUTE:
1539 case AVC_PANEL_PLAY:
1541 case AVC_PANEL_STOP:
1543 case AVC_PANEL_PAUSE:
1545 case AVC_PANEL_RECORD:
1547 case AVC_PANEL_REWIND:
1549 case AVC_PANEL_FAST_FORWARD:
1550 return "FAST FORWARD";
1551 case AVC_PANEL_EJECT:
1553 case AVC_PANEL_FORWARD:
1555 case AVC_PANEL_BACKWARD:
1563 static void avrcp_passthrough_dump(int level, struct frame *frm)
1567 p_indent(level, frm);
1570 printf("Operation: 0x%02x (%s %s)\n", op, op2str(op),
1571 op & 0x80 ? "Released" : "Pressed");
1573 p_indent(level, frm);
1577 printf("Lenght: 0x%02x\n", len);
1579 raw_dump(level, frm);
1582 static const char *subunit2str(uint8_t subunit)
1585 case AVC_SUBUNIT_MONITOR:
1587 case AVC_SUBUNIT_AUDIO:
1589 case AVC_SUBUNIT_PRINTER:
1591 case AVC_SUBUNIT_DISC:
1593 case AVC_SUBUNIT_TAPE:
1595 case AVC_SUBUNIT_TURNER:
1597 case AVC_SUBUNIT_CA:
1599 case AVC_SUBUNIT_CAMERA:
1601 case AVC_SUBUNIT_PANEL:
1603 case AVC_SUBUNIT_BULLETIN_BOARD:
1604 return "Bulleting Board";
1605 case AVC_SUBUNIT_CAMERA_STORAGE:
1606 return "Camera Storage";
1607 case AVC_SUBUNIT_VENDOR_UNIQUE:
1608 return "Vendor Unique";
1609 case AVC_SUBUNIT_EXTENDED:
1610 return "Extended to next byte";
1611 case AVC_SUBUNIT_UNIT:
1618 static const char *playertype2str(uint8_t type)
1620 switch (type & 0x0F) {
1626 return "Audio, Video";
1628 return "Audio Broadcasting";
1630 return "Audio, Audio Broadcasting";
1632 return "Video, Audio Broadcasting";
1634 return "Audio, Video, Audio Broadcasting";
1636 return "Video Broadcasting";
1638 return "Audio, Video Broadcasting";
1640 return "Video, Video Broadcasting";
1642 return "Audio, Video, Video Broadcasting";
1644 return "Audio Broadcasting, Video Broadcasting";
1646 return "Audio, Audio Broadcasting, Video Broadcasting";
1648 return "Video, Audio Broadcasting, Video Broadcasting";
1650 return "Audio, Video, Audio Broadcasting, Video Broadcasting";
1656 static const char *playersubtype2str(uint32_t subtype)
1658 switch (subtype & 0x03) {
1660 return "Audio Book";
1664 return "Audio Book, Podcast";
1670 static void avrcp_media_player_item_dump(int level, struct frame *frm,
1673 uint16_t id, charset, namelen;
1674 uint8_t type, status;
1676 uint64_t features[2];
1678 p_indent(level, frm);
1681 printf("PDU Malformed\n");
1682 raw_dump(level, frm);
1687 printf("PlayerID: 0x%04x (%u)\n", id, id);
1689 p_indent(level, frm);
1692 printf("PlayerType: 0x%04x (%s)\n", type, playertype2str(type));
1694 p_indent(level, frm);
1696 subtype = get_u32(frm);
1697 printf("PlayerSubtype: 0x%08x (%s)\n", subtype,
1698 playersubtype2str(subtype));
1700 p_indent(level, frm);
1702 status = get_u8(frm);
1703 printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
1705 p_indent(level, frm);
1707 get_u128(frm, &features[0], &features[1]);
1708 printf("Features: 0x%16" PRIx64 "%16" PRIx64 "\n", features[1],
1711 p_indent(level, frm);
1713 charset = get_u16(frm);
1714 printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1716 p_indent(level, frm);
1718 namelen = get_u16(frm);
1719 printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1721 p_indent(level, frm);
1724 for (; namelen > 0; namelen--) {
1725 uint8_t c = get_u8(frm);
1726 printf("%1c", isprint(c) ? c : '.');
1731 static const char *foldertype2str(uint8_t type)
1753 static void avrcp_folder_item_dump(int level, struct frame *frm, uint16_t len)
1755 uint8_t type, playable;
1756 uint16_t charset, namelen;
1759 p_indent(level, frm);
1762 printf("PDU Malformed\n");
1763 raw_dump(level, frm);
1768 printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1770 p_indent(level, frm);
1773 printf("FolderType: 0x%02x (%s)\n", type, foldertype2str(type));
1775 p_indent(level, frm);
1777 playable = get_u8(frm);
1778 printf("IsPlayable: 0x%02x (%s)\n", playable,
1779 playable & 0x01 ? "True" : "False");
1781 p_indent(level, frm);
1783 charset = get_u16(frm);
1784 printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1786 p_indent(level, frm);
1788 namelen = get_u16(frm);
1789 printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1791 p_indent(level, frm);
1794 for (; namelen > 0; namelen--) {
1795 uint8_t c = get_u8(frm);
1796 printf("%1c", isprint(c) ? c : '.');
1801 static const char *elementtype2str(uint8_t type)
1813 static void avrcp_attribute_entry_list_dump(int level, struct frame *frm,
1816 for (; count > 0; count--) {
1821 p_indent(level, frm);
1823 attr = get_u32(frm);
1824 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
1826 p_indent(level, frm);
1828 charset = get_u16(frm);
1829 printf("CharsetID: 0x%04x (%s)\n", charset,
1830 charset2str(charset));
1832 p_indent(level, frm);
1835 printf("AttributeLength: 0x%04x (%u)\n", len, len);
1837 p_indent(level, frm);
1839 printf("AttributeValue: ");
1840 for (; len > 0; len--) {
1841 uint8_t c = get_u8(frm);
1842 printf("%1c", isprint(c) ? c : '.');
1848 static void avrcp_media_element_item_dump(int level, struct frame *frm,
1852 uint16_t charset, namelen;
1853 uint8_t type, count;
1855 p_indent(level, frm);
1858 printf("PDU Malformed\n");
1859 raw_dump(level, frm);
1864 printf("ElementUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1866 p_indent(level, frm);
1869 printf("ElementType: 0x%02x (%s)\n", type, elementtype2str(type));
1871 p_indent(level, frm);
1873 charset = get_u16(frm);
1874 printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1876 p_indent(level, frm);
1878 namelen = get_u16(frm);
1879 printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1881 p_indent(level, frm);
1884 for (; namelen > 0; namelen--) {
1885 uint8_t c = get_u8(frm);
1886 printf("%1c", isprint(c) ? c : '.');
1890 p_indent(level, frm);
1892 count = get_u8(frm);
1893 printf("AttributeCount: 0x%02x (%u)\n", count, count);
1895 avrcp_attribute_entry_list_dump(level, frm, count);
1898 static void avrcp_get_folder_items_dump(int level, struct frame *frm,
1899 uint8_t hdr, uint16_t len)
1901 uint8_t scope, count, status;
1902 uint32_t start, end;
1905 p_indent(level, frm);
1911 printf("PDU Malformed\n");
1912 raw_dump(level, frm);
1916 scope = get_u8(frm);
1917 printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1919 p_indent(level, frm);
1921 start = get_u32(frm);
1922 printf("StartItem: 0x%08x (%u)\n", start, start);
1924 p_indent(level, frm);
1927 printf("EndItem: 0x%08x (%u)\n", end, end);
1929 p_indent(level, frm);
1931 count = get_u8(frm);
1932 printf("AttributeCount: 0x%02x (%u)\n", count, count);
1934 for (; count > 0; count--) {
1937 p_indent(level, frm);
1939 attr = get_u32(frm);
1940 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
1946 status = get_u8(frm);
1947 printf("Status: 0x%02x (%s)\n", status, error2str(status));
1952 p_indent(level, frm);
1955 printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1957 p_indent(level, frm);
1960 printf("Number of Items: 0x%04x (%u)\n", num, num);
1962 for (; num > 0; num--) {
1966 p_indent(level, frm);
1972 printf("Item: 0x01 (Media Player)) ");
1973 printf("Length: 0x%04x (%u)\n", len, len);
1974 avrcp_media_player_item_dump(level, frm, len);
1977 printf("Item: 0x02 (Folder) ");
1978 printf("Length: 0x%04x (%u)\n", len, len);
1979 avrcp_folder_item_dump(level, frm, len);
1982 printf("Item: 0x03 (Media Element) ");
1983 printf("Length: 0x%04x (%u)\n", len, len);
1984 avrcp_media_element_item_dump(level, frm, len);
1990 static const char *dir2str(uint8_t dir)
1996 return "Folder Down";
2002 static void avrcp_change_path_dump(int level, struct frame *frm, uint8_t hdr,
2007 uint16_t uidcounter;
2008 uint8_t dir, status;
2010 p_indent(level, frm);
2016 printf("PDU Malformed\n");
2017 raw_dump(level, frm);
2021 uidcounter = get_u16(frm);
2022 printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2024 p_indent(level, frm);
2027 printf("Direction: 0x%02x (%s)\n", dir, dir2str(dir));
2029 p_indent(level, frm);
2032 printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
2037 status = get_u8(frm);
2038 printf("Status: 0x%02x (%s)\n", status, error2str(status));
2043 p_indent(level, frm);
2045 items = get_u32(frm);
2046 printf("Number of Items: 0x%04x (%u)", items, items);
2049 static void avrcp_get_item_attributes_dump(int level, struct frame *frm,
2050 uint8_t hdr, uint16_t len)
2053 uint32_t uidcounter;
2054 uint8_t scope, count, status;
2056 p_indent(level, frm);
2062 printf("PDU Malformed\n");
2063 raw_dump(level, frm);
2067 scope = get_u8(frm);
2068 printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
2070 p_indent(level, frm);
2073 printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
2075 p_indent(level, frm);
2077 uidcounter = get_u16(frm);
2078 printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2080 p_indent(level, frm);
2082 count = get_u8(frm);
2083 printf("AttributeCount: 0x%02x (%u)\n", count, count);
2085 for (; count > 0; count--) {
2088 p_indent(level, frm);
2090 attr = get_u32(frm);
2091 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
2097 status = get_u8(frm);
2098 printf("Status: 0x%02x (%s)\n", status, error2str(status));
2103 p_indent(level, frm);
2105 count = get_u8(frm);
2106 printf("AttributeCount: 0x%02x (%u)\n", count, count);
2108 avrcp_attribute_entry_list_dump(level, frm, count);
2111 static void avrcp_search_dump(int level, struct frame *frm, uint8_t hdr,
2114 uint32_t uidcounter, items;
2115 uint16_t charset, namelen;
2118 p_indent(level, frm);
2124 printf("PDU Malformed\n");
2125 raw_dump(level, frm);
2129 charset = get_u16(frm);
2130 printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
2132 p_indent(level, frm);
2134 namelen = get_u16(frm);
2135 printf("Length: 0x%04x (%u)\n", namelen, namelen);
2137 p_indent(level, frm);
2140 for (; namelen > 0; namelen--) {
2141 uint8_t c = get_u8(frm);
2142 printf("%1c", isprint(c) ? c : '.');
2149 status = get_u8(frm);
2150 printf("Status: 0x%02x (%s)\n", status, error2str(status));
2155 p_indent(level, frm);
2157 uidcounter = get_u16(frm);
2158 printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2160 p_indent(level, frm);
2162 items = get_u32(frm);
2163 printf("Number of Items: 0x%04x (%u)", items, items);
2166 static void avrcp_general_reject_dump(int level, struct frame *frm,
2167 uint8_t hdr, uint16_t len)
2171 p_indent(level, frm);
2176 printf("PDU Malformed\n");
2177 raw_dump(level, frm);
2181 status = get_u8(frm);
2182 printf("Status: 0x%02x (%s)\n", status, error2str(status));
2185 static void avrcp_browsing_dump(int level, struct frame *frm, uint8_t hdr)
2190 pduid = get_u8(frm);
2193 printf("AVRCP: %s: len 0x%04x\n", pdu2str(pduid), len);
2195 if (len != frm->len) {
2196 p_indent(level, frm);
2197 printf("PDU Malformed\n");
2198 raw_dump(level, frm);
2203 case AVRCP_SET_BROWSED_PLAYER:
2204 avrcp_set_browsed_player_dump(level + 1, frm, hdr, len);
2206 case AVRCP_GET_FOLDER_ITEMS:
2207 avrcp_get_folder_items_dump(level + 1, frm, hdr, len);
2209 case AVRCP_CHANGE_PATH:
2210 avrcp_change_path_dump(level + 1, frm, hdr, len);
2212 case AVRCP_GET_ITEM_ATTRIBUTES:
2213 avrcp_get_item_attributes_dump(level + 1, frm, hdr, len);
2216 avrcp_search_dump(level + 1, frm, hdr, len);
2218 case AVRCP_GENERAL_REJECT:
2219 avrcp_general_reject_dump(level + 1, frm, hdr, len);
2222 raw_dump(level, frm);
2226 static void avrcp_control_dump(int level, struct frame *frm)
2228 uint8_t ctype, address, subunit, opcode, company[3];
2231 ctype = get_u8(frm);
2232 address = get_u8(frm);
2233 opcode = get_u8(frm);
2235 printf("AV/C: %s: address 0x%02x opcode 0x%02x\n", ctype2str(ctype),
2238 p_indent(level + 1, frm);
2240 subunit = address >> 3;
2241 printf("Subunit: %s\n", subunit2str(subunit));
2243 p_indent(level + 1, frm);
2245 printf("Opcode: %s\n", opcode2str(opcode));
2247 /* Skip non-panel subunit packets */
2248 if (subunit != AVC_SUBUNIT_PANEL) {
2249 raw_dump(level, frm);
2253 /* Not implemented should not contain any operand */
2254 if (ctype == AVC_CTYPE_NOT_IMPLEMENTED) {
2255 raw_dump(level, frm);
2260 case AVC_OP_PASSTHROUGH:
2261 avrcp_passthrough_dump(level + 1, frm);
2263 case AVC_OP_VENDORDEP:
2264 p_indent(level + 1, frm);
2266 printf("Company ID: 0x");
2267 for (i = 0; i < 3; i++) {
2268 company[i] = get_u8(frm);
2269 printf("%02x", company[i]);
2273 avrcp_pdu_dump(level + 1, frm, ctype);
2276 raw_dump(level, frm);
2280 void avrcp_dump(int level, struct frame *frm, uint8_t hdr, uint16_t psm)
2282 p_indent(level, frm);
2286 avrcp_control_dump(level, frm);
2289 avrcp_browsing_dump(level, frm, hdr);
2292 raw_dump(level, frm);