device: Set disconnect timer to zero for fast disconnection
[platform/upstream/bluez.git] / monitor / avctp.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  *
4  *  BlueZ - Bluetooth protocol stack for Linux
5  *
6  *  Copyright (C) 2011-2014  Intel Corporation
7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
8  *
9  *
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include <inttypes.h>
21
22 #include "lib/bluetooth.h"
23 #include "lib/uuid.h"
24
25 #include "src/shared/util.h"
26 #include "bt.h"
27 #include "packet.h"
28 #include "display.h"
29 #include "l2cap.h"
30 #include "uuid.h"
31 #include "keys.h"
32 #include "sdp.h"
33 #include "avctp.h"
34
35 /* ctype entries */
36 #define AVC_CTYPE_CONTROL               0x0
37 #define AVC_CTYPE_STATUS                0x1
38 #define AVC_CTYPE_SPECIFIC_INQUIRY      0x2
39 #define AVC_CTYPE_NOTIFY                0x3
40 #define AVC_CTYPE_GENERAL_INQUIRY       0x4
41 #define AVC_CTYPE_NOT_IMPLEMENTED       0x8
42 #define AVC_CTYPE_ACCEPTED              0x9
43 #define AVC_CTYPE_REJECTED              0xA
44 #define AVC_CTYPE_IN_TRANSITION         0xB
45 #define AVC_CTYPE_STABLE                0xC
46 #define AVC_CTYPE_CHANGED               0xD
47 #define AVC_CTYPE_INTERIM               0xF
48
49 /* subunit type */
50 #define AVC_SUBUNIT_MONITOR             0x00
51 #define AVC_SUBUNIT_AUDIO               0x01
52 #define AVC_SUBUNIT_PRINTER             0x02
53 #define AVC_SUBUNIT_DISC                0x03
54 #define AVC_SUBUNIT_TAPE                0x04
55 #define AVC_SUBUNIT_TUNER               0x05
56 #define AVC_SUBUNIT_CA                  0x06
57 #define AVC_SUBUNIT_CAMERA              0x07
58 #define AVC_SUBUNIT_PANEL               0x09
59 #define AVC_SUBUNIT_BULLETIN_BOARD      0x0a
60 #define AVC_SUBUNIT_CAMERA_STORAGE      0x0b
61 #define AVC_SUBUNIT_VENDOR_UNIQUE       0x0c
62 #define AVC_SUBUNIT_EXTENDED            0x1e
63 #define AVC_SUBUNIT_UNIT                0x1f
64
65 /* opcodes */
66 #define AVC_OP_VENDORDEP                0x00
67 #define AVC_OP_UNITINFO                 0x30
68 #define AVC_OP_SUBUNITINFO              0x31
69 #define AVC_OP_PASSTHROUGH              0x7c
70
71 /* notification events */
72 #define AVRCP_EVENT_PLAYBACK_STATUS_CHANGED             0x01
73 #define AVRCP_EVENT_TRACK_CHANGED                       0x02
74 #define AVRCP_EVENT_TRACK_REACHED_END                   0x03
75 #define AVRCP_EVENT_TRACK_REACHED_START                 0x04
76 #define AVRCP_EVENT_PLAYBACK_POS_CHANGED                0x05
77 #define AVRCP_EVENT_BATT_STATUS_CHANGED                 0x06
78 #define AVRCP_EVENT_SYSTEM_STATUS_CHANGED               0x07
79 #define AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED  0x08
80 #define AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED         0x09
81 #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED           0x0a
82 #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED            0x0b
83 #define AVRCP_EVENT_UIDS_CHANGED                        0x0c
84 #define AVRCP_EVENT_VOLUME_CHANGED                      0x0d
85
86 /* error statuses */
87 #define AVRCP_STATUS_INVALID_COMMAND                    0x00
88 #define AVRCP_STATUS_INVALID_PARAMETER                  0x01
89 #define AVRCP_STATUS_NOT_FOUND                          0x02
90 #define AVRCP_STATUS_INTERNAL_ERROR                     0x03
91 #define AVRCP_STATUS_SUCCESS                            0x04
92 #define AVRCP_STATUS_UID_CHANGED                        0x05
93 #define AVRCP_STATUS_INVALID_DIRECTION                  0x07
94 #define AVRCP_STATUS_NOT_DIRECTORY                      0x08
95 #define AVRCP_STATUS_DOES_NOT_EXIST                     0x09
96 #define AVRCP_STATUS_INVALID_SCOPE                      0x0a
97 #define AVRCP_STATUS_OUT_OF_BOUNDS                      0x0b
98 #define AVRCP_STATUS_IS_DIRECTORY                       0x0c
99 #define AVRCP_STATUS_MEDIA_IN_USE                       0x0d
100 #define AVRCP_STATUS_NOW_PLAYING_LIST_FULL              0x0e
101 #define AVRCP_STATUS_SEARCH_NOT_SUPPORTED               0x0f
102 #define AVRCP_STATUS_SEARCH_IN_PROGRESS                 0x10
103 #define AVRCP_STATUS_INVALID_PLAYER_ID                  0x11
104 #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE               0x12
105 #define AVRCP_STATUS_PLAYER_NOT_ADDRESSED               0x13
106 #define AVRCP_STATUS_NO_VALID_SEARCH_RESULTS            0x14
107 #define AVRCP_STATUS_NO_AVAILABLE_PLAYERS               0x15
108 #define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED           0x16
109
110 /* pdu ids */
111 #define AVRCP_GET_CAPABILITIES          0x10
112 #define AVRCP_LIST_PLAYER_ATTRIBUTES    0x11
113 #define AVRCP_LIST_PLAYER_VALUES        0x12
114 #define AVRCP_GET_CURRENT_PLAYER_VALUE  0x13
115 #define AVRCP_SET_PLAYER_VALUE          0x14
116 #define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15
117 #define AVRCP_GET_PLAYER_VALUE_TEXT     0x16
118 #define AVRCP_DISPLAYABLE_CHARSET       0x17
119 #define AVRCP_CT_BATTERY_STATUS         0x18
120 #define AVRCP_GET_ELEMENT_ATTRIBUTES    0x20
121 #define AVRCP_GET_PLAY_STATUS           0x30
122 #define AVRCP_REGISTER_NOTIFICATION     0x31
123 #define AVRCP_REQUEST_CONTINUING        0x40
124 #define AVRCP_ABORT_CONTINUING          0x41
125 #define AVRCP_SET_ABSOLUTE_VOLUME       0x50
126 #define AVRCP_SET_ADDRESSED_PLAYER      0x60
127 #define AVRCP_SET_BROWSED_PLAYER        0x70
128 #define AVRCP_GET_FOLDER_ITEMS          0x71
129 #define AVRCP_CHANGE_PATH               0x72
130 #define AVRCP_GET_ITEM_ATTRIBUTES       0x73
131 #define AVRCP_PLAY_ITEM                 0x74
132 #define AVRCP_GET_TOTAL_NUMBER_OF_ITEMS 0x75
133 #define AVRCP_SEARCH                    0x80
134 #define AVRCP_ADD_TO_NOW_PLAYING        0x90
135 #define AVRCP_GENERAL_REJECT            0xA0
136
137 /* Packet types */
138 #define AVRCP_PACKET_TYPE_SINGLE        0x00
139 #define AVRCP_PACKET_TYPE_START         0x01
140 #define AVRCP_PACKET_TYPE_CONTINUING    0x02
141 #define AVRCP_PACKET_TYPE_END           0x03
142
143 /* player attributes */
144 #define AVRCP_ATTRIBUTE_ILEGAL          0x00
145 #define AVRCP_ATTRIBUTE_EQUALIZER       0x01
146 #define AVRCP_ATTRIBUTE_REPEAT_MODE     0x02
147 #define AVRCP_ATTRIBUTE_SHUFFLE         0x03
148 #define AVRCP_ATTRIBUTE_SCAN            0x04
149
150 /* media attributes */
151 #define AVRCP_MEDIA_ATTRIBUTE_ILLEGAL   0x00
152 #define AVRCP_MEDIA_ATTRIBUTE_TITLE     0x01
153 #define AVRCP_MEDIA_ATTRIBUTE_ARTIST    0x02
154 #define AVRCP_MEDIA_ATTRIBUTE_ALBUM     0x03
155 #define AVRCP_MEDIA_ATTRIBUTE_TRACK     0x04
156 #define AVRCP_MEDIA_ATTRIBUTE_TOTAL     0x05
157 #define AVRCP_MEDIA_ATTRIBUTE_GENRE     0x06
158 #define AVRCP_MEDIA_ATTRIBUTE_DURATION  0x07
159
160 /* play status */
161 #define AVRCP_PLAY_STATUS_STOPPED       0x00
162 #define AVRCP_PLAY_STATUS_PLAYING       0x01
163 #define AVRCP_PLAY_STATUS_PAUSED        0x02
164 #define AVRCP_PLAY_STATUS_FWD_SEEK      0x03
165 #define AVRCP_PLAY_STATUS_REV_SEEK      0x04
166 #define AVRCP_PLAY_STATUS_ERROR         0xFF
167
168 /* media scope */
169 #define AVRCP_MEDIA_PLAYER_LIST         0x00
170 #define AVRCP_MEDIA_PLAYER_VFS          0x01
171 #define AVRCP_MEDIA_SEARCH              0x02
172 #define AVRCP_MEDIA_NOW_PLAYING         0x03
173
174 /* Media Item Type */
175 #define AVRCP_MEDIA_PLAYER_ITEM_TYPE    0x01
176 #define AVRCP_FOLDER_ITEM_TYPE                  0x02
177 #define AVRCP_MEDIA_ELEMENT_ITEM_TYPE   0x03
178
179 /* operands in passthrough commands */
180 #define AVC_PANEL_VOLUME_UP             0x41
181 #define AVC_PANEL_VOLUME_DOWN           0x42
182 #define AVC_PANEL_MUTE                  0x43
183 #define AVC_PANEL_PLAY                  0x44
184 #define AVC_PANEL_STOP                  0x45
185 #define AVC_PANEL_PAUSE                 0x46
186 #define AVC_PANEL_RECORD                0x47
187 #define AVC_PANEL_REWIND                0x48
188 #define AVC_PANEL_FAST_FORWARD          0x49
189 #define AVC_PANEL_EJECT                 0x4a
190 #define AVC_PANEL_FORWARD               0x4b
191 #define AVC_PANEL_BACKWARD              0x4c
192
193 struct avctp_frame {
194         uint8_t hdr;
195         uint8_t pt;
196         uint16_t pid;
197         struct l2cap_frame l2cap_frame;
198 };
199
200 static struct avrcp_continuing {
201         uint16_t num;
202         uint16_t size;
203 } avrcp_continuing;
204
205 static const char *ctype2str(uint8_t ctype)
206 {
207         switch (ctype & 0x0f) {
208         case AVC_CTYPE_CONTROL:
209                 return "Control";
210         case AVC_CTYPE_STATUS:
211                 return "Status";
212         case AVC_CTYPE_SPECIFIC_INQUIRY:
213                 return "Specific Inquiry";
214         case AVC_CTYPE_NOTIFY:
215                 return "Notify";
216         case AVC_CTYPE_GENERAL_INQUIRY:
217                 return "General Inquiry";
218         case AVC_CTYPE_NOT_IMPLEMENTED:
219                 return "Not Implemented";
220         case AVC_CTYPE_ACCEPTED:
221                 return "Accepted";
222         case AVC_CTYPE_REJECTED:
223                 return "Rejected";
224         case AVC_CTYPE_IN_TRANSITION:
225                 return "In Transition";
226         case AVC_CTYPE_STABLE:
227                 return "Stable";
228         case AVC_CTYPE_CHANGED:
229                 return "Changed";
230         case AVC_CTYPE_INTERIM:
231                 return "Interim";
232         default:
233                 return "Unknown";
234         }
235 }
236
237 static const char *subunit2str(uint8_t subunit)
238 {
239         switch (subunit) {
240         case AVC_SUBUNIT_MONITOR:
241                 return "Monitor";
242         case AVC_SUBUNIT_AUDIO:
243                 return "Audio";
244         case AVC_SUBUNIT_PRINTER:
245                 return "Printer";
246         case AVC_SUBUNIT_DISC:
247                 return "Disc";
248         case AVC_SUBUNIT_TAPE:
249                 return "Tape";
250         case AVC_SUBUNIT_TUNER:
251                 return "Tuner";
252         case AVC_SUBUNIT_CA:
253                 return "CA";
254         case AVC_SUBUNIT_CAMERA:
255                 return "Camera";
256         case AVC_SUBUNIT_PANEL:
257                 return "Panel";
258         case AVC_SUBUNIT_BULLETIN_BOARD:
259                 return "Bulletin Board";
260         case AVC_SUBUNIT_CAMERA_STORAGE:
261                 return "Camera Storage";
262         case AVC_SUBUNIT_VENDOR_UNIQUE:
263                 return "Vendor Unique";
264         case AVC_SUBUNIT_EXTENDED:
265                 return "Extended to next byte";
266         case AVC_SUBUNIT_UNIT:
267                 return "Unit";
268         default:
269                 return "Reserved";
270         }
271 }
272
273 static const char *opcode2str(uint8_t opcode)
274 {
275         switch (opcode) {
276         case AVC_OP_VENDORDEP:
277                 return "Vendor Dependent";
278         case AVC_OP_UNITINFO:
279                 return "Unit Info";
280         case AVC_OP_SUBUNITINFO:
281                 return "Subunit Info";
282         case AVC_OP_PASSTHROUGH:
283                 return "Passthrough";
284         default:
285                 return "Unknown";
286         }
287 }
288
289 static char *cap2str(uint8_t cap)
290 {
291         switch (cap) {
292         case 0x2:
293                 return "CompanyID";
294         case 0x3:
295                 return "EventsID";
296         default:
297                 return "Unknown";
298         }
299 }
300
301 static char *event2str(uint8_t event)
302 {
303         switch (event) {
304         case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
305                 return "EVENT_PLAYBACK_STATUS_CHANGED";
306         case AVRCP_EVENT_TRACK_CHANGED:
307                 return "EVENT_TRACK_CHANGED";
308         case AVRCP_EVENT_TRACK_REACHED_END:
309                 return "EVENT_TRACK_REACHED_END";
310         case AVRCP_EVENT_TRACK_REACHED_START:
311                 return "EVENT_TRACK_REACHED_START";
312         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
313                 return "EVENT_PLAYBACK_POS_CHANGED";
314         case AVRCP_EVENT_BATT_STATUS_CHANGED:
315                 return "EVENT_BATT_STATUS_CHANGED";
316         case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
317                 return "EVENT_SYSTEM_STATUS_CHANGED";
318         case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
319                 return "EVENT_PLAYER_APPLICATION_SETTING_CHANGED";
320         case AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED:
321                 return "EVENT_NOW_PLAYING_CONTENT_CHANGED";
322         case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
323                 return "EVENT_AVAILABLE_PLAYERS_CHANGED";
324         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
325                 return "EVENT_ADDRESSED_PLAYER_CHANGED";
326         case AVRCP_EVENT_UIDS_CHANGED:
327                 return "EVENT_UIDS_CHANGED";
328         case AVRCP_EVENT_VOLUME_CHANGED:
329                 return "EVENT_VOLUME_CHANGED";
330         default:
331                 return "Reserved";
332         }
333 }
334
335 static const char *error2str(uint8_t status)
336 {
337         switch (status) {
338         case AVRCP_STATUS_INVALID_COMMAND:
339                 return "Invalid Command";
340         case AVRCP_STATUS_INVALID_PARAMETER:
341                 return "Invalid Parameter";
342         case AVRCP_STATUS_NOT_FOUND:
343                 return "Not Found";
344         case AVRCP_STATUS_INTERNAL_ERROR:
345                 return "Internal Error";
346         case AVRCP_STATUS_SUCCESS:
347                 return "Success";
348         case AVRCP_STATUS_UID_CHANGED:
349                 return "UID Changed";
350         case AVRCP_STATUS_INVALID_DIRECTION:
351                 return "Invalid Direction";
352         case AVRCP_STATUS_NOT_DIRECTORY:
353                 return "Not a Directory";
354         case AVRCP_STATUS_DOES_NOT_EXIST:
355                 return "Does Not Exist";
356         case AVRCP_STATUS_INVALID_SCOPE:
357                 return "Invalid Scope";
358         case AVRCP_STATUS_OUT_OF_BOUNDS:
359                 return "Range Out of Bounds";
360         case AVRCP_STATUS_MEDIA_IN_USE:
361                 return "Media in Use";
362         case AVRCP_STATUS_IS_DIRECTORY:
363                 return "UID is a Directory";
364         case AVRCP_STATUS_NOW_PLAYING_LIST_FULL:
365                 return "Now Playing List Full";
366         case AVRCP_STATUS_SEARCH_NOT_SUPPORTED:
367                 return "Search Not Supported";
368         case AVRCP_STATUS_SEARCH_IN_PROGRESS:
369                 return "Search in Progress";
370         case AVRCP_STATUS_INVALID_PLAYER_ID:
371                 return "Invalid Player ID";
372         case AVRCP_STATUS_PLAYER_NOT_BROWSABLE:
373                 return "Player Not Browsable";
374         case AVRCP_STATUS_PLAYER_NOT_ADDRESSED:
375                 return "Player Not Addressed";
376         case AVRCP_STATUS_NO_VALID_SEARCH_RESULTS:
377                 return "No Valid Search Result";
378         case AVRCP_STATUS_NO_AVAILABLE_PLAYERS:
379                 return "No Available Players";
380         case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED:
381                 return "Addressed Player Changed";
382         default:
383                 return "Unknown";
384         }
385 }
386
387 static const char *pdu2str(uint8_t pduid)
388 {
389         switch (pduid) {
390         case AVRCP_GET_CAPABILITIES:
391                 return "GetCapabilities";
392         case AVRCP_LIST_PLAYER_ATTRIBUTES:
393                 return "ListPlayerApplicationSettingAttributes";
394         case AVRCP_LIST_PLAYER_VALUES:
395                 return "ListPlayerApplicationSettingValues";
396         case AVRCP_GET_CURRENT_PLAYER_VALUE:
397                 return "GetCurrentPlayerApplicationSettingValue";
398         case AVRCP_SET_PLAYER_VALUE:
399                 return "SetPlayerApplicationSettingValue";
400         case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
401                 return "GetPlayerApplicationSettingAttributeText";
402         case AVRCP_GET_PLAYER_VALUE_TEXT:
403                 return "GetPlayerApplicationSettingValueText";
404         case AVRCP_DISPLAYABLE_CHARSET:
405                 return "InformDisplayableCharacterSet";
406         case AVRCP_CT_BATTERY_STATUS:
407                 return "InformBatteryStatusOfCT";
408         case AVRCP_GET_ELEMENT_ATTRIBUTES:
409                 return "GetElementAttributes";
410         case AVRCP_GET_PLAY_STATUS:
411                 return "GetPlayStatus";
412         case AVRCP_REGISTER_NOTIFICATION:
413                 return "RegisterNotification";
414         case AVRCP_REQUEST_CONTINUING:
415                 return "RequestContinuingResponse";
416         case AVRCP_ABORT_CONTINUING:
417                 return "AbortContinuingResponse";
418         case AVRCP_SET_ABSOLUTE_VOLUME:
419                 return "SetAbsoluteVolume";
420         case AVRCP_SET_ADDRESSED_PLAYER:
421                 return "SetAddressedPlayer";
422         case AVRCP_SET_BROWSED_PLAYER:
423                 return "SetBrowsedPlayer";
424         case AVRCP_GET_FOLDER_ITEMS:
425                 return "GetFolderItems";
426         case AVRCP_CHANGE_PATH:
427                 return "ChangePath";
428         case AVRCP_GET_ITEM_ATTRIBUTES:
429                 return "GetItemAttributes";
430         case AVRCP_PLAY_ITEM:
431                 return "PlayItem";
432         case AVRCP_GET_TOTAL_NUMBER_OF_ITEMS:
433                 return "GetTotalNumOfItems";
434         case AVRCP_SEARCH:
435                 return "Search";
436         case AVRCP_ADD_TO_NOW_PLAYING:
437                 return "AddToNowPlaying";
438         case AVRCP_GENERAL_REJECT:
439                 return "GeneralReject";
440         default:
441                 return "Unknown";
442         }
443 }
444
445 static const char *pt2str(uint8_t pt)
446 {
447         switch (pt) {
448         case AVRCP_PACKET_TYPE_SINGLE:
449                 return "Single";
450         case AVRCP_PACKET_TYPE_START:
451                 return "Start";
452         case AVRCP_PACKET_TYPE_CONTINUING:
453                 return "Continuing";
454         case AVRCP_PACKET_TYPE_END:
455                 return "End";
456         default:
457                 return "Unknown";
458         }
459 }
460
461 static const char *attr2str(uint8_t attr)
462 {
463         switch (attr) {
464         case AVRCP_ATTRIBUTE_ILEGAL:
465                 return "Illegal";
466         case AVRCP_ATTRIBUTE_EQUALIZER:
467                 return "Equalizer ON/OFF Status";
468         case AVRCP_ATTRIBUTE_REPEAT_MODE:
469                 return "Repeat Mode Status";
470         case AVRCP_ATTRIBUTE_SHUFFLE:
471                 return "Shuffle ON/OFF Status";
472         case AVRCP_ATTRIBUTE_SCAN:
473                 return "Scan ON/OFF Status";
474         default:
475                 return "Unknown";
476         }
477 }
478
479 static const char *value2str(uint8_t attr, uint8_t value)
480 {
481         switch (attr) {
482         case AVRCP_ATTRIBUTE_ILEGAL:
483                 return "Illegal";
484         case AVRCP_ATTRIBUTE_EQUALIZER:
485                 switch (value) {
486                 case 0x01:
487                         return "OFF";
488                 case 0x02:
489                         return "ON";
490                 default:
491                         return "Reserved";
492                 }
493         case AVRCP_ATTRIBUTE_REPEAT_MODE:
494                 switch (value) {
495                 case 0x01:
496                         return "OFF";
497                 case 0x02:
498                         return "Single Track Repeat";
499                 case 0x03:
500                         return "All Track Repeat";
501                 case 0x04:
502                         return "Group Repeat";
503                 default:
504                         return "Reserved";
505                 }
506         case AVRCP_ATTRIBUTE_SHUFFLE:
507                 switch (value) {
508                 case 0x01:
509                         return "OFF";
510                 case 0x02:
511                         return "All Track Shuffle";
512                 case 0x03:
513                         return "Group Shuffle";
514                 default:
515                         return "Reserved";
516                 }
517         case AVRCP_ATTRIBUTE_SCAN:
518                 switch (value) {
519                 case 0x01:
520                         return "OFF";
521                 case 0x02:
522                         return "All Track Scan";
523                 case 0x03:
524                         return "Group Scan";
525                 default:
526                         return "Reserved";
527                 }
528         default:
529                 return "Unknown";
530         }
531 }
532
533 static const char *charset2str(uint16_t charset)
534 {
535         switch (charset) {
536         case 1:
537         case 2:
538                 return "Reserved";
539         case 3:
540                 return "ASCII";
541         case 4:
542                 return "ISO_8859-1";
543         case 5:
544                 return "ISO_8859-2";
545         case 6:
546                 return "ISO_8859-3";
547         case 7:
548                 return "ISO_8859-4";
549         case 8:
550                 return "ISO_8859-5";
551         case 9:
552                 return "ISO_8859-6";
553         case 10:
554                 return "ISO_8859-7";
555         case 11:
556                 return "ISO_8859-8";
557         case 12:
558                 return "ISO_8859-9";
559         case 106:
560                 return "UTF-8";
561         default:
562                 return "Unknown";
563         }
564 }
565
566 static const char *mediattr2str(uint32_t attr)
567 {
568         switch (attr) {
569         case AVRCP_MEDIA_ATTRIBUTE_ILLEGAL:
570                 return "Illegal";
571         case AVRCP_MEDIA_ATTRIBUTE_TITLE:
572                 return "Title";
573         case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
574                 return "Artist";
575         case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
576                 return "Album";
577         case AVRCP_MEDIA_ATTRIBUTE_TRACK:
578                 return "Track";
579         case AVRCP_MEDIA_ATTRIBUTE_TOTAL:
580                 return "Track Total";
581         case AVRCP_MEDIA_ATTRIBUTE_GENRE:
582                 return "Genre";
583         case AVRCP_MEDIA_ATTRIBUTE_DURATION:
584                 return "Track duration";
585         default:
586                 return "Reserved";
587         }
588 }
589
590 static const char *playstatus2str(uint8_t status)
591 {
592         switch (status) {
593         case AVRCP_PLAY_STATUS_STOPPED:
594                 return "STOPPED";
595         case AVRCP_PLAY_STATUS_PLAYING:
596                 return "PLAYING";
597         case AVRCP_PLAY_STATUS_PAUSED:
598                 return "PAUSED";
599         case AVRCP_PLAY_STATUS_FWD_SEEK:
600                 return "FWD_SEEK";
601         case AVRCP_PLAY_STATUS_REV_SEEK:
602                 return "REV_SEEK";
603         case AVRCP_PLAY_STATUS_ERROR:
604                 return "ERROR";
605         default:
606                 return "Unknown";
607         }
608 }
609
610 static const char *status2str(uint8_t status)
611 {
612         switch (status) {
613         case 0x0:
614                 return "NORMAL";
615         case 0x1:
616                 return "WARNING";
617         case 0x2:
618                 return "CRITICAL";
619         case 0x3:
620                 return "EXTERNAL";
621         case 0x4:
622                 return "FULL_CHARGE";
623         default:
624                 return "Reserved";
625         }
626 }
627
628 static const char *scope2str(uint8_t scope)
629 {
630         switch (scope) {
631         case AVRCP_MEDIA_PLAYER_LIST:
632                 return "Media Player List";
633         case AVRCP_MEDIA_PLAYER_VFS:
634                 return "Media Player Virtual Filesystem";
635         case AVRCP_MEDIA_SEARCH:
636                 return "Search";
637         case AVRCP_MEDIA_NOW_PLAYING:
638                 return "Now Playing";
639         default:
640                 return "Unknown";
641         }
642 }
643
644 static char *op2str(uint8_t op)
645 {
646         switch (op & 0x7f) {
647         case AVC_PANEL_VOLUME_UP:
648                 return "VOLUME UP";
649         case AVC_PANEL_VOLUME_DOWN:
650                 return "VOLUME DOWN";
651         case AVC_PANEL_MUTE:
652                 return "MUTE";
653         case AVC_PANEL_PLAY:
654                 return "PLAY";
655         case AVC_PANEL_STOP:
656                 return "STOP";
657         case AVC_PANEL_PAUSE:
658                 return "PAUSE";
659         case AVC_PANEL_RECORD:
660                 return "RECORD";
661         case AVC_PANEL_REWIND:
662                 return "REWIND";
663         case AVC_PANEL_FAST_FORWARD:
664                 return "FAST FORWARD";
665         case AVC_PANEL_EJECT:
666                 return "EJECT";
667         case AVC_PANEL_FORWARD:
668                 return "FORWARD";
669         case AVC_PANEL_BACKWARD:
670                 return "BACKWARD";
671         default:
672                 return "UNKNOWN";
673         }
674 }
675
676 static const char *type2str(uint8_t type)
677 {
678         switch (type) {
679         case AVRCP_MEDIA_PLAYER_ITEM_TYPE:
680                 return "Media Player";
681         case AVRCP_FOLDER_ITEM_TYPE:
682                 return "Folder";
683         case AVRCP_MEDIA_ELEMENT_ITEM_TYPE:
684                 return "Media Element";
685         default:
686                 return "Unknown";
687         }
688 }
689
690 static const char *playertype2str(uint8_t type)
691 {
692         switch (type & 0x0F) {
693         case 0x01:
694                 return "Audio";
695         case 0x02:
696                 return "Video";
697         case 0x03:
698                 return "Audio, Video";
699         case 0x04:
700                 return "Audio Broadcasting";
701         case 0x05:
702                 return "Audio, Audio Broadcasting";
703         case 0x06:
704                 return "Video, Audio Broadcasting";
705         case 0x07:
706                 return "Audio, Video, Audio Broadcasting";
707         case 0x08:
708                 return "Video Broadcasting";
709         case 0x09:
710                 return "Audio, Video Broadcasting";
711         case 0x0A:
712                 return "Video, Video Broadcasting";
713         case 0x0B:
714                 return "Audio, Video, Video Broadcasting";
715         case 0x0C:
716                 return "Audio Broadcasting, Video Broadcasting";
717         case 0x0D:
718                 return "Audio, Audio Broadcasting, Video Broadcasting";
719         case 0x0E:
720                 return "Video, Audio Broadcasting, Video Broadcasting";
721         case 0x0F:
722                 return "Audio, Video, Audio Broadcasting, Video Broadcasting";
723         }
724
725         return "None";
726 }
727
728 static const char *playersubtype2str(uint32_t subtype)
729 {
730         switch (subtype & 0x03) {
731         case 0x01:
732                 return "Audio Book";
733         case 0x02:
734                 return "Podcast";
735         case 0x03:
736                 return "Audio Book, Podcast";
737         }
738
739         return "None";
740 }
741
742 static const char *foldertype2str(uint8_t type)
743 {
744         switch (type) {
745         case 0x00:
746                 return "Mixed";
747         case 0x01:
748                 return "Titles";
749         case 0x02:
750                 return "Albums";
751         case 0x03:
752                 return "Artists";
753         case 0x04:
754                 return "Genres";
755         case 0x05:
756                 return "Playlists";
757         case 0x06:
758                 return "Years";
759         }
760
761         return "Reserved";
762 }
763
764 static const char *elementtype2str(uint8_t type)
765 {
766         switch (type) {
767         case 0x00:
768                 return "Audio";
769         case 0x01:
770                 return "Video";
771         }
772
773         return "Reserved";
774 }
775
776 static bool avrcp_passthrough_packet(struct avctp_frame *avctp_frame,
777                                                                 uint8_t indent)
778 {
779         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
780         uint8_t op, len;
781
782         if (!l2cap_frame_get_u8(frame, &op))
783                 return false;
784
785         print_field("%*cOperation: 0x%02x (%s %s)", (indent - 8), ' ', op,
786                                 op2str(op), op & 0x80 ? "Released" : "Pressed");
787
788         if (!l2cap_frame_get_u8(frame, &len))
789                 return false;
790
791         print_field("%*cLength: 0x%02x", (indent - 8), ' ', len);
792
793         packet_hexdump(frame->data, frame->size);
794         return true;
795 }
796
797 static bool avrcp_get_capabilities(struct avctp_frame *avctp_frame,
798                                         uint8_t ctype, uint8_t len,
799                                         uint8_t indent)
800 {
801         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
802         uint8_t cap, count;
803         int i;
804
805         if (!l2cap_frame_get_u8(frame, &cap))
806                 return false;
807
808         print_field("%*cCapabilityID: 0x%02x (%s)", (indent - 8), ' ', cap,
809                                                                 cap2str(cap));
810
811         if (len == 1)
812                 return true;
813
814         if (!l2cap_frame_get_u8(frame, &count))
815                 return false;
816
817         print_field("%*cCapabilityCount: 0x%02x", (indent - 8), ' ', count);
818
819         switch (cap) {
820         case 0x2:
821                 for (; count > 0; count--) {
822                         uint8_t company[3];
823
824                         if (!l2cap_frame_get_u8(frame, &company[0]) ||
825                                 !l2cap_frame_get_u8(frame, &company[1]) ||
826                                 !l2cap_frame_get_u8(frame, &company[2]))
827                                 return false;
828
829                         print_field("%*c%s: 0x%02x%02x%02x", (indent - 8), ' ',
830                                         cap2str(cap), company[0], company[1],
831                                         company[2]);
832                 }
833                 break;
834         case 0x3:
835                 for (i = 0; count > 0; count--, i++) {
836                         uint8_t event;
837
838                         if (!l2cap_frame_get_u8(frame, &event))
839                                 return false;
840
841                         print_field("%*c%s: 0x%02x (%s)", (indent - 8), ' ',
842                                         cap2str(cap), event, event2str(event));
843                 }
844                 break;
845         default:
846                 packet_hexdump(frame->data, frame->size);
847         }
848
849         return true;
850 }
851
852 static bool avrcp_list_player_attributes(struct avctp_frame *avctp_frame,
853                                                 uint8_t ctype, uint8_t len,
854                                                 uint8_t indent)
855 {
856         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
857         uint8_t num;
858         int i;
859
860         if (len == 0)
861                 return true;
862
863         if (!l2cap_frame_get_u8(frame, &num))
864                 return false;
865
866         print_field("%*cAttributeCount: 0x%02x", (indent - 8), ' ', num);
867
868         for (i = 0; num > 0; num--, i++) {
869                 uint8_t attr;
870
871                 if (!l2cap_frame_get_u8(frame, &attr))
872                         return false;
873
874                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8), ' ',
875                                                         attr, attr2str(attr));
876         }
877
878         return true;
879 }
880
881 static bool avrcp_list_player_values(struct avctp_frame *avctp_frame,
882                                         uint8_t ctype, uint8_t len,
883                                         uint8_t indent)
884 {
885         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
886         static uint8_t attr = 0;
887         uint8_t num;
888
889         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
890                 goto response;
891
892         if (!l2cap_frame_get_u8(frame, &attr))
893                 return false;
894
895         print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8), ' ',
896                                                 attr, attr2str(attr));
897
898         return true;
899
900 response:
901         if (!l2cap_frame_get_u8(frame, &num))
902                 return false;
903
904         print_field("%*cValueCount: 0x%02x", (indent - 8), ' ', num);
905
906         for (; num > 0; num--) {
907                 uint8_t value;
908
909                 if (!l2cap_frame_get_u8(frame, &value))
910                         return false;
911
912                 print_field("%*cValueID: 0x%02x (%s)", (indent - 8),
913                                         ' ', value, value2str(attr, value));
914         }
915
916         return true;
917 }
918
919 static bool avrcp_get_current_player_value(struct avctp_frame *avctp_frame,
920                                                 uint8_t ctype, uint8_t len,
921                                                 uint8_t indent)
922 {
923         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
924         uint8_t num;
925
926         if (!l2cap_frame_get_u8(frame, &num))
927                 return false;
928
929         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
930                 goto response;
931
932         print_field("%*cAttributeCount: 0x%02x", (indent - 8), ' ', num);
933
934         for (; num > 0; num--) {
935                 uint8_t attr;
936
937                 if (!l2cap_frame_get_u8(frame, &attr))
938                         return false;
939
940                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8),
941                                                 ' ', attr, attr2str(attr));
942         }
943
944         return true;
945
946 response:
947         print_field("%*cValueCount: 0x%02x", (indent - 8), ' ', num);
948
949         for (; num > 0; num--) {
950                 uint8_t attr, value;
951
952                 if (!l2cap_frame_get_u8(frame, &attr))
953                         return false;
954
955                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8),
956                                                 ' ', attr, attr2str(attr));
957
958                 if (!l2cap_frame_get_u8(frame, &value))
959                         return false;
960
961                 print_field("%*cValueID: 0x%02x (%s)", (indent - 8),
962                                         ' ', value, value2str(attr, value));
963         }
964
965         return true;
966 }
967
968 static bool avrcp_set_player_value(struct avctp_frame *avctp_frame,
969                                         uint8_t ctype, uint8_t len,
970                                         uint8_t indent)
971 {
972         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
973         uint8_t num;
974
975         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
976                 return true;
977
978         if (!l2cap_frame_get_u8(frame, &num))
979                 return false;
980
981         print_field("%*cAttributeCount: 0x%02x", (indent - 8), ' ', num);
982
983         for (; num > 0; num--) {
984                 uint8_t attr, value;
985
986                 if (!l2cap_frame_get_u8(frame, &attr))
987                         return false;
988
989                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8), ' ',
990                                                         attr, attr2str(attr));
991
992                 if (!l2cap_frame_get_u8(frame, &value))
993                         return false;
994
995                 print_field("%*cValueID: 0x%02x (%s)", (indent - 8), ' ',
996                                                 value, value2str(attr, value));
997         }
998
999         return true;
1000 }
1001
1002 static bool avrcp_get_player_attribute_text(struct avctp_frame *avctp_frame,
1003                                                 uint8_t ctype, uint8_t len,
1004                                                 uint8_t indent)
1005 {
1006         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1007         uint8_t num;
1008
1009         if (!l2cap_frame_get_u8(frame, &num))
1010                 return false;
1011
1012         print_field("%*cAttributeCount: 0x%02x", (indent - 8), ' ', num);
1013
1014         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1015                 goto response;
1016
1017         for (; num > 0; num--) {
1018                 uint8_t attr;
1019
1020                 if (!l2cap_frame_get_u8(frame, &attr))
1021                         return false;
1022
1023                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8),
1024                                                 ' ', attr, attr2str(attr));
1025         }
1026
1027         return true;
1028
1029 response:
1030         for (; num > 0; num--) {
1031                 uint8_t attr, len;
1032                 uint16_t charset;
1033
1034                 if (!l2cap_frame_get_u8(frame, &attr))
1035                         return false;
1036
1037                 print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8),
1038                                                 ' ', attr, attr2str(attr));
1039
1040                 if (!l2cap_frame_get_be16(frame, &charset))
1041                         return false;
1042
1043                 print_field("%*cCharsetID: 0x%04x (%s)", (indent - 8),
1044                                         ' ', charset, charset2str(charset));
1045
1046                 if (!l2cap_frame_get_u8(frame, &len))
1047                         return false;
1048
1049                 print_field("%*cStringLength: 0x%02x", (indent - 8), ' ', len);
1050
1051                 printf("String: ");
1052                 for (; len > 0; len--) {
1053                         uint8_t c;
1054
1055                         if (!l2cap_frame_get_u8(frame, &c))
1056                                 return false;
1057
1058                         printf("%1c", isprint(c) ? c : '.');
1059                 }
1060                 printf("\n");
1061         }
1062
1063         return true;
1064 }
1065
1066 static bool avrcp_get_player_value_text(struct avctp_frame *avctp_frame,
1067                                         uint8_t ctype, uint8_t len,
1068                                         uint8_t indent)
1069 {
1070         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1071         static uint8_t attr = 0;
1072         uint8_t num;
1073
1074         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1075                 goto response;
1076
1077         if (!l2cap_frame_get_u8(frame, &attr))
1078                 return false;
1079
1080         print_field("%*cAttributeID: 0x%02x (%s)", (indent - 8), ' ',
1081                                                 attr, attr2str(attr));
1082
1083         if (!l2cap_frame_get_u8(frame, &num))
1084                 return false;
1085
1086         print_field("%*cValueCount: 0x%02x", (indent - 8), ' ', num);
1087
1088         for (; num > 0; num--) {
1089                 uint8_t value;
1090
1091                 if (!l2cap_frame_get_u8(frame, &value))
1092                         return false;
1093
1094                 print_field("%*cValueID: 0x%02x (%s)", (indent - 8),
1095                                 ' ', value, value2str(attr, value));
1096         }
1097
1098         return true;
1099
1100 response:
1101         if (!l2cap_frame_get_u8(frame, &num))
1102                 return false;
1103
1104         print_field("%*cValueCount: 0x%02x", (indent - 8), ' ', num);
1105
1106         for (; num > 0; num--) {
1107                 uint8_t value, len;
1108                 uint16_t charset;
1109
1110                 if (!l2cap_frame_get_u8(frame, &value))
1111                         return false;
1112
1113                 print_field("%*cValueID: 0x%02x (%s)", (indent - 8), ' ',
1114                                                 value, value2str(attr, value));
1115
1116                 if (!l2cap_frame_get_be16(frame, &charset))
1117                         return false;
1118
1119                 print_field("%*cCharsetIDID: 0x%02x (%s)", (indent - 8), ' ',
1120                                                 charset, charset2str(charset));
1121
1122                 if (!l2cap_frame_get_u8(frame, &len))
1123                         return false;
1124
1125                 print_field("%*cStringLength: 0x%02x", (indent - 8), ' ', len);
1126
1127                 printf("String: ");
1128                 for (; len > 0; len--) {
1129                         uint8_t c;
1130
1131                         if (!l2cap_frame_get_u8(frame, &c))
1132                                 return false;
1133
1134                         printf("%1c", isprint(c) ? c : '.');
1135                 }
1136                 printf("\n");
1137         }
1138
1139         return true;
1140 }
1141
1142 static bool avrcp_displayable_charset(struct avctp_frame *avctp_frame,
1143                                         uint8_t ctype, uint8_t len,
1144                                         uint8_t indent)
1145 {
1146         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1147         uint8_t num;
1148
1149         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1150                 return true;
1151
1152         if (!l2cap_frame_get_u8(frame, &num))
1153                 return false;
1154
1155         print_field("%*cCharsetCount: 0x%02x", (indent - 8), ' ', num);
1156
1157         for (; num > 0; num--) {
1158                 uint16_t charset;
1159
1160                 if (!l2cap_frame_get_be16(frame, &charset))
1161                         return false;
1162
1163                 print_field("%*cCharsetID: 0x%04x (%s)", (indent - 8),
1164                                         ' ', charset, charset2str(charset));
1165         }
1166
1167         return true;
1168 }
1169
1170 static bool avrcp_get_element_attributes(struct avctp_frame *avctp_frame,
1171                                                 uint8_t ctype, uint8_t len,
1172                                                 uint8_t indent)
1173 {
1174         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1175         uint64_t id;
1176         uint8_t num;
1177
1178         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1179                 goto response;
1180
1181         if (!l2cap_frame_get_be64(frame, &id))
1182                 return false;
1183
1184         print_field("%*cIdentifier: 0x%jx (%s)", (indent - 8), ' ',
1185                                         id, id ? "Reserved" : "PLAYING");
1186
1187         if (!l2cap_frame_get_u8(frame, &num))
1188                 return false;
1189
1190         print_field("%*cAttributeCount: 0x%02x", (indent - 8), ' ', num);
1191
1192         for (; num > 0; num--) {
1193                 uint32_t attr;
1194
1195                 if (!l2cap_frame_get_be32(frame, &attr))
1196                         return false;
1197
1198                 print_field("%*cAttributeID: 0x%08x (%s)", (indent - 8),
1199                                         ' ', attr, mediattr2str(attr));
1200         }
1201
1202         return true;
1203
1204 response:
1205         switch (avctp_frame->pt) {
1206         case AVRCP_PACKET_TYPE_SINGLE:
1207         case AVRCP_PACKET_TYPE_START:
1208                 if (!l2cap_frame_get_u8(frame, &num))
1209                         return false;
1210
1211                 avrcp_continuing.num = num;
1212                 print_field("%*cAttributeCount: 0x%02x", (indent - 8),
1213                                                                 ' ', num);
1214                 len--;
1215                 break;
1216         case AVRCP_PACKET_TYPE_CONTINUING:
1217         case AVRCP_PACKET_TYPE_END:
1218                 num = avrcp_continuing.num;
1219
1220                 if (avrcp_continuing.size > 0) {
1221                         char attrval[UINT8_MAX] = {0};
1222                         uint16_t size;
1223                         uint8_t idx;
1224
1225                         if (avrcp_continuing.size > len) {
1226                                 size = len;
1227                                 avrcp_continuing.size -= len;
1228                         } else {
1229                                 size = avrcp_continuing.size;
1230                                 avrcp_continuing.size = 0;
1231                         }
1232
1233                         for (idx = 0; size > 0; idx++, size--) {
1234                                 uint8_t c;
1235
1236                                 if (!l2cap_frame_get_u8(frame, &c))
1237                                         goto failed;
1238
1239                                 sprintf(&attrval[idx], "%1c",
1240                                                         isprint(c) ? c : '.');
1241                         }
1242                         print_field("%*cContinuingAttributeValue: %s",
1243                                                 (indent - 8), ' ', attrval);
1244
1245                         len -= size;
1246                 }
1247                 break;
1248         default:
1249                 goto failed;
1250         }
1251
1252         while (num > 0 && len > 0) {
1253                 uint32_t attr;
1254                 uint16_t charset, attrlen;
1255                 uint8_t idx;
1256                 char attrval[UINT8_MAX] = {0};
1257
1258                 if (!l2cap_frame_get_be32(frame, &attr))
1259                         goto failed;
1260
1261                 print_field("%*cAttribute: 0x%08x (%s)", (indent - 8),
1262                                                 ' ', attr, mediattr2str(attr));
1263
1264                 if (!l2cap_frame_get_be16(frame, &charset))
1265                         goto failed;
1266
1267                 print_field("%*cCharsetID: 0x%04x (%s)", (indent - 8),
1268                                 ' ', charset, charset2str(charset));
1269
1270                 if (!l2cap_frame_get_be16(frame, &attrlen))
1271                         goto failed;
1272
1273                 print_field("%*cAttributeValueLength: 0x%04x",
1274                                                 (indent - 8), ' ', attrlen);
1275
1276                 len -= sizeof(attr) + sizeof(charset) + sizeof(attrlen);
1277                 num--;
1278
1279                 for (idx = 0; attrlen > 0 && len > 0; idx++, attrlen--, len--) {
1280                         uint8_t c;
1281
1282                         if (!l2cap_frame_get_u8(frame, &c))
1283                                 goto failed;
1284
1285                         sprintf(&attrval[idx], "%1c", isprint(c) ? c : '.');
1286                 }
1287                 print_field("%*cAttributeValue: %s", (indent - 8),
1288                                                                 ' ', attrval);
1289
1290                 if (attrlen > 0)
1291                         avrcp_continuing.size = attrlen;
1292         }
1293
1294         avrcp_continuing.num = num;
1295         return true;
1296
1297 failed:
1298         avrcp_continuing.num = 0;
1299         avrcp_continuing.size = 0;
1300         return false;
1301 }
1302
1303 static bool avrcp_get_play_status(struct avctp_frame *avctp_frame,
1304                                         uint8_t ctype, uint8_t len,
1305                                         uint8_t indent)
1306 {
1307         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1308         uint32_t interval;
1309         uint8_t status;
1310
1311         if (ctype <= AVC_CTYPE_GENERAL_INQUIRY)
1312                 return true;
1313
1314         if (!l2cap_frame_get_be32(frame, &interval))
1315                 return false;
1316
1317         print_field("%*cSongLength: 0x%08x (%u miliseconds)",
1318                                         (indent - 8), ' ', interval, interval);
1319
1320         if (!l2cap_frame_get_be32(frame, &interval))
1321                 return false;
1322
1323         print_field("%*cSongPosition: 0x%08x (%u miliseconds)",
1324                                         (indent - 8), ' ', interval, interval);
1325
1326         if (!l2cap_frame_get_u8(frame, &status))
1327                 return false;
1328
1329         print_field("%*cPlayStatus: 0x%02x (%s)", (indent - 8),
1330                                         ' ', status, playstatus2str(status));
1331
1332         return true;
1333 }
1334
1335 static bool avrcp_register_notification(struct avctp_frame *avctp_frame,
1336                                         uint8_t ctype, uint8_t len,
1337                                         uint8_t indent)
1338 {
1339         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1340         uint8_t event, status;
1341         uint16_t uid;
1342         uint32_t interval;
1343         uint64_t id;
1344
1345         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1346                 goto response;
1347
1348         if (!l2cap_frame_get_u8(frame, &event))
1349                 return false;
1350
1351         print_field("%*cEventID: 0x%02x (%s)", (indent - 8),
1352                                                 ' ', event, event2str(event));
1353
1354         if (!l2cap_frame_get_be32(frame, &interval))
1355                 return false;
1356
1357         print_field("%*cInterval: 0x%08x (%u seconds)",
1358                                         (indent - 8), ' ', interval, interval);
1359
1360         return true;
1361
1362 response:
1363         if (!l2cap_frame_get_u8(frame, &event))
1364                 return false;
1365
1366         print_field("%*cEventID: 0x%02x (%s)", (indent - 8),
1367                                                 ' ', event, event2str(event));
1368
1369         switch (event) {
1370         case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
1371                 if (!l2cap_frame_get_u8(frame, &status))
1372                         return false;
1373
1374                 print_field("%*cPlayStatus: 0x%02x (%s)", (indent - 8),
1375                                         ' ', status, playstatus2str(status));
1376                 break;
1377         case AVRCP_EVENT_TRACK_CHANGED:
1378                 if (!l2cap_frame_get_be64(frame, &id))
1379                         return false;
1380
1381                 print_field("%*cIdentifier: 0x%16" PRIx64 " (%" PRIu64 ")",
1382                                                 (indent - 8), ' ', id, id);
1383                 break;
1384         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
1385                 if (!l2cap_frame_get_be32(frame, &interval))
1386                         return false;
1387
1388                 print_field("%*cPosition: 0x%08x (%u miliseconds)",
1389                                         (indent - 8), ' ', interval, interval);
1390                 break;
1391         case AVRCP_EVENT_BATT_STATUS_CHANGED:
1392                 if (!l2cap_frame_get_u8(frame, &status))
1393                         return false;
1394
1395                 print_field("%*cBatteryStatus: 0x%02x (%s)", (indent - 8),
1396                                         ' ', status, status2str(status));
1397
1398                 break;
1399         case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
1400                 if (!l2cap_frame_get_u8(frame, &status))
1401                         return false;
1402
1403                 print_field("%*cSystemStatus: 0x%02x ", (indent - 8),
1404                                                                 ' ', status);
1405                 switch (status) {
1406                 case 0x00:
1407                         printf("(POWER_ON)\n");
1408                         break;
1409                 case 0x01:
1410                         printf("(POWER_OFF)\n");
1411                         break;
1412                 case 0x02:
1413                         printf("(UNPLUGGED)\n");
1414                         break;
1415                 default:
1416                         printf("(UNKNOWN)\n");
1417                         break;
1418                 }
1419                 break;
1420         case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
1421                 if (!l2cap_frame_get_u8(frame, &status))
1422                         return false;
1423
1424                 print_field("%*cAttributeCount: 0x%02x", (indent - 8),
1425                                                                 ' ', status);
1426
1427                 for (; status > 0; status--) {
1428                         uint8_t attr, value;
1429
1430                         if (!l2cap_frame_get_u8(frame, &attr))
1431                                 return false;
1432
1433                         print_field("%*cAttributeID: 0x%02x (%s)",
1434                                 (indent - 8), ' ', attr, attr2str(attr));
1435
1436                         if (!l2cap_frame_get_u8(frame, &value))
1437                                 return false;
1438
1439                         print_field("%*cValueID: 0x%02x (%s)", (indent - 8),
1440                                         ' ', value, value2str(attr, value));
1441                 }
1442                 break;
1443         case AVRCP_EVENT_VOLUME_CHANGED:
1444                 if (!l2cap_frame_get_u8(frame, &status))
1445                         return false;
1446
1447                 status &= 0x7F;
1448
1449                 print_field("%*cVolume: %.2f%% (%d/127)", (indent - 8),
1450                                                 ' ', status/1.27, status);
1451                 break;
1452         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
1453                 if (!l2cap_frame_get_be16(frame, &uid))
1454                         return false;
1455
1456                 print_field("%*cPlayerID: 0x%04x (%u)", (indent - 8),
1457                                                                 ' ', uid, uid);
1458
1459                 if (!l2cap_frame_get_be16(frame, &uid))
1460                         return false;
1461
1462                 print_field("%*cUIDCounter: 0x%04x (%u)", (indent - 8),
1463                                                                 ' ', uid, uid);
1464                 break;
1465         case AVRCP_EVENT_UIDS_CHANGED:
1466                 if (!l2cap_frame_get_be16(frame, &uid))
1467                         return false;
1468
1469                 print_field("%*cUIDCounter: 0x%04x (%u)", (indent - 8),
1470                                                                 ' ', uid, uid);
1471                 break;
1472         }
1473
1474         return true;
1475 }
1476
1477 static bool avrcp_set_absolute_volume(struct avctp_frame *avctp_frame,
1478                                                 uint8_t ctype, uint8_t len,
1479                                                 uint8_t indent)
1480 {
1481         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1482         uint8_t value;
1483
1484         if (!l2cap_frame_get_u8(frame, &value))
1485                 return false;
1486
1487         value &= 0x7F;
1488         print_field("%*cVolume: %.2f%% (%d/127)", (indent - 8),
1489                                                 ' ', value/1.27, value);
1490
1491         return true;
1492 }
1493
1494 static bool avrcp_set_addressed_player(struct avctp_frame *avctp_frame,
1495                                                 uint8_t ctype, uint8_t len,
1496                                                 uint8_t indent)
1497 {
1498         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1499         uint16_t id;
1500         uint8_t status;
1501
1502         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1503                 goto response;
1504
1505         if (!l2cap_frame_get_be16(frame, &id))
1506                 return false;
1507
1508         print_field("%*cPlayerID: 0x%04x (%u)", (indent - 8), ' ', id, id);
1509
1510         return true;
1511
1512 response:
1513         if (!l2cap_frame_get_u8(frame, &status))
1514                 return false;
1515
1516         print_field("%*cStatus: 0x%02x (%s)", (indent - 8), ' ',
1517                                                 status, error2str(status));
1518
1519         return true;
1520 }
1521
1522 static bool avrcp_play_item(struct avctp_frame *avctp_frame, uint8_t ctype,
1523                                                 uint8_t len, uint8_t indent)
1524 {
1525         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1526         uint64_t uid;
1527         uint16_t uidcounter;
1528         uint8_t scope, status;
1529
1530         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1531                 goto response;
1532
1533         if (!l2cap_frame_get_u8(frame, &scope))
1534                 return false;
1535
1536         print_field("%*cScope: 0x%02x (%s)", (indent - 8), ' ',
1537                                                 scope, scope2str(scope));
1538
1539         if (!l2cap_frame_get_be64(frame, &uid))
1540                 return false;
1541
1542         print_field("%*cUID: 0x%16" PRIx64 " (%" PRIu64 ")", (indent - 8),
1543                                                                 ' ', uid, uid);
1544
1545         if (!l2cap_frame_get_be16(frame, &uidcounter))
1546                 return false;
1547
1548         print_field("%*cUIDCounter: 0x%04x (%u)", (indent - 8), ' ',
1549                                                         uidcounter, uidcounter);
1550
1551         return true;
1552
1553 response:
1554         if (!l2cap_frame_get_u8(frame, &status))
1555                 return false;
1556
1557         print_field("%*cStatus: 0x%02x (%s)", (indent - 8), ' ', status,
1558                                                         error2str(status));
1559
1560         return true;
1561 }
1562
1563 static bool avrcp_add_to_now_playing(struct avctp_frame *avctp_frame,
1564                                                 uint8_t ctype, uint8_t len,
1565                                                 uint8_t indent)
1566 {
1567         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1568         uint64_t uid;
1569         uint16_t uidcounter;
1570         uint8_t scope, status;
1571
1572         if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
1573                 goto response;
1574
1575         if (!l2cap_frame_get_u8(frame, &scope))
1576                 return false;
1577
1578         print_field("%*cScope: 0x%02x (%s)", (indent - 8), ' ',
1579                                                 scope, scope2str(scope));
1580
1581         if (!l2cap_frame_get_be64(frame, &uid))
1582                 return false;
1583
1584         print_field("%*cUID: 0x%16" PRIx64 " (%" PRIu64 ")", (indent - 8),
1585                                                                 ' ', uid, uid);
1586
1587         if (!l2cap_frame_get_be16(frame, &uidcounter))
1588                 return false;
1589
1590         print_field("%*cUIDCounter: 0x%04x (%u)", (indent - 8), ' ',
1591                                                         uidcounter, uidcounter);
1592
1593         return true;
1594
1595 response:
1596         if (!l2cap_frame_get_u8(frame, &status))
1597                 return false;
1598
1599         print_field("%*cStatus: 0x%02x (%s)", (indent - 8), ' ', status,
1600                                                         error2str(status));
1601
1602         return true;
1603 }
1604
1605 struct avrcp_ctrl_pdu_data {
1606         uint8_t pduid;
1607         bool (*func) (struct avctp_frame *avctp_frame, uint8_t ctype,
1608                                                 uint8_t len, uint8_t indent);
1609 };
1610
1611 static const struct avrcp_ctrl_pdu_data avrcp_ctrl_pdu_table[] = {
1612         { 0x10, avrcp_get_capabilities                  },
1613         { 0x11, avrcp_list_player_attributes            },
1614         { 0x12, avrcp_list_player_values                },
1615         { 0x13, avrcp_get_current_player_value          },
1616         { 0x14, avrcp_set_player_value                  },
1617         { 0x15, avrcp_get_player_attribute_text         },
1618         { 0x16, avrcp_get_player_value_text             },
1619         { 0x17, avrcp_displayable_charset               },
1620         { 0x20, avrcp_get_element_attributes            },
1621         { 0x30, avrcp_get_play_status                   },
1622         { 0x31, avrcp_register_notification             },
1623         { 0x50, avrcp_set_absolute_volume               },
1624         { 0x60, avrcp_set_addressed_player              },
1625         { 0x74, avrcp_play_item                         },
1626         { 0x90, avrcp_add_to_now_playing                },
1627         { }
1628 };
1629
1630 static bool avrcp_rejected_packet(struct l2cap_frame *frame, uint8_t indent)
1631 {
1632         uint8_t status;
1633
1634         if (!l2cap_frame_get_u8(frame, &status))
1635                 return false;
1636
1637         print_field("%*cError: 0x%02x (%s)", (indent - 8), ' ', status,
1638                                                         error2str(status));
1639
1640         return true;
1641 }
1642
1643 static bool avrcp_pdu_packet(struct avctp_frame *avctp_frame, uint8_t ctype,
1644                                                                 uint8_t indent)
1645 {
1646         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1647         uint8_t pduid;
1648         uint16_t len;
1649         int i;
1650         const struct avrcp_ctrl_pdu_data *ctrl_pdu_data = NULL;
1651
1652         if (!l2cap_frame_get_u8(frame, &pduid))
1653                 return false;
1654
1655         if (!l2cap_frame_get_u8(frame, &avctp_frame->pt))
1656                 return false;
1657
1658         if (!l2cap_frame_get_be16(frame, &len))
1659                 return false;
1660
1661         print_indent(indent, COLOR_OFF, "AVRCP: ", pdu2str(pduid), COLOR_OFF,
1662                         " pt %s len 0x%04x", pt2str(avctp_frame->pt), len);
1663
1664         if (frame->size != len)
1665                 return false;
1666
1667         if (ctype == 0xA)
1668                 return avrcp_rejected_packet(frame, indent + 2);
1669
1670         for (i = 0; avrcp_ctrl_pdu_table[i].func; i++) {
1671                 if (avrcp_ctrl_pdu_table[i].pduid == pduid) {
1672                         ctrl_pdu_data = &avrcp_ctrl_pdu_table[i];
1673                         break;
1674                 }
1675         }
1676
1677         if (!ctrl_pdu_data || !ctrl_pdu_data->func) {
1678                 packet_hexdump(frame->data, frame->size);
1679                 return true;
1680         }
1681
1682         return ctrl_pdu_data->func(avctp_frame, ctype, len, indent + 2);
1683 }
1684
1685 static bool avrcp_control_packet(struct avctp_frame *avctp_frame)
1686 {
1687         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1688
1689         uint8_t ctype, address, subunit, opcode, company[3], indent = 2;
1690
1691         if (!l2cap_frame_get_u8(frame, &ctype) ||
1692                                 !l2cap_frame_get_u8(frame, &address) ||
1693                                 !l2cap_frame_get_u8(frame, &opcode))
1694                 return false;
1695
1696         print_field("AV/C: %s: address 0x%02x opcode 0x%02x",
1697                                 ctype2str(ctype), address, opcode);
1698
1699         subunit = address >> 3;
1700
1701         print_field("%*cSubunit: %s", indent, ' ', subunit2str(subunit));
1702
1703         print_field("%*cOpcode: %s", indent, ' ', opcode2str(opcode));
1704
1705         /* Skip non-panel subunit packets */
1706         if (subunit != 0x09) {
1707                 packet_hexdump(frame->data, frame->size);
1708                 return true;
1709         }
1710
1711         /* Not implemented should not contain any operand */
1712         if (ctype == 0x8) {
1713                 packet_hexdump(frame->data, frame->size);
1714                 return true;
1715         }
1716
1717         switch (opcode) {
1718         case 0x7c:
1719                 return avrcp_passthrough_packet(avctp_frame, 10);
1720         case 0x00:
1721                 if (!l2cap_frame_get_u8(frame, &company[0]) ||
1722                                 !l2cap_frame_get_u8(frame, &company[1]) ||
1723                                 !l2cap_frame_get_u8(frame, &company[2]))
1724                         return false;
1725
1726                 print_field("%*cCompany ID: 0x%02x%02x%02x", indent, ' ',
1727                                         company[0], company[1], company[2]);
1728
1729                 return avrcp_pdu_packet(avctp_frame, ctype, 10);
1730         default:
1731                 packet_hexdump(frame->data, frame->size);
1732                 return true;
1733         }
1734 }
1735
1736 static const char *dir2str(uint8_t dir)
1737 {
1738         switch (dir) {
1739         case 0x00:
1740                 return "Folder Up";
1741         case 0x01:
1742                 return "Folder Down";
1743         }
1744
1745         return "Reserved";
1746 }
1747
1748 static bool avrcp_change_path(struct avctp_frame *avctp_frame)
1749 {
1750         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1751         uint64_t uid;
1752         uint32_t items;
1753         uint16_t uidcounter;
1754         uint8_t dir, status, indent = 2;
1755
1756         if (avctp_frame->hdr & 0x02)
1757                 goto response;
1758
1759         if (frame->size < 11) {
1760                 print_field("%*cPDU Malformed", indent, ' ');
1761                 packet_hexdump(frame->data, frame->size);
1762                 return false;
1763         }
1764
1765         if (!l2cap_frame_get_be16(frame, &uidcounter))
1766                 return false;
1767
1768         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ',
1769                                         uidcounter, uidcounter);
1770
1771         if (!l2cap_frame_get_u8(frame, &dir))
1772                 return false;
1773
1774         print_field("%*cDirection: 0x%02x (%s)", indent, ' ',
1775                                         dir, dir2str(dir));
1776
1777         if (!l2cap_frame_get_be64(frame, &uid))
1778                 return false;
1779
1780         print_field("%*cFolderUID: 0x%16" PRIx64 " (%" PRIu64 ")", indent, ' ',
1781                                         uid, uid);
1782
1783         return true;
1784
1785 response:
1786         if (!l2cap_frame_get_u8(frame, &status))
1787                 return false;
1788
1789         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
1790                                         status, error2str(status));
1791
1792         if (frame->size == 1)
1793                 return false;
1794
1795         if (!l2cap_frame_get_be32(frame, &items))
1796                 return false;
1797
1798         print_field("%*cNumber of Items: 0x%04x (%u)", indent, ' ',
1799                                         items, items);
1800
1801         return true;
1802 }
1803
1804
1805 static struct {
1806         const char *str;
1807         bool reserved;
1808 } features_table[] = {
1809         /* Ignore passthrough bits */
1810         [58] = { "Advanced Control Player" },
1811         [59] = { "Browsing" },
1812         [60] = { "Searching" },
1813         [61] = { "AddToNowPlaying" },
1814         [62] = { "Unique UIDs" },
1815         [63] = { "OnlyBrowsableWhenAddressed" },
1816         [64] = { "OnlySearchableWhenAddressed" },
1817         [65] = { "NowPlaying" },
1818         [66] = { "UIDPersistency" },
1819         /* 67-127 reserved */
1820         [67 ... 127] = { .reserved = true },
1821 };
1822
1823 static void print_features(uint8_t features[16], uint8_t indent)
1824 {
1825         int i;
1826
1827         for (i = 0; i < 127; i++) {
1828                 if (!(features[i / 8] & (1 << (i % 8))))
1829                         continue;
1830
1831                 if (features_table[i].reserved) {
1832                         print_text(COLOR_WHITE_BG, "Unknown bit %u", i);
1833                         continue;
1834                 }
1835
1836                 if (!features_table[i].str)
1837                         continue;
1838
1839                 print_field("%*c%s", indent, ' ', features_table[i].str);
1840         }
1841 }
1842
1843 static bool avrcp_media_player_item(struct avctp_frame *avctp_frame,
1844                                                         uint8_t indent)
1845 {
1846         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1847         uint16_t id, charset, namelen;
1848         uint8_t type, status, i;
1849         uint32_t subtype;
1850         uint8_t features[16];
1851
1852         if (!l2cap_frame_get_be16(frame, &id))
1853                 return false;
1854
1855         print_field("%*cPlayerID: 0x%04x (%u)", indent, ' ', id, id);
1856
1857         if (!l2cap_frame_get_u8(frame, &type))
1858                 return false;
1859
1860         print_field("%*cPlayerType: 0x%04x (%s)", indent, ' ',
1861                                                 type, playertype2str(type));
1862
1863         if (!l2cap_frame_get_be32(frame, &subtype))
1864                 return false;
1865
1866         print_field("%*cPlayerSubType: 0x%08x (%s)", indent, ' ',
1867                                         subtype, playersubtype2str(subtype));
1868
1869         if (!l2cap_frame_get_u8(frame, &status))
1870                 return false;
1871
1872         print_field("%*cPlayStatus: 0x%02x (%s)", indent, ' ',
1873                                                 status, playstatus2str(status));
1874
1875         printf("%*cFeatures: 0x", indent+8, ' ');
1876
1877         for (i = 0; i < 16; i++) {
1878                 if (!l2cap_frame_get_u8(frame, &features[i]))
1879                         return false;
1880
1881                 printf("%02x", features[i]);
1882         }
1883
1884         printf("\n");
1885
1886         print_features(features, indent + 2);
1887
1888         if (!l2cap_frame_get_be16(frame, &charset))
1889                 return false;
1890
1891         print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ',
1892                                                 charset, charset2str(charset));
1893
1894         if (!l2cap_frame_get_be16(frame, &namelen))
1895                 return false;
1896
1897         print_field("%*cNameLength: 0x%04x (%u)", indent, ' ',
1898                                                 namelen, namelen);
1899
1900         printf("%*cName: ", indent+8, ' ');
1901         for (; namelen > 0; namelen--) {
1902                 uint8_t c;
1903
1904                 if (!l2cap_frame_get_u8(frame, &c))
1905                         return false;
1906                 printf("%1c", isprint(c) ? c : '.');
1907         }
1908         printf("\n");
1909
1910         return true;
1911 }
1912
1913 static bool avrcp_folder_item(struct avctp_frame *avctp_frame,
1914                                                         uint8_t indent)
1915 {
1916         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1917         uint8_t type, playable;
1918         uint16_t charset, namelen;
1919         uint64_t uid;
1920
1921         if (frame->size < 14) {
1922                 printf("PDU Malformed\n");
1923                 return false;
1924         }
1925
1926         if (!l2cap_frame_get_be64(frame, &uid))
1927                 return false;
1928
1929         print_field("%*cFolderUID: 0x%16" PRIx64 " (%" PRIu64 ")", indent, ' ',
1930                                                 uid, uid);
1931
1932         if (!l2cap_frame_get_u8(frame, &type))
1933                 return false;
1934
1935         print_field("%*cFolderType: 0x%02x (%s)", indent, ' ',
1936                                                 type, foldertype2str(type));
1937
1938         if (!l2cap_frame_get_u8(frame, &playable))
1939                 return false;
1940
1941         print_field("%*cIsPlayable: 0x%02x (%s)", indent, ' ', playable,
1942                                         playable & 0x01 ? "True" : "False");
1943
1944         if (!l2cap_frame_get_be16(frame, &charset))
1945                 return false;
1946
1947         print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ',
1948                                         charset, charset2str(charset));
1949
1950         if (!l2cap_frame_get_be16(frame, &namelen))
1951                 return false;
1952
1953         print_field("%*cNameLength: 0x%04x (%u)", indent, ' ',
1954                                         namelen, namelen);
1955
1956         printf("%*cName: ", indent+8, ' ');
1957         for (; namelen > 0; namelen--) {
1958                 uint8_t c;
1959                 if (!l2cap_frame_get_u8(frame, &c))
1960                         return false;
1961
1962                 printf("%1c", isprint(c) ? c : '.');
1963         }
1964         printf("\n");
1965
1966         return true;
1967 }
1968
1969 static bool avrcp_attribute_entry_list(struct avctp_frame *avctp_frame,
1970                                                 uint8_t indent, uint8_t count)
1971 {
1972         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
1973
1974         for (; count > 0; count--) {
1975                 uint32_t attr;
1976                 uint16_t charset, len;
1977
1978                 if (!l2cap_frame_get_be32(frame, &attr))
1979                         return false;
1980
1981                 print_field("%*cAttributeID: 0x%08x (%s)", indent, ' ',
1982                                                 attr, mediattr2str(attr));
1983
1984                 if (!l2cap_frame_get_be16(frame, &charset))
1985                         return false;
1986
1987                 print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ',
1988                                                 charset, charset2str(charset));
1989
1990                 if (!l2cap_frame_get_be16(frame, &len))
1991                         return false;
1992
1993                 print_field("%*cAttributeLength: 0x%04x (%u)", indent, ' ',
1994                                                 len, len);
1995
1996                 printf("%*cAttributeValue: ", indent+8, ' ');
1997                 for (; len > 0; len--) {
1998                         uint8_t c;
1999
2000                         if (!l2cap_frame_get_u8(frame, &c))
2001                                 return false;
2002
2003                         printf("%1c", isprint(c) ? c : '.');
2004                 }
2005                 printf("\n");
2006         }
2007
2008         return true;
2009 }
2010
2011 static bool avrcp_media_element_item(struct avctp_frame *avctp_frame,
2012                                                         uint8_t indent)
2013 {
2014         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2015         uint64_t uid;
2016         uint16_t charset, namelen;
2017         uint8_t type, count;
2018
2019         if (!l2cap_frame_get_be64(frame, &uid))
2020                 return false;
2021
2022         print_field("%*cElementUID: 0x%16" PRIx64 " (%" PRIu64 ")",
2023                                         indent, ' ', uid, uid);
2024
2025         if (!l2cap_frame_get_u8(frame, &type))
2026                 return false;
2027
2028         print_field("%*cElementType: 0x%02x (%s)", indent, ' ',
2029                                         type, elementtype2str(type));
2030
2031         if (!l2cap_frame_get_be16(frame, &charset))
2032                 return false;
2033
2034         print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ',
2035                                         charset, charset2str(charset));
2036
2037         if (!l2cap_frame_get_be16(frame, &namelen))
2038                 return false;
2039
2040         print_field("%*cNameLength: 0x%04x (%u)", indent, ' ',
2041                                         namelen, namelen);
2042
2043         printf("%*cName: ", indent+8, ' ');
2044         for (; namelen > 0; namelen--) {
2045                 uint8_t c;
2046                 if (!l2cap_frame_get_u8(frame, &c))
2047                         return false;
2048
2049                 printf("%1c", isprint(c) ? c : '.');
2050         }
2051         printf("\n");
2052
2053         if (!l2cap_frame_get_u8(frame, &count))
2054                 return false;
2055
2056         print_field("%*cAttributeCount: 0x%02x (%u)", indent, ' ',
2057                                                 count, count);
2058
2059         if (!avrcp_attribute_entry_list(avctp_frame, indent, count))
2060                 return false;
2061
2062         return true;
2063 }
2064
2065 static bool avrcp_general_reject(struct avctp_frame *avctp_frame)
2066 {
2067         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2068         uint8_t status, indent = 2;
2069
2070         if (avctp_frame->hdr & 0x02)
2071                 goto response;
2072
2073         print_field("%*cPDU Malformed", indent, ' ');
2074         packet_hexdump(frame->data, frame->size);
2075
2076         return true;
2077
2078 response:
2079         if (!l2cap_frame_get_u8(frame, &status))
2080                 return false;
2081
2082         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
2083                                 status, error2str(status));
2084
2085         return true;
2086 }
2087
2088 static bool avrcp_get_total_number_of_items(struct avctp_frame *avctp_frame)
2089 {
2090         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2091         uint32_t num_of_items;
2092         uint16_t uidcounter;
2093         uint8_t scope, status, indent = 2;
2094
2095         if (avctp_frame->hdr & 0x02)
2096                 goto response;
2097
2098         if (frame->size < 4) {
2099                 printf("PDU Malformed\n");
2100                 packet_hexdump(frame->data, frame->size);
2101                 return false;
2102         }
2103
2104         if (!l2cap_frame_get_u8(frame, &scope))
2105                 return false;
2106
2107         print_field("%*cScope: 0x%02x (%s)", (indent - 8), ' ',
2108                                                 scope, scope2str(scope));
2109
2110         return true;
2111
2112 response:
2113         if (!l2cap_frame_get_u8(frame, &status))
2114                 return false;
2115
2116         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
2117                                 status, error2str(status));
2118
2119         if (frame->size == 1)
2120                 return false;
2121
2122         if (!l2cap_frame_get_be16(frame, &uidcounter))
2123                 return false;
2124
2125         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ',
2126                                 uidcounter, uidcounter);
2127
2128         if (!l2cap_frame_get_be32(frame, &num_of_items))
2129                 return false;
2130
2131         print_field("%*cNumber of Items: 0x%04x (%u)", indent, ' ',
2132                                 num_of_items, num_of_items);
2133
2134         return true;
2135 }
2136
2137 static bool avrcp_search_item(struct avctp_frame *avctp_frame)
2138 {
2139         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2140         uint32_t items;
2141         uint16_t charset, namelen, uidcounter;
2142         uint8_t status, indent = 2;
2143
2144         if (avctp_frame->hdr & 0x02)
2145                 goto response;
2146
2147         if (frame->size < 4) {
2148                 printf("PDU Malformed\n");
2149                 packet_hexdump(frame->data, frame->size);
2150                 return false;
2151         }
2152
2153         if (!l2cap_frame_get_be16(frame, &charset))
2154                 return false;
2155
2156         print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ',
2157                                 charset, charset2str(charset));
2158
2159         if (!l2cap_frame_get_be16(frame, &namelen))
2160                 return false;
2161
2162         print_field("%*cLength: 0x%04x (%u)", indent, ' ', namelen, namelen);
2163
2164         printf("%*cString: ", indent+8, ' ');
2165         for (; namelen > 0; namelen--) {
2166                 uint8_t c;
2167
2168                 if (!l2cap_frame_get_u8(frame, &c))
2169                         return false;
2170
2171                 printf("%1c", isprint(c) ? c : '.');
2172         }
2173
2174         printf("\n");
2175
2176         return true;
2177
2178 response:
2179         if (!l2cap_frame_get_u8(frame, &status))
2180                 return false;
2181
2182         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
2183                                 status, error2str(status));
2184
2185         if (frame->size == 1)
2186                 return false;
2187
2188         if (!l2cap_frame_get_be16(frame, &uidcounter))
2189                 return false;
2190
2191         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ',
2192                                 uidcounter, uidcounter);
2193
2194         if (!l2cap_frame_get_be32(frame, &items))
2195                 return false;
2196
2197         print_field("%*cNumber of Items: 0x%04x (%u)", indent, ' ',
2198                                 items, items);
2199
2200         return true;
2201 }
2202
2203 static bool avrcp_get_item_attributes(struct avctp_frame *avctp_frame)
2204 {
2205         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2206         uint64_t uid;
2207         uint16_t uidcounter;
2208         uint8_t scope, count, status, indent = 2;
2209
2210         if (avctp_frame->hdr & 0x02)
2211                 goto response;
2212
2213         if (frame->size < 12) {
2214                 print_field("%*cPDU Malformed", indent, ' ');
2215                 packet_hexdump(frame->data, frame->size);
2216                 return false;
2217         }
2218
2219         if (!l2cap_frame_get_u8(frame, &scope))
2220                 return false;
2221
2222         print_field("%*cScope: 0x%02x (%s)", indent, ' ',
2223                                         scope, scope2str(scope));
2224
2225         if (!l2cap_frame_get_be64(frame, &uid))
2226                 return false;
2227
2228         print_field("%*cUID: 0x%016" PRIx64 " (%" PRIu64 ")", indent,
2229                                         ' ', uid, uid);
2230
2231         if (!l2cap_frame_get_be16(frame, &uidcounter))
2232                 return false;
2233
2234         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ',
2235                                         uidcounter, uidcounter);
2236
2237         if (!l2cap_frame_get_u8(frame, &count))
2238                 return false;
2239
2240         print_field("%*cAttributeCount: 0x%02x (%u)", indent, ' ',
2241                                         count, count);
2242
2243         for (; count > 0; count--) {
2244                 uint32_t attr;
2245
2246                 if (!l2cap_frame_get_be32(frame, &attr))
2247                         return false;
2248
2249                 print_field("%*cAttributeID: 0x%08x (%s)", indent, ' ',
2250                                         attr, mediattr2str(attr));
2251         }
2252
2253         return true;
2254
2255 response:
2256         if (!l2cap_frame_get_u8(frame, &status))
2257                 return false;
2258
2259         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
2260                                         status, error2str(status));
2261
2262         if (frame->size == 1)
2263                 return false;
2264
2265         if (!l2cap_frame_get_u8(frame, &count))
2266                 return false;
2267
2268         print_field("%*cAttributeCount: 0x%02x (%u)", indent, ' ',
2269                                         count, count);
2270
2271         if (!avrcp_attribute_entry_list(avctp_frame, indent, count))
2272                 return false;
2273
2274         return true;
2275 }
2276
2277 static bool avrcp_get_folder_items(struct avctp_frame *avctp_frame)
2278 {
2279         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2280         uint8_t scope, count, status, indent = 2;
2281         uint32_t start, end;
2282         uint16_t uid, num;
2283
2284         if (avctp_frame->hdr & 0x02)
2285                 goto response;
2286
2287         if (!l2cap_frame_get_u8(frame, &scope))
2288                 return false;
2289
2290         print_field("%*cScope: 0x%02x (%s)", indent, ' ',
2291                                         scope, scope2str(scope));
2292
2293         if (!l2cap_frame_get_be32(frame, &start))
2294                 return false;
2295
2296         print_field("%*cStartItem: 0x%08x (%u)", indent, ' ', start, start);
2297
2298         if (!l2cap_frame_get_be32(frame, &end))
2299                 return false;
2300
2301         print_field("%*cEndItem: 0x%08x (%u)", indent, ' ', end, end);
2302
2303         if (!l2cap_frame_get_u8(frame, &count))
2304                 return false;
2305
2306         print_field("%*cAttributeCount: 0x%02x (%u)", indent, ' ',
2307                                                 count, count);
2308
2309         for (; count > 0; count--) {
2310                 uint32_t attr;
2311
2312                 if (!l2cap_frame_get_be32(frame, &attr))
2313                         return false;
2314
2315                 print_field("%*cAttributeID: 0x%08x (%s)", indent, ' ',
2316                                         attr, mediattr2str(attr));
2317         }
2318
2319         return false;
2320
2321 response:
2322         if (!l2cap_frame_get_u8(frame, &status))
2323                 return false;
2324
2325         print_field("%*cStatus: 0x%02x (%s)", indent, ' ',
2326                                 status, error2str(status));
2327
2328         if (!l2cap_frame_get_be16(frame, &uid))
2329                 return false;
2330
2331         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ', uid, uid);
2332
2333         if (!l2cap_frame_get_be16(frame, &num))
2334                 return false;
2335
2336         print_field("%*cNumOfItems: 0x%04x (%u)", indent, ' ', num, num);
2337
2338         for (; num > 0; num--) {
2339                 uint8_t type;
2340                 uint16_t len;
2341
2342                 if (!l2cap_frame_get_u8(frame, &type))
2343                         return false;
2344
2345                 if (!l2cap_frame_get_be16(frame, &len))
2346                         return false;
2347
2348                 print_field("%*cItem: 0x%02x (%s) ", indent, ' ',
2349                                         type, type2str(type));
2350                 print_field("%*cLength: 0x%04x (%u)", indent, ' ', len, len);
2351
2352                 switch (type) {
2353                 case AVRCP_MEDIA_PLAYER_ITEM_TYPE:
2354                         avrcp_media_player_item(avctp_frame, indent);
2355                         break;
2356                 case AVRCP_FOLDER_ITEM_TYPE:
2357                         avrcp_folder_item(avctp_frame, indent);
2358                         break;
2359                 case AVRCP_MEDIA_ELEMENT_ITEM_TYPE:
2360                         avrcp_media_element_item(avctp_frame, indent);
2361                         break;
2362                 default:
2363                         print_field("%*cUnknown Media Item type", indent, ' ');
2364                         packet_hexdump(frame->data, frame->size);
2365                         break;
2366                 }
2367         }
2368         return true;
2369 }
2370
2371 static bool avrcp_set_browsed_player(struct avctp_frame *avctp_frame)
2372 {
2373         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2374         uint32_t items;
2375         uint16_t id, uids, charset;
2376         uint8_t status, folders, indent = 2;
2377
2378         if (avctp_frame->hdr & 0x02)
2379                 goto response;
2380
2381         if (!l2cap_frame_get_be16(frame, &id))
2382                 return false;
2383
2384         print_field("%*cPlayerID: 0x%04x (%u)", indent, ' ', id, id);
2385         return true;
2386
2387 response:
2388         if (!l2cap_frame_get_u8(frame, &status))
2389                 return false;
2390
2391         print_field("%*cStatus: 0x%02x (%s)", indent, ' ', status,
2392                                                         error2str(status));
2393
2394         if (!l2cap_frame_get_be16(frame, &uids))
2395                 return false;
2396
2397         print_field("%*cUIDCounter: 0x%04x (%u)", indent, ' ', uids, uids);
2398
2399         if (!l2cap_frame_get_be32(frame, &items))
2400                 return false;
2401
2402         print_field("%*cNumber of Items: 0x%08x (%u)", indent, ' ',
2403                                                                 items, items);
2404
2405         if (!l2cap_frame_get_be16(frame, &charset))
2406                 return false;
2407
2408         print_field("%*cCharsetID: 0x%04x (%s)", indent, ' ', charset,
2409                                                         charset2str(charset));
2410
2411         if (!l2cap_frame_get_u8(frame, &folders))
2412                 return false;
2413
2414         print_field("%*cFolder Depth: 0x%02x (%u)", indent, ' ', folders,
2415                                                                 folders);
2416
2417         for (; folders > 0; folders--) {
2418                 uint8_t len;
2419
2420                 if (!l2cap_frame_get_u8(frame, &len))
2421                         return false;
2422
2423                 if (!len) {
2424                         print_field("%*cFolder: <empty>", indent, ' ');
2425                         continue;
2426                 }
2427
2428                 printf("%*cFolder: ", indent+8, ' ');
2429                 for (; len > 0; len--) {
2430                         uint8_t c;
2431
2432                         if (!l2cap_frame_get_u8(frame, &c))
2433                                 return false;
2434
2435                         printf("%1c", isprint(c) ? c : '.');
2436                 }
2437                 printf("\n");
2438         }
2439
2440         return true;
2441 }
2442
2443 static bool avrcp_browsing_packet(struct avctp_frame *avctp_frame)
2444 {
2445         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2446         uint16_t len;
2447         uint8_t pduid;
2448
2449         if (!l2cap_frame_get_u8(frame, &pduid))
2450                 return false;
2451
2452         if (!l2cap_frame_get_be16(frame, &len))
2453                 return false;
2454
2455         print_field("AVRCP: %s: len 0x%04x", pdu2str(pduid), len);
2456
2457         switch (pduid) {
2458         case AVRCP_SET_BROWSED_PLAYER:
2459                 avrcp_set_browsed_player(avctp_frame);
2460                 break;
2461         case AVRCP_GET_FOLDER_ITEMS:
2462                 avrcp_get_folder_items(avctp_frame);
2463                 break;
2464         case AVRCP_CHANGE_PATH:
2465                 avrcp_change_path(avctp_frame);
2466                 break;
2467         case AVRCP_GET_ITEM_ATTRIBUTES:
2468                 avrcp_get_item_attributes(avctp_frame);
2469                 break;
2470         case AVRCP_GET_TOTAL_NUMBER_OF_ITEMS:
2471                 avrcp_get_total_number_of_items(avctp_frame);
2472                 break;
2473         case AVRCP_SEARCH:
2474                 avrcp_search_item(avctp_frame);
2475                 break;
2476         case AVRCP_GENERAL_REJECT:
2477                 avrcp_general_reject(avctp_frame);
2478                 break;
2479         default:
2480                 packet_hexdump(frame->data, frame->size);
2481         }
2482
2483         return true;
2484 }
2485
2486 static void avrcp_packet(struct avctp_frame *avctp_frame)
2487 {
2488         struct l2cap_frame *frame = &avctp_frame->l2cap_frame;
2489         bool ret;
2490
2491         switch (frame->psm) {
2492         case 0x17:
2493                 ret = avrcp_control_packet(avctp_frame);
2494                 break;
2495         case 0x1B:
2496                 ret = avrcp_browsing_packet(avctp_frame);
2497                 break;
2498         default:
2499                 packet_hexdump(frame->data, frame->size);
2500                 return;
2501         }
2502
2503         if (!ret) {
2504                 print_text(COLOR_ERROR, "PDU malformed");
2505                 packet_hexdump(frame->data, frame->size);
2506         }
2507 }
2508
2509 void avctp_packet(const struct l2cap_frame *frame)
2510 {
2511         struct l2cap_frame *l2cap_frame;
2512         struct avctp_frame avctp_frame;
2513         const char *pdu_color;
2514
2515         l2cap_frame_pull(&avctp_frame.l2cap_frame, frame, 0);
2516
2517         l2cap_frame = &avctp_frame.l2cap_frame;
2518
2519         if (!l2cap_frame_get_u8(l2cap_frame, &avctp_frame.hdr) ||
2520                         !l2cap_frame_get_be16(l2cap_frame, &avctp_frame.pid)) {
2521                 print_text(COLOR_ERROR, "frame too short");
2522                 packet_hexdump(frame->data, frame->size);
2523                 return;
2524         }
2525
2526         if (frame->in)
2527                 pdu_color = COLOR_MAGENTA;
2528         else
2529                 pdu_color = COLOR_BLUE;
2530
2531         print_indent(6, pdu_color, "AVCTP", "", COLOR_OFF,
2532                                 " %s: %s: type 0x%02x label %d PID 0x%04x",
2533                                 frame->psm == 23 ? "Control" : "Browsing",
2534                                 avctp_frame.hdr & 0x02 ? "Response" : "Command",
2535                                 avctp_frame.hdr & 0x0c, avctp_frame.hdr >> 4,
2536                                 avctp_frame.pid);
2537
2538         if (avctp_frame.pid == 0x110e || avctp_frame.pid == 0x110c)
2539                 avrcp_packet(&avctp_frame);
2540         else
2541                 packet_hexdump(frame->data, frame->size);
2542 }