| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2011 Intel Corporation.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <errno.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <inttypes.h>
- #include "parser.h"
- /* ctype entries */
- #define AVC_CTYPE_CONTROL 0x0
- #define AVC_CTYPE_STATUS 0x1
- #define AVC_CTYPE_SPECIFIC_INQUIRY 0x2
- #define AVC_CTYPE_NOTIFY 0x3
- #define AVC_CTYPE_GENERAL_INQUIRY 0x4
- #define AVC_CTYPE_NOT_IMPLEMENTED 0x8
- #define AVC_CTYPE_ACCEPTED 0x9
- #define AVC_CTYPE_REJECTED 0xA
- #define AVC_CTYPE_IN_TRANSITION 0xB
- #define AVC_CTYPE_STABLE 0xC
- #define AVC_CTYPE_CHANGED 0xD
- #define AVC_CTYPE_INTERIM 0xF
- /* subunit type */
- #define AVC_SUBUNIT_MONITOR 0x00
- #define AVC_SUBUNIT_AUDIO 0x01
- #define AVC_SUBUNIT_PRINTER 0x02
- #define AVC_SUBUNIT_DISC 0x03
- #define AVC_SUBUNIT_TAPE 0x04
- #define AVC_SUBUNIT_TURNER 0x05
- #define AVC_SUBUNIT_CA 0x06
- #define AVC_SUBUNIT_CAMERA 0x07
- #define AVC_SUBUNIT_PANEL 0x09
- #define AVC_SUBUNIT_BULLETIN_BOARD 0x0a
- #define AVC_SUBUNIT_CAMERA_STORAGE 0x0b
- #define AVC_SUBUNIT_VENDOR_UNIQUE 0x0c
- #define AVC_SUBUNIT_EXTENDED 0x1e
- #define AVC_SUBUNIT_UNIT 0x1f
- /* opcodes */
- #define AVC_OP_VENDORDEP 0x00
- #define AVC_OP_UNITINFO 0x30
- #define AVC_OP_SUBUNITINFO 0x31
- #define AVC_OP_PASSTHROUGH 0x7c
- /* operands in passthrough commands */
- #define AVC_PANEL_VOLUME_UP 0x41
- #define AVC_PANEL_VOLUME_DOWN 0x42
- #define AVC_PANEL_MUTE 0x43
- #define AVC_PANEL_PLAY 0x44
- #define AVC_PANEL_STOP 0x45
- #define AVC_PANEL_PAUSE 0x46
- #define AVC_PANEL_RECORD 0x47
- #define AVC_PANEL_REWIND 0x48
- #define AVC_PANEL_FAST_FORWARD 0x49
- #define AVC_PANEL_EJECT 0x4a
- #define AVC_PANEL_FORWARD 0x4b
- #define AVC_PANEL_BACKWARD 0x4c
- /* Packet types */
- #define AVRCP_PACKET_TYPE_SINGLE 0x00
- #define AVRCP_PACKET_TYPE_START 0x01
- #define AVRCP_PACKET_TYPE_CONTINUING 0x02
- #define AVRCP_PACKET_TYPE_END 0x03
- /* pdu ids */
- #define AVRCP_GET_CAPABILITIES 0x10
- #define AVRCP_LIST_PLAYER_ATTRIBUTES 0x11
- #define AVRCP_LIST_PLAYER_VALUES 0x12
- #define AVRCP_GET_CURRENT_PLAYER_VALUE 0x13
- #define AVRCP_SET_PLAYER_VALUE 0x14
- #define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15
- #define AVRCP_GET_PLAYER_VALUE_TEXT 0x16
- #define AVRCP_DISPLAYABLE_CHARSET 0x17
- #define AVRCP_CT_BATTERY_STATUS 0x18
- #define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20
- #define AVRCP_GET_PLAY_STATUS 0x30
- #define AVRCP_REGISTER_NOTIFICATION 0x31
- #define AVRCP_REQUEST_CONTINUING 0x40
- #define AVRCP_ABORT_CONTINUING 0x41
- #define AVRCP_SET_ABSOLUTE_VOLUME 0x50
- #define AVRCP_SET_ADDRESSED_PLAYER 0x60
- #define AVRCP_SET_BROWSED_PLAYER 0x70
- #define AVRCP_GET_FOLDER_ITEMS 0x71
- #define AVRCP_CHANGE_PATH 0x72
- #define AVRCP_GET_ITEM_ATTRIBUTES 0x73
- #define AVRCP_PLAY_ITEM 0x74
- #define AVRCP_SEARCH 0x80
- #define AVRCP_ADD_TO_NOW_PLAYING 0x90
- #define AVRCP_GENERAL_REJECT 0xA0
- /* notification events */
- #define AVRCP_EVENT_PLAYBACK_STATUS_CHANGED 0x01
- #define AVRCP_EVENT_TRACK_CHANGED 0x02
- #define AVRCP_EVENT_TRACK_REACHED_END 0x03
- #define AVRCP_EVENT_TRACK_REACHED_START 0x04
- #define AVRCP_EVENT_PLAYBACK_POS_CHANGED 0x05
- #define AVRCP_EVENT_BATT_STATUS_CHANGED 0x06
- #define AVRCP_EVENT_SYSTEM_STATUS_CHANGED 0x07
- #define AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED 0x08
- #define AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED 0x09
- #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a
- #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b
- #define AVRCP_EVENT_UIDS_CHANGED 0x0c
- #define AVRCP_EVENT_VOLUME_CHANGED 0x0d
- /* error statuses */
- #define AVRCP_STATUS_INVALID_COMMAND 0x00
- #define AVRCP_STATUS_INVALID_PARAMETER 0x01
- #define AVRCP_STATUS_NOT_FOUND 0x02
- #define AVRCP_STATUS_INTERNAL_ERROR 0x03
- #define AVRCP_STATUS_SUCCESS 0x04
- #define AVRCP_STATUS_UID_CHANGED 0x05
- #define AVRCP_STATUS_INVALID_DIRECTION 0x07
- #define AVRCP_STATUS_NOT_DIRECTORY 0x08
- #define AVRCP_STATUS_DOES_NOT_EXIST 0x09
- #define AVRCP_STATUS_INVALID_SCOPE 0x0a
- #define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b
- #define AVRCP_STATUS_IS_DIRECTORY 0x0c
- #define AVRCP_STATUS_MEDIA_IN_USE 0x0d
- #define AVRCP_STATUS_NOW_PLAYING_LIST_FULL 0x0e
- #define AVRCP_STATUS_SEARCH_NOT_SUPPORTED 0x0f
- #define AVRCP_STATUS_SEARCH_IN_PROGRESS 0x10
- #define AVRCP_STATUS_INVALID_PLAYER_ID 0x11
- #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12
- #define AVRCP_STATUS_PLAYER_NOT_ADDRESSED 0x13
- #define AVRCP_STATUS_NO_VALID_SEARCH_RESULTS 0x14
- #define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15
- #define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16
- /* player attributes */
- #define AVRCP_ATTRIBUTE_ILEGAL 0x00
- #define AVRCP_ATTRIBUTE_EQUALIZER 0x01
- #define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02
- #define AVRCP_ATTRIBUTE_SHUFFLE 0x03
- #define AVRCP_ATTRIBUTE_SCAN 0x04
- /* media attributes */
- #define AVRCP_MEDIA_ATTRIBUTE_ILLEGAL 0x0
- #define AVRCP_MEDIA_ATTRIBUTE_TITLE 0x1
- #define AVRCP_MEDIA_ATTRIBUTE_ARTIST 0x2
- #define AVRCP_MEDIA_ATTRIBUTE_ALBUM 0x3
- #define AVRCP_MEDIA_ATTRIBUTE_TRACK 0x4
- #define AVRCP_MEDIA_ATTRIBUTE_TOTAL 0x5
- #define AVRCP_MEDIA_ATTRIBUTE_GENRE 0x6
- #define AVRCP_MEDIA_ATTRIBUTE_DURATION 0x7
- /* play status */
- #define AVRCP_PLAY_STATUS_STOPPED 0x00
- #define AVRCP_PLAY_STATUS_PLAYING 0x01
- #define AVRCP_PLAY_STATUS_PAUSED 0x02
- #define AVRCP_PLAY_STATUS_FWD_SEEK 0x03
- #define AVRCP_PLAY_STATUS_REV_SEEK 0x04
- #define AVRCP_PLAY_STATUS_ERROR 0xFF
- /* media scope */
- #define AVRCP_MEDIA_PLAYER_LIST 0x00
- #define AVRCP_MEDIA_PLAYER_VFS 0x01
- #define AVRCP_MEDIA_SEARCH 0x02
- #define AVRCP_MEDIA_NOW_PLAYING 0x03
- static struct avrcp_continuing {
- uint16_t num;
- uint16_t size;
- } avrcp_continuing;
- static const char *ctype2str(uint8_t ctype)
- {
- switch (ctype & 0x0f) {
- case AVC_CTYPE_CONTROL:
- return "Control";
- case AVC_CTYPE_STATUS:
- return "Status";
- case AVC_CTYPE_SPECIFIC_INQUIRY:
- return "Specific Inquiry";
- case AVC_CTYPE_NOTIFY:
- return "Notify";
- case AVC_CTYPE_GENERAL_INQUIRY:
- return "General Inquiry";
- case AVC_CTYPE_NOT_IMPLEMENTED:
- return "Not Implemented";
- case AVC_CTYPE_ACCEPTED:
- return "Accepted";
- case AVC_CTYPE_REJECTED:
- return "Rejected";
- case AVC_CTYPE_IN_TRANSITION:
- return "In Transition";
- case AVC_CTYPE_STABLE:
- return "Stable";
- case AVC_CTYPE_CHANGED:
- return "Changed";
- case AVC_CTYPE_INTERIM:
- return "Interim";
- default:
- return "Unknown";
- }
- }
- static const char *opcode2str(uint8_t opcode)
- {
- switch (opcode) {
- case AVC_OP_VENDORDEP:
- return "Vendor Dependent";
- case AVC_OP_UNITINFO:
- return "Unit Info";
- case AVC_OP_SUBUNITINFO:
- return "Subunit Info";
- case AVC_OP_PASSTHROUGH:
- return "Passthrough";
- default:
- return "Unknown";
- }
- }
- static const char *pt2str(uint8_t pt)
- {
- switch (pt) {
- case AVRCP_PACKET_TYPE_SINGLE:
- return "Single";
- case AVRCP_PACKET_TYPE_START:
- return "Start";
- case AVRCP_PACKET_TYPE_CONTINUING:
- return "Continuing";
- case AVRCP_PACKET_TYPE_END:
- return "End";
- default:
- return "Unknown";
- }
- }
- static const char *pdu2str(uint8_t pduid)
- {
- switch (pduid) {
- case AVRCP_GET_CAPABILITIES:
- return "GetCapabilities";
- case AVRCP_LIST_PLAYER_ATTRIBUTES:
- return "ListPlayerApplicationSettingAttributes";
- case AVRCP_LIST_PLAYER_VALUES:
- return "ListPlayerApplicationSettingValues";
- case AVRCP_GET_CURRENT_PLAYER_VALUE:
- return "GetCurrentPlayerApplicationSettingValue";
- case AVRCP_SET_PLAYER_VALUE:
- return "SetPlayerApplicationSettingValue";
- case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
- return "GetPlayerApplicationSettingAttributeText";
- case AVRCP_GET_PLAYER_VALUE_TEXT:
- return "GetPlayerApplicationSettingValueText";
- case AVRCP_DISPLAYABLE_CHARSET:
- return "InformDisplayableCharacterSet";
- case AVRCP_CT_BATTERY_STATUS:
- return "InformBatteryStatusOfCT";
- case AVRCP_GET_ELEMENT_ATTRIBUTES:
- return "GetElementAttributes";
- case AVRCP_GET_PLAY_STATUS:
- return "GetPlayStatus";
- case AVRCP_REGISTER_NOTIFICATION:
- return "RegisterNotification";
- case AVRCP_REQUEST_CONTINUING:
- return "RequestContinuingResponse";
- case AVRCP_ABORT_CONTINUING:
- return "AbortContinuingResponse";
- case AVRCP_SET_ABSOLUTE_VOLUME:
- return "SetAbsoluteVolume";
- case AVRCP_SET_ADDRESSED_PLAYER:
- return "SetAddressedPlayer";
- case AVRCP_SET_BROWSED_PLAYER:
- return "SetBrowsedPlayer";
- case AVRCP_GET_FOLDER_ITEMS:
- return "GetFolderItems";
- case AVRCP_CHANGE_PATH:
- return "ChangePath";
- case AVRCP_GET_ITEM_ATTRIBUTES:
- return "GetItemAttributes";
- case AVRCP_PLAY_ITEM:
- return "PlayItem";
- case AVRCP_SEARCH:
- return "Search";
- case AVRCP_ADD_TO_NOW_PLAYING:
- return "AddToNowPlaying";
- case AVRCP_GENERAL_REJECT:
- return "GeneralReject";
- default:
- return "Unknown";
- }
- }
- static char *cap2str(uint8_t cap)
- {
- switch (cap) {
- case 0x2:
- return "CompanyID";
- case 0x3:
- return "EventsID";
- default:
- return "Unknown";
- }
- }
- static char *event2str(uint8_t event)
- {
- switch (event) {
- case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
- return "EVENT_PLAYBACK_STATUS_CHANGED";
- case AVRCP_EVENT_TRACK_CHANGED:
- return "EVENT_TRACK_CHANGED";
- case AVRCP_EVENT_TRACK_REACHED_END:
- return "EVENT_TRACK_REACHED_END";
- case AVRCP_EVENT_TRACK_REACHED_START:
- return "EVENT_TRACK_REACHED_START";
- case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
- return "EVENT_PLAYBACK_POS_CHANGED";
- case AVRCP_EVENT_BATT_STATUS_CHANGED:
- return "EVENT_BATT_STATUS_CHANGED";
- case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
- return "EVENT_SYSTEM_STATUS_CHANGED";
- case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
- return "EVENT_PLAYER_APPLICATION_SETTING_CHANGED";
- case AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED:
- return "EVENT_NOW_PLAYING_CONTENT_CHANGED";
- case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
- return "EVENT_AVAILABLE_PLAYERS_CHANGED";
- case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
- return "EVENT_ADDRESSED_PLAYER_CHANGED";
- case AVRCP_EVENT_UIDS_CHANGED:
- return "EVENT_UIDS_CHANGED";
- case AVRCP_EVENT_VOLUME_CHANGED:
- return "EVENT_VOLUME_CHANGED";
- default:
- return "Reserved";
- }
- }
- static const char *error2str(uint8_t status)
- {
- switch (status) {
- case AVRCP_STATUS_INVALID_COMMAND:
- return "Invalid Command";
- case AVRCP_STATUS_INVALID_PARAMETER:
- return "Invalid Parameter";
- case AVRCP_STATUS_NOT_FOUND:
- return "Not Found";
- case AVRCP_STATUS_INTERNAL_ERROR:
- return "Internal Error";
- case AVRCP_STATUS_SUCCESS:
- return "Success";
- case AVRCP_STATUS_UID_CHANGED:
- return "UID Changed";
- case AVRCP_STATUS_INVALID_DIRECTION:
- return "Invalid Direction";
- case AVRCP_STATUS_NOT_DIRECTORY:
- return "Not a Directory";
- case AVRCP_STATUS_DOES_NOT_EXIST:
- return "Does Not Exist";
- case AVRCP_STATUS_INVALID_SCOPE:
- return "Invalid Scope";
- case AVRCP_STATUS_OUT_OF_BOUNDS:
- return "Range Out of Bonds";
- case AVRCP_STATUS_MEDIA_IN_USE:
- return "Media in Use";
- case AVRCP_STATUS_IS_DIRECTORY:
- return "UID is a Directory";
- case AVRCP_STATUS_NOW_PLAYING_LIST_FULL:
- return "Now Playing List Full";
- case AVRCP_STATUS_SEARCH_NOT_SUPPORTED:
- return "Seach Not Supported";
- case AVRCP_STATUS_SEARCH_IN_PROGRESS:
- return "Search in Progress";
- case AVRCP_STATUS_INVALID_PLAYER_ID:
- return "Invalid Player ID";
- case AVRCP_STATUS_PLAYER_NOT_BROWSABLE:
- return "Player Not Browsable";
- case AVRCP_STATUS_PLAYER_NOT_ADDRESSED:
- return "Player Not Addressed";
- case AVRCP_STATUS_NO_VALID_SEARCH_RESULTS:
- return "No Valid Search Result";
- case AVRCP_STATUS_NO_AVAILABLE_PLAYERS:
- return "No Available Players";
- case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED:
- return "Addressed Player Changed";
- default:
- return "Unknown";
- }
- }
- static void avrcp_rejected_dump(int level, struct frame *frm, uint16_t len)
- {
- uint8_t status;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- status = p_get_u8(frm);
- printf("Error: 0x%02x (%s)\n", status, error2str(status));
- }
- static void avrcp_get_capabilities_dump(int level, struct frame *frm, uint16_t len)
- {
- uint8_t cap;
- uint8_t count;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- cap = p_get_u8(frm);
- printf("CapabilityID: 0x%02x (%s)\n", cap, cap2str(cap));
- if (len == 1)
- return;
- p_indent(level, frm);
- count = p_get_u8(frm);
- printf("CapabilityCount: 0x%02x\n", count);
- switch (cap) {
- case 0x2:
- for (; count > 0; count--) {
- int i;
- p_indent(level, frm);
- printf("%s: 0x", cap2str(cap));
- for (i = 0; i < 3; i++)
- printf("%02x", p_get_u8(frm));
- printf("\n");
- }
- break;
- case 0x3:
- for (; count > 0; count--) {
- uint8_t event;
- p_indent(level, frm);
- event = p_get_u8(frm);
- printf("%s: 0x%02x (%s)\n", cap2str(cap), event,
- event2str(event));
- }
- break;
- default:
- raw_dump(level, frm);
- }
- }
- static const char *attr2str(uint8_t attr)
- {
- switch (attr) {
- case AVRCP_ATTRIBUTE_ILEGAL:
- return "Illegal";
- case AVRCP_ATTRIBUTE_EQUALIZER:
- return "Equalizer ON/OFF Status";
- case AVRCP_ATTRIBUTE_REPEAT_MODE:
- return "Repeat Mode Status";
- case AVRCP_ATTRIBUTE_SHUFFLE:
- return "Shuffle ON/OFF Status";
- case AVRCP_ATTRIBUTE_SCAN:
- return "Scan ON/OFF Status";
- default:
- return "Unknown";
- }
- }
- static void avrcp_list_player_attributes_dump(int level, struct frame *frm,
- uint16_t len)
- {
- uint8_t num;
- if (len == 0)
- return;
- p_indent(level, frm);
- num = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t attr;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- }
- }
- static const char *value2str(uint8_t attr, uint8_t value)
- {
- switch (attr) {
- case AVRCP_ATTRIBUTE_ILEGAL:
- return "Illegal";
- case AVRCP_ATTRIBUTE_EQUALIZER:
- switch (value) {
- case 0x01:
- return "OFF";
- case 0x02:
- return "ON";
- default:
- return "Reserved";
- }
- case AVRCP_ATTRIBUTE_REPEAT_MODE:
- switch (value) {
- case 0x01:
- return "OFF";
- case 0x02:
- return "Single Track Repeat";
- case 0x03:
- return "All Track Repeat";
- case 0x04:
- return "Group Repeat";
- default:
- return "Reserved";
- }
- case AVRCP_ATTRIBUTE_SHUFFLE:
- switch (value) {
- case 0x01:
- return "OFF";
- case 0x02:
- return "All Track Suffle";
- case 0x03:
- return "Group Suffle";
- default:
- return "Reserved";
- }
- case AVRCP_ATTRIBUTE_SCAN:
- switch (value) {
- case 0x01:
- return "OFF";
- case 0x02:
- return "All Track Scan";
- case 0x03:
- return "Group Scan";
- default:
- return "Reserved";
- }
- default:
- return "Unknown";
- }
- }
- static void avrcp_list_player_values_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- static uint8_t attr = 0; /* Remember attribute */
- uint8_t num;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- return;
- response:
- num = p_get_u8(frm);
- printf("ValueCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t value;
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- }
- }
- static void avrcp_get_current_player_value_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t num;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- num = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t attr;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- }
- return;
- response:
- num = p_get_u8(frm);
- printf("ValueCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t attr, value;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- }
- }
- static void avrcp_set_player_value_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t num;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- return;
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- num = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t attr, value;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- }
- }
- static const char *charset2str(uint16_t charset)
- {
- switch (charset) {
- case 1:
- case 2:
- return "Reserved";
- case 3:
- return "ASCII";
- case 4:
- return "ISO_8859-1";
- case 5:
- return "ISO_8859-2";
- case 6:
- return "ISO_8859-3";
- case 7:
- return "ISO_8859-4";
- case 8:
- return "ISO_8859-5";
- case 9:
- return "ISO_8859-6";
- case 10:
- return "ISO_8859-7";
- case 11:
- return "ISO_8859-8";
- case 12:
- return "ISO_8859-9";
- case 106:
- return "UTF-8";
- default:
- return "Unknown";
- }
- }
- static void avrcp_get_player_attribute_text_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t num;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- num = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", num);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- for (; num > 0; num--) {
- uint8_t attr;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- }
- return;
- response:
- for (; num > 0; num--) {
- uint8_t attr, len;
- uint16_t charset;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset,
- charset2str(charset));
- p_indent(level, frm);
- len = p_get_u8(frm);
- printf("StringLength: 0x%02x\n", len);
- p_indent(level, frm);
- printf("String: ");
- for (; len > 0; len--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- }
- static void avrcp_get_player_value_text_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- static uint8_t attr = 0; /* Remember attribute */
- uint8_t num;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
- p_indent(level, frm);
- num = p_get_u8(frm);
- printf("ValueCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t value;
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- }
- return;
- response:
- num = p_get_u8(frm);
- printf("ValueCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint8_t value, len;
- uint16_t charset;
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset,
- charset2str(charset));
- p_indent(level, frm);
- len = p_get_u8(frm);
- printf("StringLength: 0x%02x\n", len);
- p_indent(level, frm);
- printf("String: ");
- for (; len > 0; len--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- }
- static void avrcp_displayable_charset(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t num;
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- return;
- p_indent(level, frm);
- if (len < 2) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- num = p_get_u8(frm);
- printf("CharsetCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint16_t charset;
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset,
- charset2str(charset));
- }
- }
- static const char *status2str(uint8_t status)
- {
- switch (status) {
- case 0x0:
- return "NORMAL";
- case 0x1:
- return "WARNING";
- case 0x2:
- return "CRITICAL";
- case 0x3:
- return "EXTERNAL";
- case 0x4:
- return "FULL_CHARGE";
- default:
- return "Reserved";
- }
- }
- static void avrcp_ct_battery_status_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t status;
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- return;
- p_indent(level, frm);
- status = p_get_u8(frm);
- printf("BatteryStatus: 0x%02x (%s)\n", status, status2str(status));
- }
- static const char *mediattr2str(uint32_t attr)
- {
- switch (attr) {
- case AVRCP_MEDIA_ATTRIBUTE_ILLEGAL:
- return "Illegal";
- case AVRCP_MEDIA_ATTRIBUTE_TITLE:
- return "Title";
- case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
- return "Artist";
- case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
- return "Album";
- case AVRCP_MEDIA_ATTRIBUTE_TRACK:
- return "Track";
- case AVRCP_MEDIA_ATTRIBUTE_TOTAL:
- return "Track Total";
- case AVRCP_MEDIA_ATTRIBUTE_GENRE:
- return "Genre";
- case AVRCP_MEDIA_ATTRIBUTE_DURATION:
- return "Track duration";
- default:
- return "Reserved";
- }
- }
- static void avrcp_get_element_attributes_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len,
- uint8_t pt)
- {
- uint64_t id;
- uint8_t num;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- if (len < 9) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- id = p_get_u64(frm);
- printf("Identifier: 0x%jx (%s)\n", id, id ? "Reserved" : "PLAYING");
- p_indent(level, frm);
- num = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", num);
- for (; num > 0; num--) {
- uint32_t attr;
- p_indent(level, frm);
- attr = p_get_u32(frm);
- printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
- }
- return;
- response:
- if (pt == AVRCP_PACKET_TYPE_SINGLE || pt == AVRCP_PACKET_TYPE_START) {
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- num = p_get_u8(frm);
- avrcp_continuing.num = num;
- printf("AttributeCount: 0x%02x\n", num);
- len--;
- } else {
- num = avrcp_continuing.num;
- if (avrcp_continuing.size > 0) {
- uint16_t size;
- if (avrcp_continuing.size > len) {
- size = len;
- avrcp_continuing.size -= len;
- } else {
- size = avrcp_continuing.size;
- avrcp_continuing.size = 0;
- }
- printf("ContinuingAttributeValue: ");
- for (; size > 0; size--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- len -= size;
- }
- }
- while (num > 0 && len > 0) {
- uint32_t attr;
- uint16_t charset, attrlen;
- p_indent(level, frm);
- attr = p_get_u32(frm);
- printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset,
- charset2str(charset));
- p_indent(level, frm);
- attrlen = p_get_u16(frm);
- printf("AttributeValueLength: 0x%04x\n", attrlen);
- len -= sizeof(attr) + sizeof(charset) + sizeof(attrlen);
- num--;
- p_indent(level, frm);
- printf("AttributeValue: ");
- for (; attrlen > 0 && len > 0; attrlen--, len--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- if (attrlen > 0)
- avrcp_continuing.size = attrlen;
- }
- avrcp_continuing.num = num;
- }
- static const char *playstatus2str(uint8_t status)
- {
- switch (status) {
- case AVRCP_PLAY_STATUS_STOPPED:
- return "STOPPED";
- case AVRCP_PLAY_STATUS_PLAYING:
- return "PLAYING";
- case AVRCP_PLAY_STATUS_PAUSED:
- return "PAUSED";
- case AVRCP_PLAY_STATUS_FWD_SEEK:
- return "FWD_SEEK";
- case AVRCP_PLAY_STATUS_REV_SEEK:
- return "REV_SEEK";
- case AVRCP_PLAY_STATUS_ERROR:
- return "ERROR";
- default:
- return "Unknown";
- }
- }
- static void avrcp_get_play_status_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint32_t interval;
- uint8_t status;
- if (ctype <= AVC_CTYPE_GENERAL_INQUIRY)
- return;
- p_indent(level, frm);
- if (len < 9) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- interval = p_get_u32(frm);
- printf("SongLength: 0x%08x (%u miliseconds)\n", interval, interval);
- p_indent(level, frm);
- interval = p_get_u32(frm);
- printf("SongPosition: 0x%08x (%u miliconds)\n", interval, interval);
- p_indent(level, frm);
- status = p_get_u8(frm);
- printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
- }
- static void avrcp_register_notification_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t event, status;
- uint16_t uid;
- uint32_t interval;
- uint64_t id;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- if (len < 5) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- event = p_get_u8(frm);
- printf("EventID: 0x%02x (%s)\n", event, event2str(event));
- p_indent(level, frm);
- interval = p_get_u32(frm);
- printf("Interval: 0x%08x (%u seconds)\n", interval, interval);
- return;
- response:
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- event = p_get_u8(frm);
- printf("EventID: 0x%02x (%s)\n", event, event2str(event));
- p_indent(level, frm);
- switch (event) {
- case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
- status = p_get_u8(frm);
- printf("PlayStatus: 0x%02x (%s)\n", status,
- playstatus2str(status));
- break;
- case AVRCP_EVENT_TRACK_CHANGED:
- id = p_get_u64(frm);
- printf("Identifier: 0x%16" PRIx64 " (%" PRIu64 ")\n", id, id);
- break;
- case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
- interval = p_get_u32(frm);
- printf("Position: 0x%08x (%u miliseconds)\n", interval,
- interval);
- break;
- case AVRCP_EVENT_BATT_STATUS_CHANGED:
- status = p_get_u8(frm);
- printf("BatteryStatus: 0x%02x (%s)\n", status,
- status2str(status));
- break;
- case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
- status = p_get_u8(frm);
- printf("SystemStatus: 0x%02x ", status);
- switch (status) {
- case 0x00:
- printf("(POWER_ON)\n");
- break;
- case 0x01:
- printf("(POWER_OFF)\n");
- break;
- case 0x02:
- printf("(UNPLUGGED)\n");
- break;
- default:
- printf("(UNKOWN)\n");
- break;
- }
- break;
- case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
- status = p_get_u8(frm);
- printf("AttributeCount: 0x%02x\n", status);
- for (; status > 0; status--) {
- uint8_t attr, value;
- p_indent(level, frm);
- attr = p_get_u8(frm);
- printf("AttributeID: 0x%02x (%s)\n", attr,
- attr2str(attr));
- p_indent(level, frm);
- value = p_get_u8(frm);
- printf("ValueID: 0x%02x (%s)\n", value,
- value2str(attr, value));
- }
- break;
- case AVRCP_EVENT_VOLUME_CHANGED:
- status = p_get_u8(frm) & 0x7F;
- printf("Volume: %.2f%% (%d/127)\n", status/1.27, status);
- break;
- case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
- uid = p_get_u16(frm);
- printf("PlayerID: 0x%04x (%u)\n", uid, uid);
- p_indent(level, frm);
- uid = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
- break;
- case AVRCP_EVENT_UIDS_CHANGED:
- uid = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
- break;
- }
- }
- static void avrcp_set_absolute_volume_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint8_t value;
- p_indent(level, frm);
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- value = p_get_u8(frm) & 0x7F;
- printf("Volume: %.2f%% (%d/127)\n", value/1.27, value);
- }
- static void avrcp_set_addressed_player(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint16_t id;
- uint8_t status;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- if (len < 2) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- id = p_get_u16(frm);
- printf("PlayerID: 0x%04x (%u)\n", id, id);
- return;
- response:
- if (len < 1) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- }
- static void avrcp_set_browsed_player_dump(int level, struct frame *frm,
- uint8_t hdr, uint16_t len)
- {
- uint32_t items;
- uint16_t id, uids, charset;
- uint8_t status, folders;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- if (len < 2) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- id = p_get_u16(frm);
- printf("PlayerID: 0x%04x (%u)\n", id, id);
- return;
- response:
- if (len != 1 && len < 10) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- if (len == 1)
- return;
- p_indent(level, frm);
- uids = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uids, uids);
- p_indent(level, frm);
- items = p_get_u32(frm);
- printf("Number of Items: 0x%08x (%u)\n", items, items);
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
- p_indent(level, frm);
- folders = p_get_u8(frm);
- printf("Folder Depth: 0x%02x (%u)\n", folders, folders);
- for (; folders > 0; folders--) {
- uint16_t len;
- p_indent(level, frm);
- len = p_get_u8(frm);
- printf("Folder: ");
- for (; len > 0; len--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- }
- static const char *scope2str(uint8_t scope)
- {
- switch (scope) {
- case AVRCP_MEDIA_PLAYER_LIST:
- return "Media Player List";
- case AVRCP_MEDIA_PLAYER_VFS:
- return "Media Player Virtual Filesystem";
- case AVRCP_MEDIA_SEARCH:
- return "Search";
- case AVRCP_MEDIA_NOW_PLAYING:
- return "Now Playing";
- default:
- return "Unknown";
- }
- }
- static void avrcp_play_item_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint64_t uid;
- uint32_t uidcounter;
- uint8_t scope, status;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- if (len < 11) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- scope = p_get_u8(frm);
- printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
- p_indent(level, frm);
- uid = p_get_u64(frm);
- printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- p_indent(level, frm);
- uidcounter = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- }
- static void avrcp_add_to_now_playing_dump(int level, struct frame *frm,
- uint8_t ctype, uint16_t len)
- {
- uint64_t uid;
- uint32_t uidcounter;
- uint8_t scope, status;
- p_indent(level, frm);
- if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
- goto response;
- if (len < 11) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- scope = p_get_u8(frm);
- printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
- p_indent(level, frm);
- uid = p_get_u64(frm);
- printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- p_indent(level, frm);
- uidcounter = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- }
- static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
- {
- uint8_t pduid, pt;
- uint16_t len;
- p_indent(level, frm);
- pduid = p_get_u8(frm);
- pt = p_get_u8(frm);
- len = p_get_u16(frm);
- printf("AVRCP: %s: pt %s len 0x%04x\n", pdu2str(pduid),
- pt2str(pt), len);
- if (len != frm->len) {
- p_indent(level, frm);
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- if (ctype == AVC_CTYPE_REJECTED) {
- avrcp_rejected_dump(level + 1, frm, len);
- return;
- }
- switch (pduid) {
- case AVRCP_GET_CAPABILITIES:
- avrcp_get_capabilities_dump(level + 1, frm, len);
- break;
- case AVRCP_LIST_PLAYER_ATTRIBUTES:
- avrcp_list_player_attributes_dump(level + 1, frm, len);
- break;
- case AVRCP_LIST_PLAYER_VALUES:
- avrcp_list_player_values_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_GET_CURRENT_PLAYER_VALUE:
- avrcp_get_current_player_value_dump(level + 1, frm, ctype,
- len);
- break;
- case AVRCP_SET_PLAYER_VALUE:
- avrcp_set_player_value_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
- avrcp_get_player_attribute_text_dump(level + 1, frm, ctype,
- len);
- break;
- case AVRCP_GET_PLAYER_VALUE_TEXT:
- avrcp_get_player_value_text_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_DISPLAYABLE_CHARSET:
- avrcp_displayable_charset(level + 1, frm, ctype, len);
- break;
- case AVRCP_CT_BATTERY_STATUS:
- avrcp_ct_battery_status_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_GET_ELEMENT_ATTRIBUTES:
- avrcp_get_element_attributes_dump(level + 1, frm, ctype, len,
- pt);
- break;
- case AVRCP_GET_PLAY_STATUS:
- avrcp_get_play_status_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_REGISTER_NOTIFICATION:
- avrcp_register_notification_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_SET_ABSOLUTE_VOLUME:
- avrcp_set_absolute_volume_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_SET_ADDRESSED_PLAYER:
- avrcp_set_addressed_player(level + 1, frm, ctype, len);
- break;
- case AVRCP_PLAY_ITEM:
- avrcp_play_item_dump(level + 1, frm, ctype, len);
- break;
- case AVRCP_ADD_TO_NOW_PLAYING:
- avrcp_add_to_now_playing_dump(level + 1, frm, ctype, len);
- break;
- default:
- raw_dump(level, frm);
- }
- }
- static char *op2str(uint8_t op)
- {
- switch (op & 0x7f) {
- case AVC_PANEL_VOLUME_UP:
- return "VOLUME UP";
- case AVC_PANEL_VOLUME_DOWN:
- return "VOLUME DOWN";
- case AVC_PANEL_MUTE:
- return "MUTE";
- case AVC_PANEL_PLAY:
- return "PLAY";
- case AVC_PANEL_STOP:
- return "STOP";
- case AVC_PANEL_PAUSE:
- return "PAUSE";
- case AVC_PANEL_RECORD:
- return "RECORD";
- case AVC_PANEL_REWIND:
- return "REWIND";
- case AVC_PANEL_FAST_FORWARD:
- return "FAST FORWARD";
- case AVC_PANEL_EJECT:
- return "EJECT";
- case AVC_PANEL_FORWARD:
- return "FORWARD";
- case AVC_PANEL_BACKWARD:
- return "BACKWARD";
- default:
- return "UNKNOWN";
- }
- }
- static void avrcp_passthrough_dump(int level, struct frame *frm)
- {
- uint8_t op, len;
- p_indent(level, frm);
- op = p_get_u8(frm);
- printf("Operation: 0x%02x (%s %s)\n", op, op2str(op),
- op & 0x80 ? "Released" : "Pressed");
- p_indent(level, frm);
- len = p_get_u8(frm);
- printf("Lenght: 0x%02x\n", len);
- raw_dump(level, frm);
- }
- static const char *subunit2str(uint8_t subunit)
- {
- switch (subunit) {
- case AVC_SUBUNIT_MONITOR:
- return "Monitor";
- case AVC_SUBUNIT_AUDIO:
- return "Audio";
- case AVC_SUBUNIT_PRINTER:
- return "Printer";
- case AVC_SUBUNIT_DISC:
- return "Disc";
- case AVC_SUBUNIT_TAPE:
- return "Tape";
- case AVC_SUBUNIT_TURNER:
- return "Turner";
- case AVC_SUBUNIT_CA:
- return "CA";
- case AVC_SUBUNIT_CAMERA:
- return "Camera";
- case AVC_SUBUNIT_PANEL:
- return "Panel";
- case AVC_SUBUNIT_BULLETIN_BOARD:
- return "Bulleting Board";
- case AVC_SUBUNIT_CAMERA_STORAGE:
- return "Camera Storage";
- case AVC_SUBUNIT_VENDOR_UNIQUE:
- return "Vendor Unique";
- case AVC_SUBUNIT_EXTENDED:
- return "Extended to next byte";
- case AVC_SUBUNIT_UNIT:
- return "Unit";
- default:
- return "Reserved";
- }
- }
- static const char *playertype2str(uint8_t type)
- {
- switch (type & 0x0F) {
- case 0x01:
- return "Audio";
- case 0x02:
- return "Video";
- case 0x03:
- return "Audio, Video";
- case 0x04:
- return "Audio Broadcasting";
- case 0x05:
- return "Audio, Audio Broadcasting";
- case 0x06:
- return "Video, Audio Broadcasting";
- case 0x07:
- return "Audio, Video, Audio Broadcasting";
- case 0x08:
- return "Video Broadcasting";
- case 0x09:
- return "Audio, Video Broadcasting";
- case 0x0A:
- return "Video, Video Broadcasting";
- case 0x0B:
- return "Audio, Video, Video Broadcasting";
- case 0x0C:
- return "Audio Broadcasting, Video Broadcasting";
- case 0x0D:
- return "Audio, Audio Broadcasting, Video Broadcasting";
- case 0x0E:
- return "Video, Audio Broadcasting, Video Broadcasting";
- case 0x0F:
- return "Audio, Video, Audio Broadcasting, Video Broadcasting";
- }
- return "None";
- }
- static const char *playersubtype2str(uint32_t subtype)
- {
- switch (subtype & 0x03) {
- case 0x01:
- return "Audio Book";
- case 0x02:
- return "Podcast";
- case 0x03:
- return "Audio Book, Podcast";
- }
- return "None";
- }
- static void avrcp_media_player_item_dump(int level, struct frame *frm,
- uint16_t len)
- {
- uint16_t id, charset, namelen;
- uint8_t type, status;
- uint32_t subtype;
- uint64_t features[2];
- p_indent(level, frm);
- if (len < 28) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- id = p_get_u16(frm);
- printf("PlayerID: 0x%04x (%u)\n", id, id);
- p_indent(level, frm);
- type = p_get_u8(frm);
- printf("PlayerType: 0x%04x (%s)\n", type, playertype2str(type));
- p_indent(level, frm);
- subtype = p_get_u32(frm);
- printf("PlayerSubtype: 0x%08x (%s)\n", subtype,
- playersubtype2str(subtype));
- p_indent(level, frm);
- status = p_get_u8(frm);
- printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
- p_indent(level, frm);
- p_get_u128(frm, &features[0], &features[1]);
- printf("Features: 0x%16" PRIx64 "%16" PRIx64 "\n", features[1],
- features[0]);
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
- p_indent(level, frm);
- namelen = p_get_u16(frm);
- printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
- p_indent(level, frm);
- printf("Name: ");
- for (; namelen > 0; namelen--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- static const char *foldertype2str(uint8_t type)
- {
- switch (type) {
- case 0x00:
- return "Mixed";
- case 0x01:
- return "Titles";
- case 0x02:
- return "Albuns";
- case 0x03:
- return "Artists";
- case 0x04:
- return "Genres";
- case 0x05:
- return "Playlists";
- case 0x06:
- return "Years";
- }
- return "Reserved";
- }
- static void avrcp_folder_item_dump(int level, struct frame *frm, uint16_t len)
- {
- uint8_t type, playable;
- uint16_t charset, namelen;
- uint64_t uid;
- p_indent(level, frm);
- if (len < 14) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- uid = p_get_u64(frm);
- printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- p_indent(level, frm);
- type = p_get_u8(frm);
- printf("FolderType: 0x%02x (%s)\n", type, foldertype2str(type));
- p_indent(level, frm);
- playable = p_get_u8(frm);
- printf("IsPlayable: 0x%02x (%s)\n", playable,
- playable & 0x01 ? "True" : "False");
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
- p_indent(level, frm);
- namelen = p_get_u16(frm);
- printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
- p_indent(level, frm);
- printf("Name: ");
- for (; namelen > 0; namelen--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- static const char *elementtype2str(uint8_t type)
- {
- switch (type) {
- case 0x00:
- return "Audio";
- case 0x01:
- return "Video";
- }
- return "Reserved";
- }
- static void avrcp_attribute_entry_list_dump(int level, struct frame *frm,
- uint8_t count)
- {
- for (; count > 0; count--) {
- uint32_t attr;
- uint16_t charset;
- uint8_t len;
- p_indent(level, frm);
- attr = p_get_u32(frm);
- printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset,
- charset2str(charset));
- p_indent(level, frm);
- len = p_get_u16(frm);
- printf("AttributeLength: 0x%04x (%u)\n", len, len);
- p_indent(level, frm);
- printf("AttributeValue: ");
- for (; len > 0; len--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- }
- }
- static void avrcp_media_element_item_dump(int level, struct frame *frm,
- uint16_t len)
- {
- uint64_t uid;
- uint16_t charset, namelen;
- uint8_t type, count;
- p_indent(level, frm);
- if (len < 14) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- uid = p_get_u64(frm);
- printf("ElementUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- p_indent(level, frm);
- type = p_get_u8(frm);
- printf("ElementType: 0x%02x (%s)\n", type, elementtype2str(type));
- p_indent(level, frm);
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
- p_indent(level, frm);
- namelen = p_get_u16(frm);
- printf("NameLength: 0x%04x (%u)\n", namelen, namelen);
- p_indent(level, frm);
- printf("Name: ");
- for (; namelen > 0; namelen--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- p_indent(level, frm);
- count = p_get_u8(frm);
- printf("AttributeCount: 0x%02x (%u)\n", count, count);
- avrcp_attribute_entry_list_dump(level, frm, count);
- }
- static void avrcp_get_folder_items_dump(int level, struct frame *frm,
- uint8_t hdr, uint16_t len)
- {
- uint8_t scope, count, status;
- uint32_t start, end;
- uint16_t uid, num;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- if (len < 10) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- scope = p_get_u8(frm);
- printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
- p_indent(level, frm);
- start = p_get_u32(frm);
- printf("StartItem: 0x%08x (%u)\n", start, start);
- p_indent(level, frm);
- end = p_get_u32(frm);
- printf("EndItem: 0x%08x (%u)\n", end, end);
- p_indent(level, frm);
- count = p_get_u8(frm);
- printf("AttributeCount: 0x%02x (%u)\n", count, count);
- for (; count > 0; count--) {
- uint32_t attr;
- p_indent(level, frm);
- attr = p_get_u32(frm);
- printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
- }
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- if (len == 1)
- return;
- p_indent(level, frm);
- uid = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uid, uid);
- p_indent(level, frm);
- num = p_get_u16(frm);
- printf("Number of Items: 0x%04x (%u)\n", num, num);
- for (; num > 0; num--) {
- uint8_t type;
- uint16_t len;
- p_indent(level, frm);
- type = p_get_u8(frm);
- len = p_get_u16(frm);
- switch (type) {
- case 0x01:
- printf("Item: 0x01 (Media Player)) ");
- printf("Length: 0x%04x (%u)\n", len, len);
- avrcp_media_player_item_dump(level, frm, len);
- break;
- case 0x02:
- printf("Item: 0x02 (Folder) ");
- printf("Length: 0x%04x (%u)\n", len, len);
- avrcp_folder_item_dump(level, frm, len);
- break;
- case 0x03:
- printf("Item: 0x03 (Media Element) ");
- printf("Length: 0x%04x (%u)\n", len, len);
- avrcp_media_element_item_dump(level, frm, len);
- break;
- }
- }
- }
- static const char *dir2str(uint8_t dir)
- {
- switch (dir) {
- case 0x00:
- return "Folder Up";
- case 0x01:
- return "Folder Down";
- }
- return "Reserved";
- }
- static void avrcp_change_path_dump(int level, struct frame *frm, uint8_t hdr,
- uint16_t len)
- {
- uint64_t uid;
- uint32_t items;
- uint16_t uidcounter;
- uint8_t dir, status;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- if (len < 11) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- uidcounter = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
- p_indent(level, frm);
- dir = p_get_u8(frm);
- printf("Direction: 0x%02x (%s)\n", dir, dir2str(dir));
- p_indent(level, frm);
- uid = p_get_u64(frm);
- printf("FolderUID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- if (len == 1)
- return;
- p_indent(level, frm);
- items = p_get_u32(frm);
- printf("Number of Items: 0x%04x (%u)", items, items);
- }
- static void avrcp_get_item_attributes_dump(int level, struct frame *frm,
- uint8_t hdr, uint16_t len)
- {
- uint64_t uid;
- uint32_t uidcounter;
- uint8_t scope, count, status;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- if (len < 12) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- scope = p_get_u8(frm);
- printf("Scope: 0x%02x (%s)\n", scope, scope2str(scope));
- p_indent(level, frm);
- uid = p_get_u64(frm);
- printf("UID: 0x%16" PRIx64 " (%" PRIu64 ")\n", uid, uid);
- p_indent(level, frm);
- uidcounter = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
- p_indent(level, frm);
- count = p_get_u8(frm);
- printf("AttributeCount: 0x%02x (%u)\n", count, count);
- for (; count > 0; count--) {
- uint32_t attr;
- p_indent(level, frm);
- attr = p_get_u32(frm);
- printf("AttributeID: 0x%08x (%s)\n", attr, mediattr2str(attr));
- }
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- if (len == 1)
- return;
- p_indent(level, frm);
- count = p_get_u8(frm);
- printf("AttributeCount: 0x%02x (%u)\n", count, count);
- avrcp_attribute_entry_list_dump(level, frm, count);
- }
- static void avrcp_search_dump(int level, struct frame *frm, uint8_t hdr,
- uint16_t len)
- {
- uint32_t uidcounter, items;
- uint16_t charset, namelen;
- uint8_t status;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- if (len < 4) {
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- charset = p_get_u16(frm);
- printf("CharsetID: 0x%04x (%s)\n", charset, charset2str(charset));
- p_indent(level, frm);
- namelen = p_get_u16(frm);
- printf("Length: 0x%04x (%u)\n", namelen, namelen);
- p_indent(level, frm);
- printf("String: ");
- for (; namelen > 0; namelen--) {
- uint8_t c = p_get_u8(frm);
- printf("%1c", isprint(c) ? c : '.');
- }
- printf("\n");
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- if (len == 1)
- return;
- p_indent(level, frm);
- uidcounter = p_get_u16(frm);
- printf("UIDCounter: 0x%04x (%u)\n", uidcounter, uidcounter);
- p_indent(level, frm);
- items = p_get_u32(frm);
- printf("Number of Items: 0x%04x (%u)", items, items);
- }
- static void avrcp_general_reject_dump(int level, struct frame *frm,
- uint8_t hdr, uint16_t len)
- {
- uint8_t status;
- p_indent(level, frm);
- if (hdr & 0x02)
- goto response;
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- response:
- status = p_get_u8(frm);
- printf("Status: 0x%02x (%s)\n", status, error2str(status));
- }
- static void avrcp_browsing_dump(int level, struct frame *frm, uint8_t hdr)
- {
- uint8_t pduid;
- uint16_t len;
- pduid = p_get_u8(frm);
- len = p_get_u16(frm);
- printf("AVRCP: %s: len 0x%04x\n", pdu2str(pduid), len);
- if (len != frm->len) {
- p_indent(level, frm);
- printf("PDU Malformed\n");
- raw_dump(level, frm);
- return;
- }
- switch (pduid) {
- case AVRCP_SET_BROWSED_PLAYER:
- avrcp_set_browsed_player_dump(level + 1, frm, hdr, len);
- break;
- case AVRCP_GET_FOLDER_ITEMS:
- avrcp_get_folder_items_dump(level + 1, frm, hdr, len);
- break;
- case AVRCP_CHANGE_PATH:
- avrcp_change_path_dump(level + 1, frm, hdr, len);
- break;
- case AVRCP_GET_ITEM_ATTRIBUTES:
- avrcp_get_item_attributes_dump(level + 1, frm, hdr, len);
- break;
- case AVRCP_SEARCH:
- avrcp_search_dump(level + 1, frm, hdr, len);
- break;
- case AVRCP_GENERAL_REJECT:
- avrcp_general_reject_dump(level + 1, frm, hdr, len);
- break;
- default:
- raw_dump(level, frm);
- }
- }
- static void avrcp_control_dump(int level, struct frame *frm)
- {
- uint8_t ctype, address, subunit, opcode, company[3];
- int i;
- ctype = p_get_u8(frm);
- address = p_get_u8(frm);
- opcode = p_get_u8(frm);
- printf("AV/C: %s: address 0x%02x opcode 0x%02x\n", ctype2str(ctype),
- address, opcode);
- p_indent(level + 1, frm);
- subunit = address >> 3;
- printf("Subunit: %s\n", subunit2str(subunit));
- p_indent(level + 1, frm);
- printf("Opcode: %s\n", opcode2str(opcode));
- /* Skip non-panel subunit packets */
- if (subunit != AVC_SUBUNIT_PANEL) {
- raw_dump(level, frm);
- return;
- }
- /* Not implemented should not contain any operand */
- if (ctype == AVC_CTYPE_NOT_IMPLEMENTED) {
- raw_dump(level, frm);
- return;
- }
- switch (opcode) {
- case AVC_OP_PASSTHROUGH:
- avrcp_passthrough_dump(level + 1, frm);
- break;
- case AVC_OP_VENDORDEP:
- p_indent(level + 1, frm);
- printf("Company ID: 0x");
- for (i = 0; i < 3; i++) {
- company[i] = p_get_u8(frm);
- printf("%02x", company[i]);
- }
- printf("\n");
- avrcp_pdu_dump(level + 1, frm, ctype);
- break;
- default:
- raw_dump(level, frm);
- }
- }
- void avrcp_dump(int level, struct frame *frm, uint8_t hdr, uint16_t psm)
- {
- p_indent(level, frm);
- switch (psm) {
- case 0x17:
- avrcp_control_dump(level, frm);
- break;
- case 0x1B:
- avrcp_browsing_dump(level, frm, hdr);
- break;
- default:
- raw_dump(level, frm);
- }
- }
|