tizen 2.3.1 release
[framework/connectivity/bluez.git] / tools / parser / avrcp.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2011 Intel Corporation.
6  *
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <inttypes.h>
35
36 #include "parser.h"
37
38 /* ctype entries */
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
51
52 /* subunit type */
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
67
68 /* opcodes */
69 #define AVC_OP_VENDORDEP                0x00
70 #define AVC_OP_UNITINFO                 0x30
71 #define AVC_OP_SUBUNITINFO              0x31
72 #define AVC_OP_PASSTHROUGH              0x7c
73
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
87
88 /* Packet types */
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
93
94 /* pdu ids */
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
119
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
134
135 /* error statuses */
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
158
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
165
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
175
176 /* play status */
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
183
184 /* media scope */
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
189
190 static struct avrcp_continuing {
191         uint16_t num;
192         uint16_t size;
193 } avrcp_continuing;
194
195 static const char *ctype2str(uint8_t ctype)
196 {
197         switch (ctype & 0x0f) {
198         case AVC_CTYPE_CONTROL:
199                 return "Control";
200         case AVC_CTYPE_STATUS:
201                 return "Status";
202         case AVC_CTYPE_SPECIFIC_INQUIRY:
203                 return "Specific Inquiry";
204         case AVC_CTYPE_NOTIFY:
205                 return "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:
211                 return "Accepted";
212         case AVC_CTYPE_REJECTED:
213                 return "Rejected";
214         case AVC_CTYPE_IN_TRANSITION:
215                 return "In Transition";
216         case AVC_CTYPE_STABLE:
217                 return "Stable";
218         case AVC_CTYPE_CHANGED:
219                 return "Changed";
220         case AVC_CTYPE_INTERIM:
221                 return "Interim";
222         default:
223                 return "Unknown";
224         }
225 }
226
227 static const char *opcode2str(uint8_t opcode)
228 {
229         switch (opcode) {
230         case AVC_OP_VENDORDEP:
231                 return "Vendor Dependent";
232         case AVC_OP_UNITINFO:
233                 return "Unit Info";
234         case AVC_OP_SUBUNITINFO:
235                 return "Subunit Info";
236         case AVC_OP_PASSTHROUGH:
237                 return "Passthrough";
238         default:
239                 return "Unknown";
240         }
241 }
242
243 static const char *pt2str(uint8_t pt)
244 {
245         switch (pt) {
246         case AVRCP_PACKET_TYPE_SINGLE:
247                 return "Single";
248         case AVRCP_PACKET_TYPE_START:
249                 return "Start";
250         case AVRCP_PACKET_TYPE_CONTINUING:
251                 return "Continuing";
252         case AVRCP_PACKET_TYPE_END:
253                 return "End";
254         default:
255                 return "Unknown";
256         }
257 }
258
259 static const char *pdu2str(uint8_t pduid)
260 {
261         switch (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:
299                 return "ChangePath";
300         case AVRCP_GET_ITEM_ATTRIBUTES:
301                 return "GetItemAttributes";
302         case AVRCP_PLAY_ITEM:
303                 return "PlayItem";
304         case AVRCP_SEARCH:
305                 return "Search";
306         case AVRCP_ADD_TO_NOW_PLAYING:
307                 return "AddToNowPlaying";
308         case AVRCP_GENERAL_REJECT:
309                 return "GeneralReject";
310         default:
311                 return "Unknown";
312         }
313 }
314
315 static char *cap2str(uint8_t cap)
316 {
317         switch (cap) {
318         case 0x2:
319                 return "CompanyID";
320         case 0x3:
321                 return "EventsID";
322         default:
323                 return "Unknown";
324         }
325 }
326
327 static char *event2str(uint8_t event)
328 {
329         switch (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";
356         default:
357                 return "Reserved";
358         }
359 }
360
361 static const char *error2str(uint8_t status)
362 {
363         switch (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:
369                 return "Not Found";
370         case AVRCP_STATUS_INTERNAL_ERROR:
371                 return "Internal Error";
372         case AVRCP_STATUS_SUCCESS:
373                 return "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";
408         default:
409                 return "Unknown";
410         }
411 }
412
413 static void avrcp_rejected_dump(int level, struct frame *frm, uint16_t len)
414 {
415         uint8_t status;
416
417         p_indent(level, frm);
418
419         if (len < 1) {
420                 printf("PDU Malformed\n");
421                 raw_dump(level, frm);
422                 return;
423         }
424
425         status = get_u8(frm);
426         printf("Error: 0x%02x (%s)\n", status, error2str(status));
427 }
428
429 static void avrcp_get_capabilities_dump(int level, struct frame *frm, uint16_t len)
430 {
431         uint8_t cap;
432         uint8_t count;
433
434         p_indent(level, frm);
435
436         if (len < 1) {
437                 printf("PDU Malformed\n");
438                 raw_dump(level, frm);
439                 return;
440         }
441
442         cap = get_u8(frm);
443         printf("CapabilityID: 0x%02x (%s)\n", cap, cap2str(cap));
444
445         if (len == 1)
446                 return;
447
448         p_indent(level, frm);
449
450         count = get_u8(frm);
451         printf("CapabilityCount: 0x%02x\n", count);
452
453         switch (cap) {
454         case 0x2:
455                 for (; count > 0; count--) {
456                         int i;
457
458                         p_indent(level, frm);
459
460                         printf("%s: 0x", cap2str(cap));
461                         for (i = 0; i < 3; i++)
462                                 printf("%02x", get_u8(frm));
463                         printf("\n");
464                 }
465                 break;
466         case 0x3:
467                 for (; count > 0; count--) {
468                         uint8_t event;
469
470                         p_indent(level, frm);
471
472                         event = get_u8(frm);
473                         printf("%s: 0x%02x (%s)\n", cap2str(cap), event,
474                                                         event2str(event));
475                 }
476                 break;
477         default:
478                 raw_dump(level, frm);
479         }
480 }
481
482 static const char *attr2str(uint8_t attr)
483 {
484         switch (attr) {
485         case AVRCP_ATTRIBUTE_ILEGAL:
486                 return "Illegal";
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";
495         default:
496                 return "Unknown";
497         }
498 }
499
500 static void avrcp_list_player_attributes_dump(int level, struct frame *frm,
501                                                                 uint16_t len)
502 {
503         uint8_t num;
504
505         if (len == 0)
506                 return;
507
508         p_indent(level, frm);
509
510         num = get_u8(frm);
511         printf("AttributeCount: 0x%02x\n", num);
512
513         for (; num > 0; num--) {
514                 uint8_t attr;
515
516                 p_indent(level, frm);
517
518                 attr = get_u8(frm);
519                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
520         }
521 }
522
523 static const char *value2str(uint8_t attr, uint8_t value)
524 {
525         switch (attr) {
526         case AVRCP_ATTRIBUTE_ILEGAL:
527                 return "Illegal";
528         case AVRCP_ATTRIBUTE_EQUALIZER:
529                 switch (value) {
530                 case 0x01:
531                         return "OFF";
532                 case 0x02:
533                         return "ON";
534                 default:
535                         return "Reserved";
536                 }
537         case AVRCP_ATTRIBUTE_REPEAT_MODE:
538                 switch (value) {
539                 case 0x01:
540                         return "OFF";
541                 case 0x02:
542                         return "Single Track Repeat";
543                 case 0x03:
544                         return "All Track Repeat";
545                 case 0x04:
546                         return "Group Repeat";
547                 default:
548                         return "Reserved";
549                 }
550         case AVRCP_ATTRIBUTE_SHUFFLE:
551                 switch (value) {
552                 case 0x01:
553                         return "OFF";
554                 case 0x02:
555                         return "All Track Suffle";
556                 case 0x03:
557                         return "Group Suffle";
558                 default:
559                         return "Reserved";
560                 }
561         case AVRCP_ATTRIBUTE_SCAN:
562                 switch (value) {
563                 case 0x01:
564                         return "OFF";
565                 case 0x02:
566                         return "All Track Scan";
567                 case 0x03:
568                         return "Group Scan";
569                 default:
570                         return "Reserved";
571                 }
572         default:
573                 return "Unknown";
574         }
575 }
576
577 static void avrcp_list_player_values_dump(int level, struct frame *frm,
578                                                 uint8_t ctype, uint16_t len)
579 {
580         static uint8_t attr = 0; /* Remember attribute */
581         uint8_t num;
582
583         p_indent(level, frm);
584
585         if (len < 1) {
586                 printf("PDU Malformed\n");
587                 raw_dump(level, frm);
588                 return;
589         }
590
591         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
592                 goto response;
593
594         attr = get_u8(frm);
595         printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
596
597         return;
598
599 response:
600         num = get_u8(frm);
601         printf("ValueCount: 0x%02x\n", num);
602
603         for (; num > 0; num--) {
604                 uint8_t value;
605
606                 p_indent(level, frm);
607
608                 value = get_u8(frm);
609                 printf("ValueID: 0x%02x (%s)\n", value,
610                                                 value2str(attr, value));
611         }
612 }
613
614 static void avrcp_get_current_player_value_dump(int level, struct frame *frm,
615                                                 uint8_t ctype, uint16_t len)
616 {
617         uint8_t num;
618
619         p_indent(level, frm);
620
621         if (len < 1) {
622                 printf("PDU Malformed\n");
623                 raw_dump(level, frm);
624                 return;
625         }
626
627         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
628                 goto response;
629
630         num = get_u8(frm);
631         printf("AttributeCount: 0x%02x\n", num);
632
633         for (; num > 0; num--) {
634                 uint8_t attr;
635
636                 p_indent(level, frm);
637
638                 attr = get_u8(frm);
639                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
640         }
641
642         return;
643
644 response:
645         num = get_u8(frm);
646         printf("ValueCount: 0x%02x\n", num);
647
648         for (; num > 0; num--) {
649                 uint8_t attr, value;
650
651                 p_indent(level, frm);
652
653                 attr = get_u8(frm);
654                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
655
656                 p_indent(level, frm);
657
658                 value = get_u8(frm);
659                 printf("ValueID: 0x%02x (%s)\n", value,
660                                                 value2str(attr, value));
661         }
662 }
663
664 static void avrcp_set_player_value_dump(int level, struct frame *frm,
665                                                 uint8_t ctype, uint16_t len)
666 {
667         uint8_t num;
668
669         p_indent(level, frm);
670
671         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
672                 return;
673
674         if (len < 1) {
675                 printf("PDU Malformed\n");
676                 raw_dump(level, frm);
677                 return;
678         }
679
680         num = get_u8(frm);
681         printf("AttributeCount: 0x%02x\n", num);
682
683         for (; num > 0; num--) {
684                 uint8_t attr, value;
685
686                 p_indent(level, frm);
687
688                 attr = get_u8(frm);
689                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
690
691                 p_indent(level, frm);
692
693                 value = get_u8(frm);
694                 printf("ValueID: 0x%02x (%s)\n", value,
695                                                 value2str(attr, value));
696         }
697 }
698
699 static const char *charset2str(uint16_t charset)
700 {
701         switch (charset) {
702         case 1:
703         case 2:
704                 return "Reserved";
705         case 3:
706                 return "ASCII";
707         case 4:
708                 return "ISO_8859-1";
709         case 5:
710                 return "ISO_8859-2";
711         case 6:
712                 return "ISO_8859-3";
713         case 7:
714                 return "ISO_8859-4";
715         case 8:
716                 return "ISO_8859-5";
717         case 9:
718                 return "ISO_8859-6";
719         case 10:
720                 return "ISO_8859-7";
721         case 11:
722                 return "ISO_8859-8";
723         case 12:
724                 return "ISO_8859-9";
725         case 106:
726                 return "UTF-8";
727         default:
728                 return "Unknown";
729         }
730 }
731
732 static void avrcp_get_player_attribute_text_dump(int level, struct frame *frm,
733                                                 uint8_t ctype, uint16_t len)
734 {
735         uint8_t num;
736
737         p_indent(level, frm);
738
739         if (len < 1) {
740                 printf("PDU Malformed\n");
741                 raw_dump(level, frm);
742                 return;
743         }
744
745         num = get_u8(frm);
746         printf("AttributeCount: 0x%02x\n", num);
747
748         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
749                 goto response;
750
751         for (; num > 0; num--) {
752                 uint8_t attr;
753
754                 p_indent(level, frm);
755
756                 attr = get_u8(frm);
757                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
758         }
759
760         return;
761
762 response:
763         for (; num > 0; num--) {
764                 uint8_t attr, len;
765                 uint16_t charset;
766
767                 p_indent(level, frm);
768
769                 attr = get_u8(frm);
770                 printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
771
772                 p_indent(level, frm);
773
774                 charset = get_u16(frm);
775                 printf("CharsetID: 0x%04x (%s)\n", charset,
776                                                         charset2str(charset));
777
778                 p_indent(level, frm);
779
780                 len = get_u8(frm);
781                 printf("StringLength: 0x%02x\n", len);
782
783                 p_indent(level, frm);
784
785                 printf("String: ");
786                 for (; len > 0; len--) {
787                         uint8_t c = get_u8(frm);
788                         printf("%1c", isprint(c) ? c : '.');
789                 }
790                 printf("\n");
791         }
792 }
793
794 static void avrcp_get_player_value_text_dump(int level, struct frame *frm,
795                                                 uint8_t ctype, uint16_t len)
796 {
797         static uint8_t attr = 0; /* Remember attribute */
798         uint8_t num;
799
800         p_indent(level, frm);
801
802         if (len < 1) {
803                 printf("PDU Malformed\n");
804                 raw_dump(level, frm);
805                 return;
806         }
807
808         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
809                 goto response;
810
811         attr = get_u8(frm);
812         printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
813
814         p_indent(level, frm);
815
816         num = get_u8(frm);
817         printf("ValueCount: 0x%02x\n", num);
818
819         for (; num > 0; num--) {
820                 uint8_t value;
821
822                 p_indent(level, frm);
823
824                 value = get_u8(frm);
825                 printf("ValueID: 0x%02x (%s)\n", value,
826                                                 value2str(attr, value));
827         }
828
829         return;
830
831 response:
832         num = get_u8(frm);
833         printf("ValueCount: 0x%02x\n", num);
834
835         for (; num > 0; num--) {
836                 uint8_t value, len;
837                 uint16_t charset;
838
839                 p_indent(level, frm);
840
841                 value = get_u8(frm);
842                 printf("ValueID: 0x%02x (%s)\n", value,
843                                                 value2str(attr, value));
844
845                 p_indent(level, frm);
846
847                 charset = get_u16(frm);
848                 printf("CharsetID: 0x%04x (%s)\n", charset,
849                                                         charset2str(charset));
850
851                 p_indent(level, frm);
852
853                 len = get_u8(frm);
854                 printf("StringLength: 0x%02x\n", len);
855
856                 p_indent(level, frm);
857
858                 printf("String: ");
859                 for (; len > 0; len--) {
860                         uint8_t c = get_u8(frm);
861                         printf("%1c", isprint(c) ? c : '.');
862                 }
863                 printf("\n");
864         }
865 }
866
867 static void avrcp_displayable_charset(int level, struct frame *frm,
868                                                 uint8_t ctype, uint16_t len)
869 {
870         uint8_t num;
871
872         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
873                 return;
874
875         p_indent(level, frm);
876
877         if (len < 2) {
878                 printf("PDU Malformed\n");
879                 raw_dump(level, frm);
880                 return;
881         }
882
883         num = get_u8(frm);
884         printf("CharsetCount: 0x%02x\n", num);
885
886         for (; num > 0; num--) {
887                 uint16_t charset;
888
889                 p_indent(level, frm);
890
891                 charset = get_u16(frm);
892                 printf("CharsetID: 0x%04x (%s)\n", charset,
893                                                         charset2str(charset));
894         }
895 }
896
897 static const char *status2str(uint8_t status)
898 {
899         switch (status) {
900         case 0x0:
901                 return "NORMAL";
902         case 0x1:
903                 return "WARNING";
904         case 0x2:
905                 return "CRITICAL";
906         case 0x3:
907                 return "EXTERNAL";
908         case 0x4:
909                 return "FULL_CHARGE";
910         default:
911                 return "Reserved";
912         }
913 }
914
915 static void avrcp_ct_battery_status_dump(int level, struct frame *frm,
916                                                 uint8_t ctype, uint16_t len)
917 {
918         uint8_t status;
919
920         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
921                 return;
922
923         p_indent(level, frm);
924
925         status = get_u8(frm);
926         printf("BatteryStatus: 0x%02x (%s)\n", status, status2str(status));
927 }
928
929 static const char *mediattr2str(uint32_t attr)
930 {
931         switch (attr) {
932         case AVRCP_MEDIA_ATTRIBUTE_ILLEGAL:
933                 return "Illegal";
934         case AVRCP_MEDIA_ATTRIBUTE_TITLE:
935                 return "Title";
936         case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
937                 return "Artist";
938         case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
939                 return "Album";
940         case AVRCP_MEDIA_ATTRIBUTE_TRACK:
941                 return "Track";
942         case AVRCP_MEDIA_ATTRIBUTE_TOTAL:
943                 return "Track Total";
944         case AVRCP_MEDIA_ATTRIBUTE_GENRE:
945                 return "Genre";
946         case AVRCP_MEDIA_ATTRIBUTE_DURATION:
947                 return "Track duration";
948         default:
949                 return "Reserved";
950         }
951 }
952
953 static void avrcp_get_element_attributes_dump(int level, struct frame *frm,
954                                                 uint8_t ctype, uint16_t len,
955                                                 uint8_t pt)
956 {
957         uint64_t id;
958         uint8_t num;
959
960         p_indent(level, frm);
961
962         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
963                 goto response;
964
965         if (len < 9) {
966                 printf("PDU Malformed\n");
967                 raw_dump(level, frm);
968                 return;
969         }
970
971         id = get_u64(frm);
972         printf("Identifier: 0x%jx (%s)\n", id, id ? "Reserved" : "PLAYING");
973
974         p_indent(level, frm);
975
976         num = get_u8(frm);
977         printf("AttributeCount: 0x%02x\n", num);
978
979         for (; num > 0; num--) {
980                 uint32_t attr;
981
982                 p_indent(level, frm);
983
984                 attr = get_u32(frm);
985                 printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
986         }
987
988         return;
989
990 response:
991         if (pt == AVRCP_PACKET_TYPE_SINGLE || pt == AVRCP_PACKET_TYPE_START) {
992                 if (len < 1) {
993                         printf("PDU Malformed\n");
994                         raw_dump(level, frm);
995                         return;
996                 }
997
998                 num = get_u8(frm);
999                 avrcp_continuing.num = num;
1000                 printf("AttributeCount: 0x%02x\n", num);
1001                 len--;
1002         } else {
1003                 num = avrcp_continuing.num;
1004
1005                 if (avrcp_continuing.size > 0) {
1006                         uint16_t size;
1007
1008                         if (avrcp_continuing.size > len) {
1009                                 size = len;
1010                                 avrcp_continuing.size -= len;
1011                         } else {
1012                                 size = avrcp_continuing.size;
1013                                 avrcp_continuing.size = 0;
1014                         }
1015
1016                         printf("ContinuingAttributeValue: ");
1017                         for (; size > 0; size--) {
1018                                 uint8_t c = get_u8(frm);
1019                                 printf("%1c", isprint(c) ? c : '.');
1020                         }
1021                         printf("\n");
1022
1023                         len -= size;
1024                 }
1025         }
1026
1027         while (num > 0 && len > 0) {
1028                 uint32_t attr;
1029                 uint16_t charset, attrlen;
1030
1031                 p_indent(level, frm);
1032
1033                 attr = get_u32(frm);
1034                 printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
1035
1036                 p_indent(level, frm);
1037
1038                 charset = get_u16(frm);
1039                 printf("CharsetID: 0x%04x (%s)\n", charset,
1040                                                         charset2str(charset));
1041
1042                 p_indent(level, frm);
1043                 attrlen = get_u16(frm);
1044                 printf("AttributeValueLength: 0x%04x\n", attrlen);
1045
1046                 len -= sizeof(attr) + sizeof(charset) + sizeof(attrlen);
1047                 num--;
1048
1049                 p_indent(level, frm);
1050
1051                 printf("AttributeValue: ");
1052                 for (; attrlen > 0 && len > 0; attrlen--, len--) {
1053                         uint8_t c = get_u8(frm);
1054                         printf("%1c", isprint(c) ? c : '.');
1055                 }
1056                 printf("\n");
1057
1058                 if (attrlen > 0)
1059                         avrcp_continuing.size = attrlen;
1060         }
1061
1062         avrcp_continuing.num = num;
1063 }
1064
1065 static const char *playstatus2str(uint8_t status)
1066 {
1067         switch (status) {
1068         case AVRCP_PLAY_STATUS_STOPPED:
1069                 return "STOPPED";
1070         case AVRCP_PLAY_STATUS_PLAYING:
1071                 return "PLAYING";
1072         case AVRCP_PLAY_STATUS_PAUSED:
1073                 return "PAUSED";
1074         case AVRCP_PLAY_STATUS_FWD_SEEK:
1075                 return "FWD_SEEK";
1076         case AVRCP_PLAY_STATUS_REV_SEEK:
1077                 return "REV_SEEK";
1078         case AVRCP_PLAY_STATUS_ERROR:
1079                 return "ERROR";
1080         default:
1081                 return "Unknown";
1082         }
1083 }
1084
1085 static void avrcp_get_play_status_dump(int level, struct frame *frm,
1086                                                 uint8_t ctype, uint16_t len)
1087 {
1088         uint32_t interval;
1089         uint8_t status;
1090
1091         if (ctype <= AVC_CTYPE_GENERAL_INQUIRY)
1092                 return;
1093
1094         p_indent(level, frm);
1095
1096         if (len < 9) {
1097                 printf("PDU Malformed\n");
1098                 raw_dump(level, frm);
1099                 return;
1100         }
1101
1102         interval = get_u32(frm);
1103         printf("SongLength: 0x%08x (%u miliseconds)\n", interval, interval);
1104
1105         p_indent(level, frm);
1106
1107         interval = get_u32(frm);
1108         printf("SongPosition: 0x%08x (%u miliconds)\n", interval, interval);
1109
1110         p_indent(level, frm);
1111
1112         status = get_u8(frm);
1113         printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
1114 }
1115
1116 static void avrcp_register_notification_dump(int level, struct frame *frm,
1117                                                 uint8_t ctype, uint16_t len)
1118 {
1119         uint8_t event, status;
1120         uint16_t uid;
1121         uint32_t interval;
1122         uint64_t id;
1123
1124         p_indent(level, frm);
1125
1126         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1127                 goto response;
1128
1129         if (len < 5) {
1130                 printf("PDU Malformed\n");
1131                 raw_dump(level, frm);
1132                 return;
1133         }
1134
1135         event = get_u8(frm);
1136         printf("EventID: 0x%02x (%s)\n", event, event2str(event));
1137
1138         p_indent(level, frm);
1139
1140         interval = get_u32(frm);
1141         printf("Interval: 0x%08x (%u seconds)\n", interval, interval);
1142
1143         return;
1144
1145 response:
1146         if (len < 1) {
1147                 printf("PDU Malformed\n");
1148                 raw_dump(level, frm);
1149                 return;
1150         }
1151
1152         event = get_u8(frm);
1153         printf("EventID: 0x%02x (%s)\n", event, event2str(event));
1154
1155         p_indent(level, frm);
1156
1157         switch (event) {
1158         case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
1159                 status = get_u8(frm);
1160                 printf("PlayStatus: 0x%02x (%s)\n", status,
1161                                                 playstatus2str(status));
1162                 break;
1163         case AVRCP_EVENT_TRACK_CHANGED:
1164                 id = get_u64(frm);
1165                 printf("Identifier: 0x%16" PRIx64 " (%" PRIu64 ")\n", id, id);
1166                 break;
1167         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
1168                 interval = get_u32(frm);
1169                 printf("Position: 0x%08x (%u miliseconds)\n", interval,
1170                                                                 interval);
1171                 break;
1172         case AVRCP_EVENT_BATT_STATUS_CHANGED:
1173                 status = get_u8(frm);
1174                 printf("BatteryStatus: 0x%02x (%s)\n", status,
1175                                                         status2str(status));
1176                 break;
1177         case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
1178                 status = get_u8(frm);
1179                 printf("SystemStatus: 0x%02x ", status);
1180                 switch (status) {
1181                 case 0x00:
1182                         printf("(POWER_ON)\n");
1183                         break;
1184                 case 0x01:
1185                         printf("(POWER_OFF)\n");
1186                         break;
1187                 case 0x02:
1188                         printf("(UNPLUGGED)\n");
1189                         break;
1190                 default:
1191                         printf("(UNKOWN)\n");
1192                         break;
1193                 }
1194                 break;
1195         case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
1196                 status = get_u8(frm);
1197                 printf("AttributeCount: 0x%02x\n", status);
1198
1199                 for (; status > 0; status--) {
1200                         uint8_t attr, value;
1201
1202                         p_indent(level, frm);
1203
1204                         attr = get_u8(frm);
1205                         printf("AttributeID: 0x%02x (%s)\n", attr,
1206                                                         attr2str(attr));
1207
1208                         p_indent(level, frm);
1209
1210                         value = get_u8(frm);
1211                         printf("ValueID: 0x%02x (%s)\n", value,
1212                                                 value2str(attr, value));
1213                 }
1214                 break;
1215         case AVRCP_EVENT_VOLUME_CHANGED:
1216                 status = get_u8(frm) & 0x7F;
1217                 printf("Volume: %.2f%% (%d/127)\n", status/1.27, status);
1218                 break;
1219         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
1220                 uid = get_u16(frm);
1221                 printf("PlayerID: 0x%04x (%u)\n", uid, uid);
1222
1223
1224                 p_indent(level, frm);
1225
1226                 uid = get_u16(frm);
1227                 printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1228                 break;
1229         case AVRCP_EVENT_UIDS_CHANGED:
1230                 uid = get_u16(frm);
1231                 printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1232                 break;
1233         }
1234 }
1235
1236 static void avrcp_set_absolute_volume_dump(int level, struct frame *frm,
1237                                                 uint8_t ctype, uint16_t len)
1238 {
1239         uint8_t value;
1240
1241         p_indent(level, frm);
1242
1243         if (len < 1) {
1244                 printf("PDU Malformed\n");
1245                 raw_dump(level, frm);
1246                 return;
1247         }
1248
1249         value = get_u8(frm) & 0x7F;
1250         printf("Volume: %.2f%% (%d/127)\n", value/1.27, value);
1251 }
1252
1253 static void avrcp_set_addressed_player(int level, struct frame *frm,
1254                                                 uint8_t ctype, uint16_t len)
1255 {
1256         uint16_t id;
1257         uint8_t status;
1258
1259         p_indent(level, frm);
1260
1261         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1262                 goto response;
1263
1264         if (len < 2) {
1265                 printf("PDU Malformed\n");
1266                 raw_dump(level, frm);
1267                 return;
1268         }
1269
1270         id = get_u16(frm);
1271         printf("PlayerID: 0x%04x (%u)\n", id, id);
1272         return;
1273
1274 response:
1275         if (len < 1) {
1276                 printf("PDU Malformed\n");
1277                 raw_dump(level, frm);
1278                 return;
1279         }
1280
1281         status = get_u8(frm);
1282         printf("Status: 0x%02x (%s)\n", status, error2str(status));
1283 }
1284
1285 static void avrcp_set_browsed_player_dump(int level, struct frame *frm,
1286                                                 uint8_t hdr, uint16_t len)
1287 {
1288         uint32_t items;
1289         uint16_t id, uids, charset;
1290         uint8_t status, folders;
1291
1292         p_indent(level, frm);
1293
1294         if (hdr & 0x02)
1295                 goto response;
1296
1297         if (len < 2) {
1298                 printf("PDU Malformed\n");
1299                 raw_dump(level, frm);
1300                 return;
1301         }
1302
1303         id = get_u16(frm);
1304         printf("PlayerID: 0x%04x (%u)\n", id, id);
1305         return;
1306
1307 response:
1308         if (len != 1 && len < 10) {
1309                 printf("PDU Malformed\n");
1310                 raw_dump(level, frm);
1311                 return;
1312         }
1313
1314         status = get_u8(frm);
1315         printf("Status: 0x%02x (%s)\n", status, error2str(status));
1316
1317         if (len == 1)
1318                 return;
1319
1320         p_indent(level, frm);
1321
1322         uids = get_u16(frm);
1323         printf("UIDCounter: 0x%04x (%u)\n", uids, uids);
1324
1325         p_indent(level, frm);
1326
1327         items = get_u32(frm);
1328         printf("Number of Items: 0x%08x (%u)\n", items, items);
1329
1330         p_indent(level, frm);
1331
1332         charset = get_u16(frm);
1333         printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1334
1335         p_indent(level, frm);
1336
1337         folders = get_u8(frm);
1338         printf("Folder Depth: 0x%02x (%u)\n", folders, folders);
1339
1340         for (; folders > 0; folders--) {
1341                 uint16_t len;
1342
1343                 p_indent(level, frm);
1344
1345                 len = get_u8(frm);
1346                 printf("Folder: ");
1347                 for (; len > 0; len--) {
1348                         uint8_t c = get_u8(frm);
1349                         printf("%1c", isprint(c) ? c : '.');
1350                 }
1351                 printf("\n");
1352         }
1353 }
1354
1355 static const char *scope2str(uint8_t scope)
1356 {
1357         switch (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:
1363                 return "Search";
1364         case AVRCP_MEDIA_NOW_PLAYING:
1365                 return "Now Playing";
1366         default:
1367                 return "Unknown";
1368         }
1369 }
1370
1371 static void avrcp_play_item_dump(int level, struct frame *frm,
1372                                                 uint8_t ctype, uint16_t len)
1373 {
1374         uint64_t uid;
1375         uint32_t uidcounter;
1376         uint8_t scope, status;
1377
1378         p_indent(level, frm);
1379
1380         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1381                 goto response;
1382
1383         if (len < 11) {
1384                 printf("PDU Malformed\n");
1385                 raw_dump(level, frm);
1386                 return;
1387         }
1388
1389         scope = get_u8(frm);
1390         printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1391
1392         p_indent(level, frm);
1393
1394         uid = get_u64(frm);
1395         printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1396
1397         p_indent(level, frm);
1398
1399         uidcounter = get_u16(frm);
1400         printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
1401
1402         return;
1403
1404 response:
1405         status = get_u8(frm);
1406         printf("Status: 0x%02x (%s)\n", status, error2str(status));
1407 }
1408
1409 static void avrcp_add_to_now_playing_dump(int level, struct frame *frm,
1410                                                 uint8_t ctype, uint16_t len)
1411 {
1412         uint64_t uid;
1413         uint32_t uidcounter;
1414         uint8_t scope, status;
1415
1416         p_indent(level, frm);
1417
1418         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1419                 goto response;
1420
1421         if (len < 11) {
1422                 printf("PDU Malformed\n");
1423                 raw_dump(level, frm);
1424                 return;
1425         }
1426
1427         scope = get_u8(frm);
1428         printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1429
1430         p_indent(level, frm);
1431
1432         uid = get_u64(frm);
1433         printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1434
1435         p_indent(level, frm);
1436
1437         uidcounter = get_u16(frm);
1438         printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
1439
1440         return;
1441
1442 response:
1443         status = get_u8(frm);
1444         printf("Status: 0x%02x (%s)\n", status, error2str(status));
1445 }
1446
1447 static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
1448 {
1449         uint8_t pduid, pt;
1450         uint16_t len;
1451
1452         p_indent(level, frm);
1453
1454         pduid = get_u8(frm);
1455         pt = get_u8(frm);
1456         len = get_u16(frm);
1457
1458         printf("AVRCP: %s: pt %s len 0x%04x\n", pdu2str(pduid),
1459                                                         pt2str(pt), len);
1460
1461         if (len != frm->len) {
1462                 p_indent(level, frm);
1463                 printf("PDU Malformed\n");
1464                 raw_dump(level, frm);
1465                 return;
1466         }
1467
1468         if (ctype == AVC_CTYPE_REJECTED) {
1469                 avrcp_rejected_dump(level + 1, frm, len);
1470                 return;
1471         }
1472
1473         switch (pduid) {
1474         case AVRCP_GET_CAPABILITIES:
1475                 avrcp_get_capabilities_dump(level + 1, frm, len);
1476                 break;
1477         case AVRCP_LIST_PLAYER_ATTRIBUTES:
1478                 avrcp_list_player_attributes_dump(level + 1, frm, len);
1479                 break;
1480         case AVRCP_LIST_PLAYER_VALUES:
1481                 avrcp_list_player_values_dump(level + 1, frm, ctype, len);
1482                 break;
1483         case AVRCP_GET_CURRENT_PLAYER_VALUE:
1484                 avrcp_get_current_player_value_dump(level + 1, frm, ctype,
1485                                                                         len);
1486                 break;
1487         case AVRCP_SET_PLAYER_VALUE:
1488                 avrcp_set_player_value_dump(level + 1, frm, ctype, len);
1489                 break;
1490         case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
1491                 avrcp_get_player_attribute_text_dump(level + 1, frm, ctype,
1492                                                                         len);
1493                 break;
1494         case AVRCP_GET_PLAYER_VALUE_TEXT:
1495                 avrcp_get_player_value_text_dump(level + 1, frm, ctype, len);
1496                 break;
1497         case AVRCP_DISPLAYABLE_CHARSET:
1498                 avrcp_displayable_charset(level + 1, frm, ctype, len);
1499                 break;
1500         case AVRCP_CT_BATTERY_STATUS:
1501                 avrcp_ct_battery_status_dump(level + 1, frm, ctype, len);
1502                 break;
1503         case AVRCP_GET_ELEMENT_ATTRIBUTES:
1504                 avrcp_get_element_attributes_dump(level + 1, frm, ctype, len,
1505                                                                         pt);
1506                 break;
1507         case AVRCP_GET_PLAY_STATUS:
1508                 avrcp_get_play_status_dump(level + 1, frm, ctype, len);
1509                 break;
1510         case AVRCP_REGISTER_NOTIFICATION:
1511                 avrcp_register_notification_dump(level + 1, frm, ctype, len);
1512                 break;
1513         case AVRCP_SET_ABSOLUTE_VOLUME:
1514                 avrcp_set_absolute_volume_dump(level + 1, frm, ctype, len);
1515                 break;
1516         case AVRCP_SET_ADDRESSED_PLAYER:
1517                 avrcp_set_addressed_player(level + 1, frm, ctype, len);
1518                 break;
1519         case AVRCP_PLAY_ITEM:
1520                 avrcp_play_item_dump(level + 1, frm, ctype, len);
1521                 break;
1522         case AVRCP_ADD_TO_NOW_PLAYING:
1523                 avrcp_add_to_now_playing_dump(level + 1, frm, ctype, len);
1524                 break;
1525         default:
1526                 raw_dump(level, frm);
1527         }
1528 }
1529
1530 static char *op2str(uint8_t op)
1531 {
1532         switch (op & 0x7f) {
1533         case AVC_PANEL_VOLUME_UP:
1534                 return "VOLUME UP";
1535         case AVC_PANEL_VOLUME_DOWN:
1536                 return "VOLUME DOWN";
1537         case AVC_PANEL_MUTE:
1538                 return "MUTE";
1539         case AVC_PANEL_PLAY:
1540                 return "PLAY";
1541         case AVC_PANEL_STOP:
1542                 return "STOP";
1543         case AVC_PANEL_PAUSE:
1544                 return "PAUSE";
1545         case AVC_PANEL_RECORD:
1546                 return "RECORD";
1547         case AVC_PANEL_REWIND:
1548                 return "REWIND";
1549         case AVC_PANEL_FAST_FORWARD:
1550                 return "FAST FORWARD";
1551         case AVC_PANEL_EJECT:
1552                 return "EJECT";
1553         case AVC_PANEL_FORWARD:
1554                 return "FORWARD";
1555         case AVC_PANEL_BACKWARD:
1556                 return "BACKWARD";
1557         default:
1558                 return "UNKNOWN";
1559         }
1560 }
1561
1562
1563 static void avrcp_passthrough_dump(int level, struct frame *frm)
1564 {
1565         uint8_t op, len;
1566
1567         p_indent(level, frm);
1568
1569         op = get_u8(frm);
1570         printf("Operation: 0x%02x (%s %s)\n", op, op2str(op),
1571                                         op & 0x80 ? "Released" : "Pressed");
1572
1573         p_indent(level, frm);
1574
1575         len = get_u8(frm);
1576
1577         printf("Lenght: 0x%02x\n", len);
1578
1579         raw_dump(level, frm);
1580 }
1581
1582 static const char *subunit2str(uint8_t subunit)
1583 {
1584         switch (subunit) {
1585         case AVC_SUBUNIT_MONITOR:
1586                 return "Monitor";
1587         case AVC_SUBUNIT_AUDIO:
1588                 return "Audio";
1589         case AVC_SUBUNIT_PRINTER:
1590                 return "Printer";
1591         case AVC_SUBUNIT_DISC:
1592                 return "Disc";
1593         case AVC_SUBUNIT_TAPE:
1594                 return "Tape";
1595         case AVC_SUBUNIT_TURNER:
1596                 return "Turner";
1597         case AVC_SUBUNIT_CA:
1598                 return "CA";
1599         case AVC_SUBUNIT_CAMERA:
1600                 return "Camera";
1601         case AVC_SUBUNIT_PANEL:
1602                 return "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:
1612                 return "Unit";
1613         default:
1614                 return "Reserved";
1615         }
1616 }
1617
1618 static const char *playertype2str(uint8_t type)
1619 {
1620         switch (type & 0x0F) {
1621         case 0x01:
1622                 return "Audio";
1623         case 0x02:
1624                 return "Video";
1625         case 0x03:
1626                 return "Audio, Video";
1627         case 0x04:
1628                 return "Audio Broadcasting";
1629         case 0x05:
1630                 return "Audio, Audio Broadcasting";
1631         case 0x06:
1632                 return "Video, Audio Broadcasting";
1633         case 0x07:
1634                 return "Audio, Video, Audio Broadcasting";
1635         case 0x08:
1636                 return "Video Broadcasting";
1637         case 0x09:
1638                 return "Audio, Video Broadcasting";
1639         case 0x0A:
1640                 return "Video, Video Broadcasting";
1641         case 0x0B:
1642                 return "Audio, Video, Video Broadcasting";
1643         case 0x0C:
1644                 return "Audio Broadcasting, Video Broadcasting";
1645         case 0x0D:
1646                 return "Audio, Audio Broadcasting, Video Broadcasting";
1647         case 0x0E:
1648                 return "Video, Audio Broadcasting, Video Broadcasting";
1649         case 0x0F:
1650                 return "Audio, Video, Audio Broadcasting, Video Broadcasting";
1651         }
1652
1653         return "None";
1654 }
1655
1656 static const char *playersubtype2str(uint32_t subtype)
1657 {
1658         switch (subtype & 0x03) {
1659         case 0x01:
1660                 return "Audio Book";
1661         case 0x02:
1662                 return "Podcast";
1663         case 0x03:
1664                 return "Audio Book, Podcast";
1665         }
1666
1667         return "None";
1668 }
1669
1670 static void avrcp_media_player_item_dump(int level, struct frame *frm,
1671                                                                 uint16_t len)
1672 {
1673         uint16_t id, charset, namelen;
1674         uint8_t type, status;
1675         uint32_t subtype;
1676         uint64_t features[2];
1677
1678         p_indent(level, frm);
1679
1680         if (len < 28) {
1681                 printf("PDU Malformed\n");
1682                 raw_dump(level, frm);
1683                 return;
1684         }
1685
1686         id = get_u16(frm);
1687         printf("PlayerID: 0x%04x (%u)\n", id, id);
1688
1689         p_indent(level, frm);
1690
1691         type = get_u8(frm);
1692         printf("PlayerType: 0x%04x (%s)\n", type, playertype2str(type));
1693
1694         p_indent(level, frm);
1695
1696         subtype = get_u32(frm);
1697         printf("PlayerSubtype: 0x%08x (%s)\n", subtype,
1698                                                 playersubtype2str(subtype));
1699
1700         p_indent(level, frm);
1701
1702         status = get_u8(frm);
1703         printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
1704
1705         p_indent(level, frm);
1706
1707         get_u128(frm, &features[0], &features[1]);
1708         printf("Features: 0x%16" PRIx64 "%16" PRIx64 "\n", features[1],
1709                                                                 features[0]);
1710
1711         p_indent(level, frm);
1712
1713         charset = get_u16(frm);
1714         printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1715
1716         p_indent(level, frm);
1717
1718         namelen = get_u16(frm);
1719         printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1720
1721         p_indent(level, frm);
1722
1723         printf("Name: ");
1724         for (; namelen > 0; namelen--) {
1725                 uint8_t c = get_u8(frm);
1726                 printf("%1c", isprint(c) ? c : '.');
1727         }
1728         printf("\n");
1729 }
1730
1731 static const char *foldertype2str(uint8_t type)
1732 {
1733         switch (type) {
1734         case 0x00:
1735                 return "Mixed";
1736         case 0x01:
1737                 return "Titles";
1738         case 0x02:
1739                 return "Albuns";
1740         case 0x03:
1741                 return "Artists";
1742         case 0x04:
1743                 return "Genres";
1744         case 0x05:
1745                 return "Playlists";
1746         case 0x06:
1747                 return "Years";
1748         }
1749
1750         return "Reserved";
1751 }
1752
1753 static void avrcp_folder_item_dump(int level, struct frame *frm, uint16_t len)
1754 {
1755         uint8_t type, playable;
1756         uint16_t charset, namelen;
1757         uint64_t uid;
1758
1759         p_indent(level, frm);
1760
1761         if (len < 14) {
1762                 printf("PDU Malformed\n");
1763                 raw_dump(level, frm);
1764                 return;
1765         }
1766
1767         uid = get_u64(frm);
1768         printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1769
1770         p_indent(level, frm);
1771
1772         type = get_u8(frm);
1773         printf("FolderType: 0x%02x (%s)\n", type, foldertype2str(type));
1774
1775         p_indent(level, frm);
1776
1777         playable = get_u8(frm);
1778         printf("IsPlayable: 0x%02x (%s)\n", playable,
1779                                         playable & 0x01 ? "True" : "False");
1780
1781         p_indent(level, frm);
1782
1783         charset = get_u16(frm);
1784         printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1785
1786         p_indent(level, frm);
1787
1788         namelen = get_u16(frm);
1789         printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1790
1791         p_indent(level, frm);
1792
1793         printf("Name: ");
1794         for (; namelen > 0; namelen--) {
1795                 uint8_t c = get_u8(frm);
1796                 printf("%1c", isprint(c) ? c : '.');
1797         }
1798         printf("\n");
1799 }
1800
1801 static const char *elementtype2str(uint8_t type)
1802 {
1803         switch (type) {
1804         case 0x00:
1805                 return "Audio";
1806         case 0x01:
1807                 return "Video";
1808         }
1809
1810         return "Reserved";
1811 }
1812
1813 static void avrcp_attribute_entry_list_dump(int level, struct frame *frm,
1814                                                                 uint8_t count)
1815 {
1816         for (; count > 0; count--) {
1817                 uint32_t attr;
1818                 uint16_t charset;
1819                 uint8_t len;
1820
1821                 p_indent(level, frm);
1822
1823                 attr = get_u32(frm);
1824                 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
1825
1826                 p_indent(level, frm);
1827
1828                 charset = get_u16(frm);
1829                 printf("CharsetID: 0x%04x (%s)\n", charset,
1830                                                         charset2str(charset));
1831
1832                 p_indent(level, frm);
1833
1834                 len = get_u16(frm);
1835                 printf("AttributeLength: 0x%04x (%u)\n", len, len);
1836
1837                 p_indent(level, frm);
1838
1839                 printf("AttributeValue: ");
1840                 for (; len > 0; len--) {
1841                         uint8_t c = get_u8(frm);
1842                         printf("%1c", isprint(c) ? c : '.');
1843                 }
1844                 printf("\n");
1845         }
1846 }
1847
1848 static void avrcp_media_element_item_dump(int level, struct frame *frm,
1849                                                                 uint16_t len)
1850 {
1851         uint64_t uid;
1852         uint16_t charset, namelen;
1853         uint8_t type, count;
1854
1855         p_indent(level, frm);
1856
1857         if (len < 14) {
1858                 printf("PDU Malformed\n");
1859                 raw_dump(level, frm);
1860                 return;
1861         }
1862
1863         uid = get_u64(frm);
1864         printf("ElementUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
1865
1866         p_indent(level, frm);
1867
1868         type = get_u8(frm);
1869         printf("ElementType: 0x%02x (%s)\n", type, elementtype2str(type));
1870
1871         p_indent(level, frm);
1872
1873         charset = get_u16(frm);
1874         printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
1875
1876         p_indent(level, frm);
1877
1878         namelen = get_u16(frm);
1879         printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
1880
1881         p_indent(level, frm);
1882
1883         printf("Name: ");
1884         for (; namelen > 0; namelen--) {
1885                 uint8_t c = get_u8(frm);
1886                 printf("%1c", isprint(c) ? c : '.');
1887         }
1888         printf("\n");
1889
1890         p_indent(level, frm);
1891
1892         count = get_u8(frm);
1893         printf("AttributeCount: 0x%02x (%u)\n", count, count);
1894
1895         avrcp_attribute_entry_list_dump(level, frm, count);
1896 }
1897
1898 static void avrcp_get_folder_items_dump(int level, struct frame *frm,
1899                                                 uint8_t hdr, uint16_t len)
1900 {
1901         uint8_t scope, count, status;
1902         uint32_t start, end;
1903         uint16_t uid, num;
1904
1905         p_indent(level, frm);
1906
1907         if (hdr & 0x02)
1908                 goto response;
1909
1910         if (len < 10) {
1911                 printf("PDU Malformed\n");
1912                 raw_dump(level, frm);
1913                 return;
1914         }
1915
1916         scope = get_u8(frm);
1917         printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
1918
1919         p_indent(level, frm);
1920
1921         start = get_u32(frm);
1922         printf("StartItem: 0x%08x (%u)\n", start, start);
1923
1924         p_indent(level, frm);
1925
1926         end = get_u32(frm);
1927         printf("EndItem: 0x%08x (%u)\n", end, end);
1928
1929         p_indent(level, frm);
1930
1931         count = get_u8(frm);
1932         printf("AttributeCount: 0x%02x (%u)\n", count, count);
1933
1934         for (; count > 0; count--) {
1935                 uint32_t attr;
1936
1937                 p_indent(level, frm);
1938
1939                 attr = get_u32(frm);
1940                 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
1941         }
1942
1943         return;
1944
1945 response:
1946         status = get_u8(frm);
1947         printf("Status: 0x%02x (%s)\n", status, error2str(status));
1948
1949         if (len == 1)
1950                 return;
1951
1952         p_indent(level, frm);
1953
1954         uid = get_u16(frm);
1955         printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
1956
1957         p_indent(level, frm);
1958
1959         num = get_u16(frm);
1960         printf("Number of Items: 0x%04x (%u)\n", num, num);
1961
1962         for (; num > 0; num--) {
1963                 uint8_t type;
1964                 uint16_t len;
1965
1966                 p_indent(level, frm);
1967
1968                 type = get_u8(frm);
1969                 len = get_u16(frm);
1970                 switch (type) {
1971                 case 0x01:
1972                         printf("Item: 0x01 (Media Player)) ");
1973                         printf("Length: 0x%04x (%u)\n", len, len);
1974                         avrcp_media_player_item_dump(level, frm, len);
1975                         break;
1976                 case 0x02:
1977                         printf("Item: 0x02 (Folder) ");
1978                         printf("Length: 0x%04x (%u)\n", len, len);
1979                         avrcp_folder_item_dump(level, frm, len);
1980                         break;
1981                 case 0x03:
1982                         printf("Item: 0x03 (Media Element) ");
1983                         printf("Length: 0x%04x (%u)\n", len, len);
1984                         avrcp_media_element_item_dump(level, frm, len);
1985                         break;
1986                 }
1987         }
1988 }
1989
1990 static const char *dir2str(uint8_t dir)
1991 {
1992         switch (dir) {
1993         case 0x00:
1994                 return "Folder Up";
1995         case 0x01:
1996                 return "Folder Down";
1997         }
1998
1999         return "Reserved";
2000 }
2001
2002 static void avrcp_change_path_dump(int level, struct frame *frm, uint8_t hdr,
2003                                                                 uint16_t len)
2004 {
2005         uint64_t uid;
2006         uint32_t items;
2007         uint16_t uidcounter;
2008         uint8_t dir, status;
2009
2010         p_indent(level, frm);
2011
2012         if (hdr & 0x02)
2013                 goto response;
2014
2015         if (len < 11) {
2016                 printf("PDU Malformed\n");
2017                 raw_dump(level, frm);
2018                 return;
2019         }
2020
2021         uidcounter = get_u16(frm);
2022         printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2023
2024         p_indent(level, frm);
2025
2026         dir = get_u8(frm);
2027         printf("Direction: 0x%02x (%s)\n", dir, dir2str(dir));
2028
2029         p_indent(level, frm);
2030
2031         uid = get_u64(frm);
2032         printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
2033
2034         return;
2035
2036 response:
2037         status = get_u8(frm);
2038         printf("Status: 0x%02x (%s)\n", status, error2str(status));
2039
2040         if (len == 1)
2041                 return;
2042
2043         p_indent(level, frm);
2044
2045         items = get_u32(frm);
2046         printf("Number of Items: 0x%04x (%u)", items, items);
2047 }
2048
2049 static void avrcp_get_item_attributes_dump(int level, struct frame *frm,
2050                                                 uint8_t hdr, uint16_t len)
2051 {
2052         uint64_t uid;
2053         uint32_t uidcounter;
2054         uint8_t scope, count, status;
2055
2056         p_indent(level, frm);
2057
2058         if (hdr & 0x02)
2059                 goto response;
2060
2061         if (len < 12) {
2062                 printf("PDU Malformed\n");
2063                 raw_dump(level, frm);
2064                 return;
2065         }
2066
2067         scope = get_u8(frm);
2068         printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
2069
2070         p_indent(level, frm);
2071
2072         uid = get_u64(frm);
2073         printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
2074
2075         p_indent(level, frm);
2076
2077         uidcounter = get_u16(frm);
2078         printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2079
2080         p_indent(level, frm);
2081
2082         count = get_u8(frm);
2083         printf("AttributeCount: 0x%02x (%u)\n", count, count);
2084
2085         for (; count > 0; count--) {
2086                 uint32_t attr;
2087
2088                 p_indent(level, frm);
2089
2090                 attr = get_u32(frm);
2091                 printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
2092         }
2093
2094         return;
2095
2096 response:
2097         status = get_u8(frm);
2098         printf("Status: 0x%02x (%s)\n", status, error2str(status));
2099
2100         if (len == 1)
2101                 return;
2102
2103         p_indent(level, frm);
2104
2105         count = get_u8(frm);
2106         printf("AttributeCount: 0x%02x (%u)\n", count, count);
2107
2108         avrcp_attribute_entry_list_dump(level, frm, count);
2109 }
2110
2111 static void avrcp_search_dump(int level, struct frame *frm, uint8_t hdr,
2112                                                                 uint16_t len)
2113 {
2114         uint32_t uidcounter, items;
2115         uint16_t charset, namelen;
2116         uint8_t status;
2117
2118         p_indent(level, frm);
2119
2120         if (hdr & 0x02)
2121                 goto response;
2122
2123         if (len < 4) {
2124                 printf("PDU Malformed\n");
2125                 raw_dump(level, frm);
2126                 return;
2127         }
2128
2129         charset = get_u16(frm);
2130         printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
2131
2132         p_indent(level, frm);
2133
2134         namelen = get_u16(frm);
2135         printf("Length: 0x%04x (%u)\n", namelen, namelen);
2136
2137         p_indent(level, frm);
2138
2139         printf("String: ");
2140         for (; namelen > 0; namelen--) {
2141                 uint8_t c = get_u8(frm);
2142                 printf("%1c", isprint(c) ? c : '.');
2143         }
2144         printf("\n");
2145
2146         return;
2147
2148 response:
2149         status = get_u8(frm);
2150         printf("Status: 0x%02x (%s)\n", status, error2str(status));
2151
2152         if (len == 1)
2153                 return;
2154
2155         p_indent(level, frm);
2156
2157         uidcounter = get_u16(frm);
2158         printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
2159
2160         p_indent(level, frm);
2161
2162         items = get_u32(frm);
2163         printf("Number of Items: 0x%04x (%u)", items, items);
2164 }
2165
2166 static void avrcp_general_reject_dump(int level, struct frame *frm,
2167                                                 uint8_t hdr, uint16_t len)
2168 {
2169         uint8_t status;
2170
2171         p_indent(level, frm);
2172
2173         if (hdr & 0x02)
2174                 goto response;
2175
2176         printf("PDU Malformed\n");
2177         raw_dump(level, frm);
2178         return;
2179
2180 response:
2181         status = get_u8(frm);
2182         printf("Status: 0x%02x (%s)\n", status, error2str(status));
2183 }
2184
2185 static void avrcp_browsing_dump(int level, struct frame *frm, uint8_t hdr)
2186 {
2187         uint8_t pduid;
2188         uint16_t len;
2189
2190         pduid = get_u8(frm);
2191         len = get_u16(frm);
2192
2193         printf("AVRCP: %s: len 0x%04x\n", pdu2str(pduid), len);
2194
2195         if (len != frm->len) {
2196                 p_indent(level, frm);
2197                 printf("PDU Malformed\n");
2198                 raw_dump(level, frm);
2199                 return;
2200         }
2201
2202         switch (pduid) {
2203         case AVRCP_SET_BROWSED_PLAYER:
2204                 avrcp_set_browsed_player_dump(level + 1, frm, hdr, len);
2205                 break;
2206         case AVRCP_GET_FOLDER_ITEMS:
2207                 avrcp_get_folder_items_dump(level + 1, frm, hdr, len);
2208                 break;
2209         case AVRCP_CHANGE_PATH:
2210                 avrcp_change_path_dump(level + 1, frm, hdr, len);
2211                 break;
2212         case AVRCP_GET_ITEM_ATTRIBUTES:
2213                 avrcp_get_item_attributes_dump(level + 1, frm, hdr, len);
2214                 break;
2215         case AVRCP_SEARCH:
2216                 avrcp_search_dump(level + 1, frm, hdr, len);
2217                 break;
2218         case AVRCP_GENERAL_REJECT:
2219                 avrcp_general_reject_dump(level + 1, frm, hdr, len);
2220                 break;
2221         default:
2222                 raw_dump(level, frm);
2223         }
2224 }
2225
2226 static void avrcp_control_dump(int level, struct frame *frm)
2227 {
2228         uint8_t ctype, address, subunit, opcode, company[3];
2229         int i;
2230
2231         ctype = get_u8(frm);
2232         address = get_u8(frm);
2233         opcode = get_u8(frm);
2234
2235         printf("AV/C: %s: address 0x%02x opcode 0x%02x\n", ctype2str(ctype),
2236                                                         address, opcode);
2237
2238         p_indent(level + 1, frm);
2239
2240         subunit = address >> 3;
2241         printf("Subunit: %s\n", subunit2str(subunit));
2242
2243         p_indent(level + 1, frm);
2244
2245         printf("Opcode: %s\n", opcode2str(opcode));
2246
2247         /* Skip non-panel subunit packets */
2248         if (subunit != AVC_SUBUNIT_PANEL) {
2249                 raw_dump(level, frm);
2250                 return;
2251         }
2252
2253         /* Not implemented should not contain any operand */
2254         if (ctype == AVC_CTYPE_NOT_IMPLEMENTED) {
2255                 raw_dump(level, frm);
2256                 return;
2257         }
2258
2259         switch (opcode) {
2260         case AVC_OP_PASSTHROUGH:
2261                 avrcp_passthrough_dump(level + 1, frm);
2262                 break;
2263         case AVC_OP_VENDORDEP:
2264                 p_indent(level + 1, frm);
2265
2266                 printf("Company ID: 0x");
2267                 for (i = 0; i < 3; i++) {
2268                         company[i] = get_u8(frm);
2269                         printf("%02x", company[i]);
2270                 }
2271                 printf("\n");
2272
2273                 avrcp_pdu_dump(level + 1, frm, ctype);
2274                 break;
2275         default:
2276                 raw_dump(level, frm);
2277         }
2278 }
2279
2280 void avrcp_dump(int level, struct frame *frm, uint8_t hdr, uint16_t psm)
2281 {
2282         p_indent(level, frm);
2283
2284         switch (psm) {
2285                 case 0x17:
2286                         avrcp_control_dump(level, frm);
2287                         break;
2288                 case 0x1B:
2289                         avrcp_browsing_dump(level, frm, hdr);
2290                         break;
2291                 default:
2292                         raw_dump(level, frm);
2293         }
2294 }