avctp.c 57 KB

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