avrcp-lib.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2014 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <stdbool.h>
  15. #include <glib.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. #include "lib/bluetooth.h"
  19. #include "src/shared/util.h"
  20. #include "src/log.h"
  21. #include "avctp.h"
  22. #include "avrcp-lib.h"
  23. /* Packet types */
  24. #define AVRCP_PACKET_TYPE_SINGLE 0x00
  25. #define AVRCP_PACKET_TYPE_START 0x01
  26. #define AVRCP_PACKET_TYPE_CONTINUING 0x02
  27. #define AVRCP_PACKET_TYPE_END 0x03
  28. #define AVRCP_CHARSET_UTF8 0x006a
  29. #if __BYTE_ORDER == __LITTLE_ENDIAN
  30. struct avrcp_header {
  31. uint8_t company_id[3];
  32. uint8_t pdu_id;
  33. uint8_t packet_type:2;
  34. uint8_t rsvd:6;
  35. uint16_t params_len;
  36. uint8_t params[0];
  37. } __attribute__ ((packed));
  38. #define AVRCP_HEADER_LENGTH 7
  39. #elif __BYTE_ORDER == __BIG_ENDIAN
  40. struct avrcp_header {
  41. uint8_t company_id[3];
  42. uint8_t pdu_id;
  43. uint8_t rsvd:6;
  44. uint8_t packet_type:2;
  45. uint16_t params_len;
  46. uint8_t params[0];
  47. } __attribute__ ((packed));
  48. #define AVRCP_HEADER_LENGTH 7
  49. #else
  50. #error "Unknown byte order"
  51. #endif
  52. struct avrcp_browsing_header {
  53. uint8_t pdu_id;
  54. uint16_t params_len;
  55. uint8_t params[0];
  56. } __attribute__ ((packed));
  57. #define AVRCP_BROWSING_HEADER_LENGTH 3
  58. struct get_capabilities_req {
  59. uint8_t cap;
  60. uint8_t params[0];
  61. } __attribute__ ((packed));
  62. struct get_capabilities_rsp {
  63. uint8_t cap;
  64. uint8_t number;
  65. uint8_t params[0];
  66. } __attribute__ ((packed));
  67. struct list_attributes_rsp {
  68. uint8_t number;
  69. uint8_t params[0];
  70. } __attribute__ ((packed));
  71. struct list_values_req {
  72. uint8_t attr;
  73. } __attribute__ ((packed));
  74. struct list_values_rsp {
  75. uint8_t number;
  76. uint8_t params[0];
  77. } __attribute__ ((packed));
  78. struct get_value_req {
  79. uint8_t number;
  80. uint8_t attrs[0];
  81. } __attribute__ ((packed));
  82. struct attr_value {
  83. uint8_t attr;
  84. uint8_t value;
  85. } __attribute__ ((packed));
  86. struct value_rsp {
  87. uint8_t number;
  88. struct attr_value values[0];
  89. } __attribute__ ((packed));
  90. struct set_value_req {
  91. uint8_t number;
  92. struct attr_value values[0];
  93. } __attribute__ ((packed));
  94. struct get_attribute_text_req {
  95. uint8_t number;
  96. uint8_t attrs[0];
  97. } __attribute__ ((packed));
  98. struct text_value {
  99. uint8_t attr;
  100. uint16_t charset;
  101. uint8_t len;
  102. char data[0];
  103. } __attribute__ ((packed));
  104. struct get_attribute_text_rsp {
  105. uint8_t number;
  106. struct text_value values[0];
  107. } __attribute__ ((packed));
  108. struct get_value_text_req {
  109. uint8_t attr;
  110. uint8_t number;
  111. uint8_t values[0];
  112. } __attribute__ ((packed));
  113. struct get_value_text_rsp {
  114. uint8_t number;
  115. struct text_value values[0];
  116. } __attribute__ ((packed));
  117. struct media_item {
  118. uint32_t attr;
  119. uint16_t charset;
  120. uint16_t len;
  121. char data[0];
  122. } __attribute__ ((packed));
  123. struct get_element_attributes_req {
  124. uint64_t id;
  125. uint8_t number;
  126. uint32_t attrs[0];
  127. } __attribute__ ((packed));
  128. struct get_element_attributes_rsp {
  129. uint8_t number;
  130. struct media_item items[0];
  131. } __attribute__ ((packed));
  132. struct get_play_status_rsp {
  133. uint32_t duration;
  134. uint32_t position;
  135. uint8_t status;
  136. } __attribute__ ((packed));
  137. struct register_notification_req {
  138. uint8_t event;
  139. uint32_t interval;
  140. } __attribute__ ((packed));
  141. struct register_notification_rsp {
  142. uint8_t event;
  143. uint8_t data[0];
  144. } __attribute__ ((packed));
  145. struct set_volume_req {
  146. uint8_t value;
  147. } __attribute__ ((packed));
  148. struct set_volume_rsp {
  149. uint8_t value;
  150. } __attribute__ ((packed));
  151. struct set_addressed_req {
  152. uint16_t id;
  153. } __attribute__ ((packed));
  154. struct set_addressed_rsp {
  155. uint8_t status;
  156. } __attribute__ ((packed));
  157. struct set_browsed_req {
  158. uint16_t id;
  159. } __attribute__ ((packed));
  160. struct set_browsed_rsp {
  161. uint8_t status;
  162. uint16_t counter;
  163. uint32_t items;
  164. uint16_t charset;
  165. uint8_t depth;
  166. uint8_t data[0];
  167. } __attribute__ ((packed));
  168. struct get_folder_items_req {
  169. uint8_t scope;
  170. uint32_t start;
  171. uint32_t end;
  172. uint8_t number;
  173. uint32_t attrs[0];
  174. } __attribute__ ((packed));
  175. struct get_folder_items_rsp {
  176. uint8_t status;
  177. uint16_t counter;
  178. uint16_t number;
  179. uint8_t data[0];
  180. } __attribute__ ((packed));
  181. struct change_path_req {
  182. uint16_t counter;
  183. uint8_t direction;
  184. uint64_t uid;
  185. } __attribute__ ((packed));
  186. struct change_path_rsp {
  187. uint8_t status;
  188. uint32_t items;
  189. } __attribute__ ((packed));
  190. struct get_item_attributes_req {
  191. uint8_t scope;
  192. uint64_t uid;
  193. uint16_t counter;
  194. uint8_t number;
  195. uint32_t attrs[0];
  196. } __attribute__ ((packed));
  197. struct get_item_attributes_rsp {
  198. uint8_t status;
  199. uint8_t number;
  200. struct media_item items[0];
  201. } __attribute__ ((packed));
  202. struct play_item_req {
  203. uint8_t scope;
  204. uint64_t uid;
  205. uint16_t counter;
  206. } __attribute__ ((packed));
  207. struct play_item_rsp {
  208. uint8_t status;
  209. } __attribute__ ((packed));
  210. struct search_req {
  211. uint16_t charset;
  212. uint16_t len;
  213. char string[0];
  214. } __attribute__ ((packed));
  215. struct search_rsp {
  216. uint8_t status;
  217. uint16_t counter;
  218. uint32_t items;
  219. } __attribute__ ((packed));
  220. struct add_to_now_playing_req {
  221. uint8_t scope;
  222. uint64_t uid;
  223. uint16_t counter;
  224. } __attribute__ ((packed));
  225. struct add_to_now_playing_rsp {
  226. uint8_t status;
  227. } __attribute__ ((packed));
  228. struct avrcp_control_handler {
  229. uint8_t id;
  230. uint8_t code;
  231. uint8_t rsp;
  232. ssize_t (*func) (struct avrcp *session, uint8_t transaction,
  233. uint16_t params_len, uint8_t *params, void *user_data);
  234. };
  235. struct avrcp_browsing_handler {
  236. uint8_t id;
  237. ssize_t (*func) (struct avrcp *session, uint8_t transaction,
  238. uint16_t params_len, uint8_t *params, void *user_data);
  239. };
  240. struct avrcp_continuing {
  241. uint8_t pdu_id;
  242. struct iovec pdu;
  243. };
  244. struct avrcp {
  245. struct avctp *conn;
  246. struct avrcp_player *player;
  247. const struct avrcp_control_handler *control_handlers;
  248. void *control_data;
  249. unsigned int control_id;
  250. uint16_t control_mtu;
  251. struct avrcp_continuing *continuing;
  252. const struct avrcp_passthrough_handler *passthrough_handlers;
  253. void *passthrough_data;
  254. unsigned int passthrough_id;
  255. const struct avrcp_browsing_handler *browsing_handlers;
  256. void *browsing_data;
  257. unsigned int browsing_id;
  258. avrcp_destroy_cb_t destroy;
  259. void *destroy_data;
  260. };
  261. struct avrcp_player {
  262. const struct avrcp_control_ind *ind;
  263. const struct avrcp_control_cfm *cfm;
  264. void *user_data;
  265. };
  266. static inline uint32_t ntoh24(const uint8_t src[3])
  267. {
  268. return src[0] << 16 | src[1] << 8 | src[2];
  269. }
  270. static inline void hton24(uint8_t dst[3], uint32_t src)
  271. {
  272. dst[0] = (src & 0xff0000) >> 16;
  273. dst[1] = (src & 0x00ff00) >> 8;
  274. dst[2] = (src & 0x0000ff);
  275. }
  276. static void continuing_free(struct avrcp_continuing *continuing)
  277. {
  278. g_free(continuing->pdu.iov_base);
  279. g_free(continuing);
  280. }
  281. void avrcp_shutdown(struct avrcp *session)
  282. {
  283. if (session->conn) {
  284. if (session->control_id > 0)
  285. avctp_unregister_pdu_handler(session->conn,
  286. session->control_id);
  287. if (session->passthrough_id > 0)
  288. avctp_unregister_passthrough_handler(session->conn,
  289. session->passthrough_id);
  290. if (session->browsing_id > 0)
  291. avctp_unregister_browsing_pdu_handler(session->conn,
  292. session->browsing_id);
  293. /* clear destroy callback that would call shutdown again */
  294. avctp_set_destroy_cb(session->conn, NULL, NULL);
  295. avctp_shutdown(session->conn);
  296. }
  297. if (session->destroy)
  298. session->destroy(session->destroy_data);
  299. if (session->continuing)
  300. continuing_free(session->continuing);
  301. g_free(session->player);
  302. g_free(session);
  303. }
  304. static struct avrcp_header *parse_pdu(uint8_t *operands, size_t operand_count)
  305. {
  306. struct avrcp_header *pdu;
  307. if (!operands || operand_count < sizeof(*pdu)) {
  308. error("AVRCP: packet too small (%zu bytes)", operand_count);
  309. return NULL;
  310. }
  311. pdu = (void *) operands;
  312. pdu->params_len = ntohs(pdu->params_len);
  313. if (operand_count != pdu->params_len + sizeof(*pdu)) {
  314. error("AVRCP: invalid parameter length (%u bytes)",
  315. pdu->params_len);
  316. return NULL;
  317. }
  318. return pdu;
  319. }
  320. static struct avrcp_browsing_header *parse_browsing_pdu(uint8_t *operands,
  321. size_t operand_count)
  322. {
  323. struct avrcp_browsing_header *pdu;
  324. if (!operands || operand_count < sizeof(*pdu)) {
  325. error("AVRCP: packet too small (%zu bytes)", operand_count);
  326. return NULL;
  327. }
  328. pdu = (void *) operands;
  329. pdu->params_len = ntohs(pdu->params_len);
  330. if (operand_count != pdu->params_len + sizeof(*pdu)) {
  331. error("AVRCP: invalid parameter length (%u bytes)",
  332. pdu->params_len);
  333. return NULL;
  334. }
  335. return pdu;
  336. }
  337. static uint8_t errno2status(int err)
  338. {
  339. switch (err) {
  340. case -ENOSYS:
  341. return AVRCP_STATUS_INVALID_COMMAND;
  342. case -EINVAL:
  343. return AVRCP_STATUS_INVALID_PARAM;
  344. case 0:
  345. return AVRCP_STATUS_SUCCESS;
  346. case -ENOTDIR:
  347. return AVRCP_STATUS_NOT_DIRECTORY;
  348. case -EBADRQC:
  349. return AVRCP_STATUS_INVALID_SCOPE;
  350. case -ERANGE:
  351. return AVRCP_STATUS_OUT_OF_BOUNDS;
  352. case -ENOENT:
  353. return AVRCP_STATUS_DOES_NOT_EXIST;
  354. default:
  355. return AVRCP_STATUS_INTERNAL_ERROR;
  356. }
  357. }
  358. static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
  359. uint8_t *code, uint8_t *subunit,
  360. uint8_t *operands, size_t operand_count,
  361. void *user_data)
  362. {
  363. struct avrcp *session = user_data;
  364. const struct avrcp_control_handler *handler;
  365. struct avrcp_header *pdu;
  366. uint32_t company_id;
  367. ssize_t ret;
  368. pdu = parse_pdu(operands, operand_count);
  369. if (!pdu) {
  370. pdu = (void *) operands;
  371. pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
  372. goto reject;
  373. }
  374. company_id = ntoh24(pdu->company_id);
  375. if (company_id != IEEEID_BTSIG) {
  376. *code = AVC_CTYPE_NOT_IMPLEMENTED;
  377. return 0;
  378. }
  379. DBG("AVRCP PDU 0x%02X, len 0x%04X", pdu->pdu_id, pdu->params_len);
  380. pdu->packet_type = 0;
  381. pdu->rsvd = 0;
  382. if (!session->control_handlers)
  383. goto reject;
  384. for (handler = session->control_handlers; handler->id; handler++) {
  385. if (handler->id == pdu->pdu_id)
  386. break;
  387. }
  388. if (handler->id != pdu->pdu_id || handler->code != *code) {
  389. pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
  390. goto reject;
  391. }
  392. if (!handler->func) {
  393. pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
  394. goto reject;
  395. }
  396. ret = handler->func(session, transaction, pdu->params_len, pdu->params,
  397. session->control_data);
  398. if (ret == 0)
  399. return -EAGAIN;
  400. if (ret < 0) {
  401. if (ret == -EAGAIN)
  402. return ret;
  403. pdu->params[0] = errno2status(ret);
  404. goto reject;
  405. }
  406. *code = handler->rsp;
  407. pdu->params_len = htons(ret);
  408. return AVRCP_HEADER_LENGTH + ret;
  409. reject:
  410. pdu->params_len = htons(1);
  411. *code = AVC_CTYPE_REJECTED;
  412. return AVRCP_HEADER_LENGTH + 1;
  413. }
  414. static bool handle_passthrough_pdu(struct avctp *conn, uint8_t op,
  415. bool pressed, void *user_data)
  416. {
  417. struct avrcp *session = user_data;
  418. const struct avrcp_passthrough_handler *handler;
  419. if (!session->passthrough_handlers)
  420. return false;
  421. for (handler = session->passthrough_handlers; handler->func;
  422. handler++) {
  423. if (handler->op == op)
  424. break;
  425. }
  426. if (handler->func == NULL)
  427. return false;
  428. return handler->func(session, pressed, session->passthrough_data);
  429. }
  430. static void disconnect_cb(void *data)
  431. {
  432. struct avrcp *session = data;
  433. session->conn = NULL;
  434. avrcp_shutdown(session);
  435. }
  436. struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
  437. {
  438. struct avrcp *session;
  439. session = g_new0(struct avrcp, 1);
  440. session->conn = avctp_new(fd, imtu, omtu, version);
  441. if (!session->conn) {
  442. g_free(session);
  443. return NULL;
  444. }
  445. session->passthrough_id = avctp_register_passthrough_handler(
  446. session->conn,
  447. handle_passthrough_pdu,
  448. session);
  449. session->control_id = avctp_register_pdu_handler(session->conn,
  450. AVC_OP_VENDORDEP,
  451. handle_vendordep_pdu,
  452. session);
  453. session->control_mtu = omtu - AVC_DATA_OFFSET;
  454. /*
  455. * 27.1.2 AV/C Command Frame
  456. * An AV/C command frame contains up to 512 octets of data
  457. */
  458. if (session->control_mtu > AVC_DATA_MTU)
  459. session->control_mtu = AVC_DATA_MTU;
  460. avctp_set_destroy_cb(session->conn, disconnect_cb, session);
  461. return session;
  462. }
  463. static ssize_t handle_browsing_pdu(struct avctp *conn,
  464. uint8_t transaction, uint8_t *operands,
  465. size_t operand_count, void *user_data)
  466. {
  467. struct avrcp *session = user_data;
  468. const struct avrcp_browsing_handler *handler;
  469. struct avrcp_browsing_header *pdu;
  470. int ret;
  471. pdu = parse_browsing_pdu(operands, operand_count);
  472. if (!pdu) {
  473. pdu = (void *) operands;
  474. pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
  475. goto reject;
  476. }
  477. DBG("AVRCP Browsing PDU 0x%02X, len 0x%04X", pdu->pdu_id,
  478. pdu->params_len);
  479. if (!session->browsing_handlers) {
  480. pdu->pdu_id = AVRCP_GENERAL_REJECT;
  481. pdu->params[0] = AVRCP_STATUS_INTERNAL_ERROR;
  482. goto reject;
  483. }
  484. for (handler = session->browsing_handlers; handler->id; handler++) {
  485. if (handler->id == pdu->pdu_id)
  486. break;
  487. }
  488. if (handler->id != pdu->pdu_id) {
  489. pdu->pdu_id = AVRCP_GENERAL_REJECT;
  490. pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
  491. goto reject;
  492. }
  493. if (!handler->func) {
  494. pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
  495. goto reject;
  496. }
  497. ret = handler->func(session, transaction, pdu->params_len, pdu->params,
  498. session->control_data);
  499. if (ret == 0)
  500. return -EAGAIN;
  501. if (ret < 0) {
  502. if (ret == -EAGAIN)
  503. return ret;
  504. pdu->params[0] = errno2status(ret);
  505. goto reject;
  506. }
  507. pdu->params_len = htons(ret);
  508. return AVRCP_BROWSING_HEADER_LENGTH + ret;
  509. reject:
  510. pdu->params_len = htons(1);
  511. return AVRCP_BROWSING_HEADER_LENGTH + 1;
  512. }
  513. static void browsing_disconnect_cb(void *data)
  514. {
  515. struct avrcp *session = data;
  516. session->browsing_id = 0;
  517. }
  518. int avrcp_connect_browsing(struct avrcp *session, int fd, size_t imtu,
  519. size_t omtu)
  520. {
  521. int err;
  522. err = avctp_connect_browsing(session->conn, fd, imtu, omtu);
  523. if (err < 0)
  524. return err;
  525. session->browsing_id = avctp_register_browsing_pdu_handler(
  526. session->conn,
  527. handle_browsing_pdu,
  528. session,
  529. browsing_disconnect_cb);
  530. return 0;
  531. }
  532. void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb,
  533. void *user_data)
  534. {
  535. session->destroy = cb;
  536. session->destroy_data = user_data;
  537. }
  538. static ssize_t get_capabilities(struct avrcp *session, uint8_t transaction,
  539. uint16_t params_len, uint8_t *params,
  540. void *user_data)
  541. {
  542. struct avrcp_player *player = user_data;
  543. struct get_capabilities_req *req;
  544. if (!params || params_len != sizeof(*req))
  545. return -EINVAL;
  546. req = (void *) params;
  547. switch (req->cap) {
  548. case CAP_COMPANY_ID:
  549. req->params[0] = 1;
  550. hton24(&req->params[1], IEEEID_BTSIG);
  551. return 5;
  552. case CAP_EVENTS_SUPPORTED:
  553. if (!player->ind || !player->ind->get_capabilities)
  554. return -ENOSYS;
  555. return player->ind->get_capabilities(session, transaction,
  556. player->user_data);
  557. }
  558. return -EINVAL;
  559. }
  560. static ssize_t list_attributes(struct avrcp *session, uint8_t transaction,
  561. uint16_t params_len, uint8_t *params,
  562. void *user_data)
  563. {
  564. struct avrcp_player *player = user_data;
  565. DBG("");
  566. if (!player->ind || !player->ind->list_attributes)
  567. return -ENOSYS;
  568. return player->ind->list_attributes(session, transaction,
  569. player->user_data);
  570. }
  571. static bool check_attributes(uint8_t number, const uint8_t *attrs)
  572. {
  573. int i;
  574. for (i = 0; i < number; i++) {
  575. if (attrs[i] > AVRCP_ATTRIBUTE_LAST ||
  576. attrs[i] == AVRCP_ATTRIBUTE_ILEGAL)
  577. return false;
  578. }
  579. return true;
  580. }
  581. static ssize_t get_attribute_text(struct avrcp *session, uint8_t transaction,
  582. uint16_t params_len, uint8_t *params,
  583. void *user_data)
  584. {
  585. struct avrcp_player *player = user_data;
  586. struct get_attribute_text_req *req;
  587. DBG("");
  588. if (!player->ind || !player->ind->get_attribute_text)
  589. return -ENOSYS;
  590. if (!params || params_len < sizeof(*req))
  591. return -EINVAL;
  592. req = (void *) params;
  593. if (params_len != sizeof(*req) + req->number)
  594. return -EINVAL;
  595. if (!check_attributes(req->number, req->attrs))
  596. return -EINVAL;
  597. return player->ind->get_attribute_text(session, transaction,
  598. req->number, req->attrs,
  599. player->user_data);
  600. }
  601. static ssize_t list_values(struct avrcp *session, uint8_t transaction,
  602. uint16_t params_len, uint8_t *params,
  603. void *user_data)
  604. {
  605. struct avrcp_player *player = user_data;
  606. struct list_values_req *req;
  607. DBG("");
  608. if (!params || params_len != sizeof(*req))
  609. return -EINVAL;
  610. req = (void *) params;
  611. if (req->attr > AVRCP_ATTRIBUTE_LAST ||
  612. req->attr == AVRCP_ATTRIBUTE_ILEGAL)
  613. return -EINVAL;
  614. if (!player->ind || !player->ind->list_values)
  615. return -ENOSYS;
  616. return player->ind->list_values(session, transaction, req->attr,
  617. player->user_data);
  618. }
  619. static bool check_value(uint8_t attr, uint8_t number, const uint8_t *values)
  620. {
  621. int i;
  622. for (i = 0; i < number; i++) {
  623. /* Check for invalid value */
  624. switch (attr) {
  625. case AVRCP_ATTRIBUTE_EQUALIZER:
  626. if (values[i] < AVRCP_EQUALIZER_OFF ||
  627. values[i] > AVRCP_EQUALIZER_ON)
  628. return false;
  629. break;
  630. case AVRCP_ATTRIBUTE_REPEAT_MODE:
  631. if (values[i] < AVRCP_REPEAT_MODE_OFF ||
  632. values[i] > AVRCP_REPEAT_MODE_GROUP)
  633. return false;
  634. break;
  635. case AVRCP_ATTRIBUTE_SHUFFLE:
  636. if (values[i] < AVRCP_SHUFFLE_OFF ||
  637. values[i] > AVRCP_SHUFFLE_GROUP)
  638. return false;
  639. break;
  640. case AVRCP_ATTRIBUTE_SCAN:
  641. if (values[i] < AVRCP_SCAN_OFF ||
  642. values[i] > AVRCP_SCAN_GROUP)
  643. return false;
  644. break;
  645. }
  646. }
  647. return true;
  648. }
  649. static ssize_t get_value_text(struct avrcp *session, uint8_t transaction,
  650. uint16_t params_len, uint8_t *params,
  651. void *user_data)
  652. {
  653. struct avrcp_player *player = user_data;
  654. struct get_value_text_req *req;
  655. DBG("");
  656. if (!player->ind || !player->ind->get_value_text)
  657. return -ENOSYS;
  658. if (!params || params_len < sizeof(*req))
  659. return -EINVAL;
  660. req = (void *) params;
  661. if (params_len != sizeof(*req) + req->number)
  662. return -EINVAL;
  663. if (req->number > AVRCP_ATTRIBUTE_LAST ||
  664. req->number == AVRCP_ATTRIBUTE_ILEGAL)
  665. return -EINVAL;
  666. if (!check_value(req->attr, req->number, req->values))
  667. return -EINVAL;
  668. return player->ind->get_value_text(session, transaction, params[0],
  669. params[1], &params[2],
  670. player->user_data);
  671. }
  672. static ssize_t get_value(struct avrcp *session, uint8_t transaction,
  673. uint16_t params_len, uint8_t *params,
  674. void *user_data)
  675. {
  676. struct avrcp_player *player = user_data;
  677. struct get_value_req *req;
  678. DBG("");
  679. if (!player->ind || !player->ind->get_value)
  680. return -ENOSYS;
  681. if (!params || params_len < sizeof(*req))
  682. return -EINVAL;
  683. req = (void *) params;
  684. if (params_len < sizeof(*req) + req->number)
  685. return -EINVAL;
  686. if (!check_attributes(req->number, req->attrs))
  687. return -EINVAL;
  688. return player->ind->get_value(session, transaction, params[0],
  689. &params[1], player->user_data);
  690. }
  691. static ssize_t set_value(struct avrcp *session, uint8_t transaction,
  692. uint16_t params_len, uint8_t *params,
  693. void *user_data)
  694. {
  695. struct avrcp_player *player = user_data;
  696. struct set_value_req *req;
  697. uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
  698. uint8_t values[AVRCP_ATTRIBUTE_LAST];
  699. int i;
  700. DBG("");
  701. if (!player->ind || !player->ind->set_value)
  702. return -ENOSYS;
  703. if (!params || params_len < sizeof(*req))
  704. return -EINVAL;
  705. req = (void *) params;
  706. if (params_len < sizeof(*req) + req->number * sizeof(*req->values))
  707. return -EINVAL;
  708. for (i = 0; i < req->number; i++) {
  709. attrs[i] = req->values[i].attr;
  710. values[i] = req->values[i].value;
  711. if (!check_value(attrs[i], 1, &values[i]))
  712. return -EINVAL;
  713. }
  714. return player->ind->set_value(session, transaction, req->number,
  715. attrs, values, player->user_data);
  716. }
  717. static ssize_t get_play_status(struct avrcp *session, uint8_t transaction,
  718. uint16_t params_len, uint8_t *params,
  719. void *user_data)
  720. {
  721. struct avrcp_player *player = user_data;
  722. DBG("");
  723. if (!player->ind || !player->ind->get_play_status)
  724. return -ENOSYS;
  725. return player->ind->get_play_status(session, transaction,
  726. player->user_data);
  727. }
  728. static bool parse_attributes(struct get_element_attributes_req *req,
  729. uint16_t params_len, uint8_t number,
  730. uint32_t *attrs)
  731. {
  732. int i;
  733. for (i = 0; i < number && params_len >= sizeof(*attrs); i++,
  734. params_len -= sizeof(*attrs)) {
  735. attrs[i] = be32_to_cpu(req->attrs[i]);
  736. if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
  737. attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
  738. return false;
  739. }
  740. return true;
  741. }
  742. static ssize_t get_element_attributes(struct avrcp *session,
  743. uint8_t transaction,
  744. uint16_t params_len,
  745. uint8_t *params,
  746. void *user_data)
  747. {
  748. struct avrcp_player *player = user_data;
  749. struct get_element_attributes_req *req;
  750. uint64_t uid;
  751. uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST];
  752. DBG("");
  753. if (!player->ind || !player->ind->get_element_attributes)
  754. return -ENOSYS;
  755. req = (void *) params;
  756. if (!params || params_len < sizeof(*req))
  757. return -EINVAL;
  758. if (!parse_attributes(req, params_len - sizeof(*req),
  759. req->number, attrs))
  760. return -EINVAL;
  761. uid = get_be64(params);
  762. return player->ind->get_element_attributes(session, transaction, uid,
  763. req->number, attrs,
  764. player->user_data);
  765. }
  766. static ssize_t register_notification(struct avrcp *session, uint8_t transaction,
  767. uint16_t params_len, uint8_t *params,
  768. void *user_data)
  769. {
  770. struct avrcp_player *player = user_data;
  771. struct register_notification_req *req;
  772. uint32_t interval;
  773. DBG("");
  774. if (!player->ind || !player->ind->register_notification)
  775. return -ENOSYS;
  776. if (!params || params_len != sizeof(*req))
  777. return -EINVAL;
  778. req = (void *) params;
  779. interval = be32_to_cpu(req->interval);
  780. return player->ind->register_notification(session, transaction,
  781. req->event, interval,
  782. player->user_data);
  783. }
  784. static ssize_t set_volume(struct avrcp *session, uint8_t transaction,
  785. uint16_t params_len, uint8_t *params,
  786. void *user_data)
  787. {
  788. struct avrcp_player *player = user_data;
  789. struct set_volume_req *req;
  790. uint8_t volume;
  791. DBG("");
  792. if (!player->ind || !player->ind->set_volume)
  793. return -ENOSYS;
  794. if (!params || params_len != sizeof(volume))
  795. return -EINVAL;
  796. req = (void *) params;
  797. volume = req->value & 0x7f;
  798. return player->ind->set_volume(session, transaction, volume,
  799. player->user_data);
  800. }
  801. static ssize_t set_addressed(struct avrcp *session, uint8_t transaction,
  802. uint16_t params_len, uint8_t *params,
  803. void *user_data)
  804. {
  805. struct avrcp_player *player = user_data;
  806. struct set_addressed_req *req;
  807. uint16_t id;
  808. DBG("");
  809. if (!player->ind || !player->ind->set_addressed)
  810. return -ENOSYS;
  811. if (!params || params_len != sizeof(*req))
  812. return -EINVAL;
  813. req = (void *) params;
  814. id = be16_to_cpu(req->id);
  815. return player->ind->set_addressed(session, transaction, id,
  816. player->user_data);
  817. }
  818. static void continuing_new(struct avrcp *session, uint8_t pdu_id,
  819. const struct iovec *iov, int iov_cnt,
  820. size_t offset)
  821. {
  822. struct avrcp_continuing *continuing;
  823. int i;
  824. size_t len = 0;
  825. continuing = g_new0(struct avrcp_continuing, 1);
  826. continuing->pdu_id = pdu_id;
  827. for (i = 0; i < iov_cnt; i++) {
  828. if (i == 0 && offset) {
  829. len += iov[i].iov_len - offset;
  830. continue;
  831. }
  832. len += iov[i].iov_len;
  833. }
  834. continuing->pdu.iov_base = g_malloc0(len);
  835. DBG("len %zu", len);
  836. for (i = 0; i < iov_cnt; i++) {
  837. if (i == 0 && offset) {
  838. memcpy(continuing->pdu.iov_base,
  839. iov[i].iov_base + offset,
  840. iov[i].iov_len - offset);
  841. continuing->pdu.iov_len += iov[i].iov_len - offset;
  842. continue;
  843. }
  844. memcpy(continuing->pdu.iov_base + continuing->pdu.iov_len,
  845. iov[i].iov_base, iov[i].iov_len);
  846. continuing->pdu.iov_len += iov[i].iov_len;
  847. }
  848. session->continuing = continuing;
  849. }
  850. static int avrcp_send_internal(struct avrcp *session, uint8_t transaction,
  851. uint8_t code, uint8_t subunit,
  852. uint8_t pdu_id, uint8_t type,
  853. const struct iovec *iov, int iov_cnt)
  854. {
  855. struct iovec pdu[iov_cnt + 1];
  856. struct avrcp_header hdr;
  857. int i;
  858. /*
  859. * If a receiver receives a start fragment or non-fragmented AVRCP
  860. * Specific AV/C message when it already has an incomplete fragment
  861. * from that sender then the receiver shall consider the first PDU
  862. * aborted.
  863. */
  864. if (session->continuing) {
  865. continuing_free(session->continuing);
  866. session->continuing = NULL;
  867. }
  868. memset(&hdr, 0, sizeof(hdr));
  869. pdu[0].iov_base = &hdr;
  870. pdu[0].iov_len = sizeof(hdr);
  871. hdr.packet_type = type;
  872. for (i = 0; i < iov_cnt; i++) {
  873. pdu[i + 1].iov_base = iov[i].iov_base;
  874. if (pdu[0].iov_len + hdr.params_len + iov[i].iov_len <=
  875. session->control_mtu) {
  876. pdu[i + 1].iov_len = iov[i].iov_len;
  877. hdr.params_len += iov[i].iov_len;
  878. if (hdr.packet_type != AVRCP_PACKET_TYPE_SINGLE)
  879. hdr.packet_type = AVRCP_PACKET_TYPE_END;
  880. continue;
  881. }
  882. /*
  883. * Only send what can fit and store the remaining in the
  884. * continuing iovec
  885. */
  886. pdu[i + 1].iov_len = session->control_mtu -
  887. (pdu[0].iov_len + hdr.params_len);
  888. hdr.params_len += pdu[i + 1].iov_len;
  889. continuing_new(session, pdu_id, &iov[i], iov_cnt - i,
  890. pdu[i + 1].iov_len);
  891. hdr.packet_type = hdr.packet_type != AVRCP_PACKET_TYPE_SINGLE ?
  892. AVRCP_PACKET_TYPE_CONTINUING :
  893. AVRCP_PACKET_TYPE_START;
  894. break;
  895. }
  896. hton24(hdr.company_id, IEEEID_BTSIG);
  897. hdr.pdu_id = pdu_id;
  898. hdr.params_len = htons(hdr.params_len);
  899. return avctp_send_vendor(session->conn, transaction, code, subunit,
  900. pdu, iov_cnt + 1);
  901. }
  902. static ssize_t request_continuing(struct avrcp *session, uint8_t transaction,
  903. uint16_t params_len, uint8_t *params,
  904. void *user_data)
  905. {
  906. struct iovec iov;
  907. int err;
  908. DBG("");
  909. if (!params || params_len != 1 || !session->continuing ||
  910. session->continuing->pdu_id != params[0])
  911. return -EINVAL;
  912. iov.iov_base = session->continuing->pdu.iov_base;
  913. iov.iov_len = session->continuing->pdu.iov_len;
  914. DBG("len %zu", iov.iov_len);
  915. session->continuing->pdu.iov_base = NULL;
  916. err = avrcp_send_internal(session, transaction, AVC_CTYPE_STABLE,
  917. AVC_SUBUNIT_PANEL, params[0],
  918. AVRCP_PACKET_TYPE_CONTINUING, &iov, 1);
  919. g_free(iov.iov_base);
  920. if (err < 0)
  921. return -EINVAL;
  922. return 0;
  923. }
  924. static ssize_t abort_continuing(struct avrcp *session, uint8_t transaction,
  925. uint16_t params_len, uint8_t *params,
  926. void *user_data)
  927. {
  928. DBG("");
  929. if (!params || params_len != 1 || !session->continuing)
  930. return -EINVAL;
  931. continuing_free(session->continuing);
  932. session->continuing = NULL;
  933. avrcp_send_internal(session, transaction, AVC_CTYPE_ACCEPTED,
  934. AVC_SUBUNIT_PANEL, AVRCP_ABORT_CONTINUING,
  935. AVRCP_PACKET_TYPE_SINGLE, NULL, 0);
  936. return 0;
  937. }
  938. static const struct avrcp_control_handler player_handlers[] = {
  939. { AVRCP_GET_CAPABILITIES,
  940. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  941. get_capabilities },
  942. { AVRCP_LIST_PLAYER_ATTRIBUTES,
  943. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  944. list_attributes },
  945. { AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
  946. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  947. get_attribute_text },
  948. { AVRCP_LIST_PLAYER_VALUES,
  949. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  950. list_values },
  951. { AVRCP_GET_PLAYER_VALUE_TEXT,
  952. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  953. get_value_text },
  954. { AVRCP_GET_CURRENT_PLAYER_VALUE,
  955. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  956. get_value },
  957. { AVRCP_SET_PLAYER_VALUE,
  958. AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE,
  959. set_value },
  960. { AVRCP_GET_PLAY_STATUS,
  961. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  962. get_play_status },
  963. { AVRCP_GET_ELEMENT_ATTRIBUTES,
  964. AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
  965. get_element_attributes },
  966. { AVRCP_REGISTER_NOTIFICATION,
  967. AVC_CTYPE_NOTIFY, AVC_CTYPE_INTERIM,
  968. register_notification },
  969. { AVRCP_SET_ABSOLUTE_VOLUME,
  970. AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE,
  971. set_volume },
  972. { AVRCP_SET_ADDRESSED_PLAYER,
  973. AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE,
  974. set_addressed },
  975. { AVRCP_REQUEST_CONTINUING,
  976. AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE,
  977. request_continuing },
  978. { AVRCP_ABORT_CONTINUING,
  979. AVC_CTYPE_CONTROL, AVC_CTYPE_ACCEPTED,
  980. abort_continuing },
  981. { },
  982. };
  983. static void avrcp_set_control_handlers(struct avrcp *session,
  984. const struct avrcp_control_handler *handlers,
  985. void *user_data)
  986. {
  987. session->control_handlers = handlers;
  988. session->control_data = user_data;
  989. }
  990. static ssize_t set_browsed(struct avrcp *session, uint8_t transaction,
  991. uint16_t params_len, uint8_t *params,
  992. void *user_data)
  993. {
  994. struct avrcp_player *player = user_data;
  995. struct set_browsed_req *req;
  996. uint16_t id;
  997. DBG("");
  998. if (!player->ind || !player->ind->set_browsed)
  999. return -ENOSYS;
  1000. if (!params || params_len != sizeof(*req))
  1001. return -EINVAL;
  1002. req = (void *) params;
  1003. id = be16_to_cpu(req->id);
  1004. return player->ind->set_browsed(session, transaction, id,
  1005. player->user_data);
  1006. }
  1007. static ssize_t get_folder_items(struct avrcp *session, uint8_t transaction,
  1008. uint16_t params_len, uint8_t *params,
  1009. void *user_data)
  1010. {
  1011. struct avrcp_player *player = user_data;
  1012. struct get_folder_items_req *req;
  1013. uint32_t start, end;
  1014. uint16_t number;
  1015. uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST];
  1016. int i;
  1017. DBG("");
  1018. if (!player->ind || !player->ind->get_folder_items)
  1019. return -ENOSYS;
  1020. if (!params || params_len < sizeof(*req))
  1021. return -EINVAL;
  1022. req = (void *) params;
  1023. if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
  1024. return -EBADRQC;
  1025. start = be32_to_cpu(req->start);
  1026. end = be32_to_cpu(req->end);
  1027. if (start > end)
  1028. return -ERANGE;
  1029. number = be16_to_cpu(req->number);
  1030. for (i = 0; i < number; i++) {
  1031. attrs[i] = be32_to_cpu(req->attrs[i]);
  1032. if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
  1033. attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
  1034. return -EINVAL;
  1035. }
  1036. return player->ind->get_folder_items(session, transaction, req->scope,
  1037. start, end, number, attrs,
  1038. player->user_data);
  1039. }
  1040. static ssize_t change_path(struct avrcp *session, uint8_t transaction,
  1041. uint16_t params_len, uint8_t *params,
  1042. void *user_data)
  1043. {
  1044. struct avrcp_player *player = user_data;
  1045. struct change_path_req *req;
  1046. uint16_t counter;
  1047. uint64_t uid;
  1048. DBG("");
  1049. if (!player->ind || !player->ind->change_path)
  1050. return -ENOSYS;
  1051. if (!params || params_len < sizeof(*req))
  1052. return -EINVAL;
  1053. req = (void *) params;
  1054. counter = be16_to_cpu(req->counter);
  1055. uid = be64_to_cpu(req->uid);
  1056. return player->ind->change_path(session, transaction, counter,
  1057. req->direction, uid, player->user_data);
  1058. }
  1059. static ssize_t get_item_attributes(struct avrcp *session, uint8_t transaction,
  1060. uint16_t params_len, uint8_t *params,
  1061. void *user_data)
  1062. {
  1063. struct avrcp_player *player = user_data;
  1064. struct get_item_attributes_req *req;
  1065. uint64_t uid;
  1066. uint16_t counter;
  1067. uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST];
  1068. int i;
  1069. DBG("");
  1070. if (!player->ind || !player->ind->get_item_attributes)
  1071. return -ENOSYS;
  1072. if (!params || params_len < sizeof(*req))
  1073. return -EINVAL;
  1074. req = (void *) params;
  1075. if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
  1076. return -EBADRQC;
  1077. uid = be64_to_cpu(req->uid);
  1078. counter = be16_to_cpu(req->counter);
  1079. for (i = 0; i < req->number; i++) {
  1080. attrs[i] = be32_to_cpu(req->attrs[i]);
  1081. if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
  1082. attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
  1083. return -EINVAL;
  1084. }
  1085. return player->ind->get_item_attributes(session, transaction,
  1086. req->scope, uid, counter,
  1087. req->number, attrs,
  1088. player->user_data);
  1089. }
  1090. static ssize_t play_item(struct avrcp *session, uint8_t transaction,
  1091. uint16_t params_len, uint8_t *params,
  1092. void *user_data)
  1093. {
  1094. struct avrcp_player *player = user_data;
  1095. struct play_item_req *req;
  1096. uint64_t uid;
  1097. uint16_t counter;
  1098. DBG("");
  1099. if (!player->ind || !player->ind->play_item)
  1100. return -ENOSYS;
  1101. if (!params || params_len < sizeof(*req))
  1102. return -EINVAL;
  1103. req = (void *) params;
  1104. if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
  1105. return -EBADRQC;
  1106. uid = be64_to_cpu(req->uid);
  1107. counter = be16_to_cpu(req->counter);
  1108. return player->ind->play_item(session, transaction, req->scope, uid,
  1109. counter, player->user_data);
  1110. }
  1111. static ssize_t search(struct avrcp *session, uint8_t transaction,
  1112. uint16_t params_len, uint8_t *params,
  1113. void *user_data)
  1114. {
  1115. struct avrcp_player *player = user_data;
  1116. struct search_req *req;
  1117. char *string;
  1118. uint16_t len;
  1119. int ret;
  1120. DBG("");
  1121. if (!player->ind || !player->ind->search)
  1122. return -ENOSYS;
  1123. if (!params || params_len < sizeof(*req))
  1124. return -EINVAL;
  1125. req = (void *) params;
  1126. len = be16_to_cpu(req->len);
  1127. if (!len)
  1128. return -EINVAL;
  1129. string = strndup(req->string, len);
  1130. ret = player->ind->search(session, transaction, string,
  1131. player->user_data);
  1132. free(string);
  1133. return ret;
  1134. }
  1135. static ssize_t add_to_now_playing(struct avrcp *session, uint8_t transaction,
  1136. uint16_t params_len, uint8_t *params,
  1137. void *user_data)
  1138. {
  1139. struct avrcp_player *player = user_data;
  1140. struct add_to_now_playing_req *req;
  1141. uint64_t uid;
  1142. uint16_t counter;
  1143. DBG("");
  1144. if (!player->ind || !player->ind->add_to_now_playing)
  1145. return -ENOSYS;
  1146. if (!params || params_len < sizeof(*req))
  1147. return -EINVAL;
  1148. req = (void *) params;
  1149. if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
  1150. return -EBADRQC;
  1151. uid = be64_to_cpu(req->uid);
  1152. counter = be16_to_cpu(req->counter);
  1153. return player->ind->add_to_now_playing(session, transaction, req->scope,
  1154. uid, counter,
  1155. player->user_data);
  1156. }
  1157. static const struct avrcp_browsing_handler browsing_handlers[] = {
  1158. { AVRCP_SET_BROWSED_PLAYER, set_browsed },
  1159. { AVRCP_GET_FOLDER_ITEMS, get_folder_items },
  1160. { AVRCP_CHANGE_PATH, change_path },
  1161. { AVRCP_GET_ITEM_ATTRIBUTES, get_item_attributes },
  1162. { AVRCP_PLAY_ITEM, play_item },
  1163. { AVRCP_SEARCH, search },
  1164. { AVRCP_ADD_TO_NOW_PLAYING, add_to_now_playing },
  1165. { },
  1166. };
  1167. static void avrcp_set_browsing_handlers(struct avrcp *session,
  1168. const struct avrcp_browsing_handler *handlers,
  1169. void *user_data)
  1170. {
  1171. session->browsing_handlers = handlers;
  1172. session->browsing_data = user_data;
  1173. }
  1174. void avrcp_register_player(struct avrcp *session,
  1175. const struct avrcp_control_ind *ind,
  1176. const struct avrcp_control_cfm *cfm,
  1177. void *user_data)
  1178. {
  1179. struct avrcp_player *player;
  1180. player = g_new0(struct avrcp_player, 1);
  1181. player->ind = ind;
  1182. player->cfm = cfm;
  1183. player->user_data = user_data;
  1184. avrcp_set_control_handlers(session, player_handlers, player);
  1185. avrcp_set_browsing_handlers(session, browsing_handlers, player);
  1186. session->player = player;
  1187. }
  1188. void avrcp_set_passthrough_handlers(struct avrcp *session,
  1189. const struct avrcp_passthrough_handler *handlers,
  1190. void *user_data)
  1191. {
  1192. session->passthrough_handlers = handlers;
  1193. session->passthrough_data = user_data;
  1194. }
  1195. int avrcp_init_uinput(struct avrcp *session, const char *name,
  1196. const char *address)
  1197. {
  1198. return avctp_init_uinput(session->conn, name, address);
  1199. }
  1200. int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
  1201. uint8_t subunit, uint8_t pdu_id,
  1202. const struct iovec *iov, int iov_cnt)
  1203. {
  1204. return avrcp_send_internal(session, transaction, code, subunit, pdu_id,
  1205. AVRCP_PACKET_TYPE_SINGLE, iov, iov_cnt);
  1206. }
  1207. static int status2errno(uint8_t status)
  1208. {
  1209. switch (status) {
  1210. case AVRCP_STATUS_INVALID_COMMAND:
  1211. return -ENOSYS;
  1212. case AVRCP_STATUS_INVALID_PARAM:
  1213. return -EINVAL;
  1214. case AVRCP_STATUS_SUCCESS:
  1215. return 0;
  1216. case AVRCP_STATUS_NOT_DIRECTORY:
  1217. return -ENOTDIR;
  1218. case AVRCP_STATUS_INVALID_SCOPE:
  1219. return -EBADRQC;
  1220. case AVRCP_STATUS_OUT_OF_BOUNDS:
  1221. return -ERANGE;
  1222. case AVRCP_STATUS_INTERNAL_ERROR:
  1223. case AVRCP_STATUS_INVALID_PLAYER_ID:
  1224. case AVRCP_STATUS_PLAYER_NOT_BROWSABLE:
  1225. case AVRCP_STATUS_NO_AVAILABLE_PLAYERS:
  1226. case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED:
  1227. return -EPERM;
  1228. default:
  1229. return -EPROTO;
  1230. }
  1231. }
  1232. static int parse_status(struct avrcp_header *pdu)
  1233. {
  1234. if (pdu->params_len < 1)
  1235. return -EPROTO;
  1236. return status2errno(pdu->params[0]);
  1237. }
  1238. static int parse_browsing_status(struct avrcp_browsing_header *pdu)
  1239. {
  1240. if (pdu->params_len < 1)
  1241. return -EPROTO;
  1242. return status2errno(pdu->params[0]);
  1243. }
  1244. static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit,
  1245. uint8_t pdu_id, const struct iovec *iov,
  1246. int iov_cnt, avctp_rsp_cb func,
  1247. void *user_data)
  1248. {
  1249. struct iovec pdu[iov_cnt + 1];
  1250. struct avrcp_header hdr;
  1251. int i;
  1252. memset(&hdr, 0, sizeof(hdr));
  1253. pdu[0].iov_base = &hdr;
  1254. pdu[0].iov_len = sizeof(hdr);
  1255. for (i = 0; i < iov_cnt; i++) {
  1256. pdu[i + 1].iov_base = iov[i].iov_base;
  1257. pdu[i + 1].iov_len = iov[i].iov_len;
  1258. hdr.params_len += iov[i].iov_len;
  1259. }
  1260. hton24(hdr.company_id, IEEEID_BTSIG);
  1261. hdr.pdu_id = pdu_id;
  1262. hdr.packet_type = AVRCP_PACKET_TYPE_SINGLE;
  1263. hdr.params_len = htons(hdr.params_len);
  1264. return avctp_send_vendor_req(session->conn, code, subunit, pdu,
  1265. iov_cnt + 1, func, user_data);
  1266. }
  1267. static int avrcp_send_browsing_req(struct avrcp *session, uint8_t pdu_id,
  1268. const struct iovec *iov, int iov_cnt,
  1269. avctp_browsing_rsp_cb func,
  1270. void *user_data)
  1271. {
  1272. struct iovec pdu[iov_cnt + 1];
  1273. struct avrcp_browsing_header hdr;
  1274. int i;
  1275. memset(&hdr, 0, sizeof(hdr));
  1276. for (i = 0; i < iov_cnt; i++) {
  1277. pdu[i + 1].iov_base = iov[i].iov_base;
  1278. pdu[i + 1].iov_len = iov[i].iov_len;
  1279. hdr.params_len += iov[i].iov_len;
  1280. }
  1281. hdr.pdu_id = pdu_id;
  1282. hdr.params_len = htons(hdr.params_len);
  1283. pdu[0].iov_base = &hdr;
  1284. pdu[0].iov_len = sizeof(hdr);
  1285. return avctp_send_browsing_req(session->conn, pdu, iov_cnt + 1,
  1286. func, user_data);
  1287. }
  1288. static int avrcp_send_browsing(struct avrcp *session, uint8_t transaction,
  1289. uint8_t pdu_id, const struct iovec *iov,
  1290. int iov_cnt)
  1291. {
  1292. struct iovec pdu[iov_cnt + 1];
  1293. struct avrcp_browsing_header hdr;
  1294. int i;
  1295. memset(&hdr, 0, sizeof(hdr));
  1296. for (i = 0; i < iov_cnt; i++) {
  1297. pdu[i + 1].iov_base = iov[i].iov_base;
  1298. pdu[i + 1].iov_len = iov[i].iov_len;
  1299. hdr.params_len += iov[i].iov_len;
  1300. }
  1301. hdr.pdu_id = pdu_id;
  1302. hdr.params_len = htons(hdr.params_len);
  1303. pdu[0].iov_base = &hdr;
  1304. pdu[0].iov_len = sizeof(hdr);
  1305. return avctp_send_browsing(session->conn, transaction, pdu,
  1306. iov_cnt + 1);
  1307. }
  1308. static gboolean get_capabilities_rsp(struct avctp *conn,
  1309. uint8_t code, uint8_t subunit,
  1310. uint8_t *operands, size_t operand_count,
  1311. void *user_data)
  1312. {
  1313. struct avrcp *session = user_data;
  1314. struct avrcp_player *player = session->player;
  1315. struct avrcp_header *pdu;
  1316. struct get_capabilities_rsp *rsp;
  1317. uint8_t number = 0;
  1318. uint8_t *params = NULL;
  1319. int err;
  1320. DBG("");
  1321. if (!player || !player->cfm || !player->cfm->get_capabilities)
  1322. return FALSE;
  1323. pdu = parse_pdu(operands, operand_count);
  1324. if (!pdu) {
  1325. err = -EPROTO;
  1326. goto done;
  1327. }
  1328. if (code == AVC_CTYPE_REJECTED) {
  1329. err = parse_status(pdu);
  1330. goto done;
  1331. }
  1332. if (pdu->params_len < sizeof(*rsp)) {
  1333. err = -EPROTO;
  1334. goto done;
  1335. }
  1336. rsp = (void *) pdu->params;
  1337. switch (rsp->cap) {
  1338. case CAP_COMPANY_ID:
  1339. case CAP_EVENTS_SUPPORTED:
  1340. break;
  1341. default:
  1342. err = -EPROTO;
  1343. goto done;
  1344. }
  1345. if (rsp->number > 0) {
  1346. number = rsp->number;
  1347. params = rsp->params;
  1348. }
  1349. err = 0;
  1350. done:
  1351. player->cfm->get_capabilities(session, err, number, params,
  1352. player->user_data);
  1353. return FALSE;
  1354. }
  1355. int avrcp_get_capabilities(struct avrcp *session, uint8_t param)
  1356. {
  1357. struct iovec iov;
  1358. struct get_capabilities_req req;
  1359. req.cap = param;
  1360. iov.iov_base = &req;
  1361. iov.iov_len = sizeof(req);
  1362. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1363. AVRCP_GET_CAPABILITIES, &iov, 1,
  1364. get_capabilities_rsp, session);
  1365. }
  1366. static gboolean register_notification_rsp(struct avctp *conn,
  1367. uint8_t code, uint8_t subunit,
  1368. uint8_t *operands, size_t operand_count,
  1369. void *user_data)
  1370. {
  1371. struct avrcp *session = user_data;
  1372. struct avrcp_player *player = session->player;
  1373. struct avrcp_header *pdu;
  1374. struct register_notification_rsp *rsp;
  1375. uint8_t event = 0;
  1376. uint16_t value16, value16_2[2];
  1377. uint32_t value32;
  1378. uint64_t value64;
  1379. uint8_t *params = NULL;
  1380. int err;
  1381. DBG("");
  1382. if (!player || !player->cfm || !player->cfm->register_notification)
  1383. return FALSE;
  1384. pdu = parse_pdu(operands, operand_count);
  1385. if (!pdu) {
  1386. err = -EPROTO;
  1387. goto done;
  1388. }
  1389. if (code == AVC_CTYPE_REJECTED) {
  1390. err = parse_status(pdu);
  1391. goto done;
  1392. }
  1393. if (pdu->params_len < sizeof(*rsp)) {
  1394. err = -EPROTO;
  1395. goto done;
  1396. }
  1397. rsp = (void *) pdu->params;
  1398. event = rsp->event;
  1399. if (event > AVRCP_EVENT_LAST) {
  1400. err = -EPROTO;
  1401. goto done;
  1402. }
  1403. switch (event) {
  1404. case AVRCP_EVENT_STATUS_CHANGED:
  1405. if (pdu->params_len != sizeof(*rsp) + sizeof(uint8_t)) {
  1406. err = -EPROTO;
  1407. goto done;
  1408. }
  1409. params = rsp->data;
  1410. break;
  1411. case AVRCP_EVENT_VOLUME_CHANGED:
  1412. if (pdu->params_len != sizeof(*rsp) + sizeof(uint8_t)) {
  1413. err = -EPROTO;
  1414. goto done;
  1415. }
  1416. params = rsp->data;
  1417. params[0] &= 0x7f;
  1418. break;
  1419. case AVRCP_EVENT_TRACK_CHANGED:
  1420. if (pdu->params_len != sizeof(*rsp) + sizeof(value64)) {
  1421. err = -EPROTO;
  1422. goto done;
  1423. }
  1424. value64 = get_be64(rsp->data);
  1425. params = (uint8_t *) &value64;
  1426. break;
  1427. case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
  1428. if (pdu->params_len != sizeof(*rsp) + sizeof(value32)) {
  1429. err = -EPROTO;
  1430. goto done;
  1431. }
  1432. value32 = get_be32(rsp->data);
  1433. params = (uint8_t *) &value32;
  1434. break;
  1435. case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
  1436. if (pdu->params_len < sizeof(*rsp) + sizeof(value16_2)) {
  1437. err = -EPROTO;
  1438. goto done;
  1439. }
  1440. value16_2[0] = get_be16(rsp->data);
  1441. value16_2[1] = get_be16(rsp->data + 2);
  1442. params = (uint8_t *) value16_2;
  1443. break;
  1444. case AVRCP_EVENT_SETTINGS_CHANGED:
  1445. if (pdu->params_len < sizeof(*rsp) + sizeof(uint8_t)) {
  1446. err = -EPROTO;
  1447. goto done;
  1448. }
  1449. params = rsp->data;
  1450. break;
  1451. case AVRCP_EVENT_UIDS_CHANGED:
  1452. if (pdu->params_len < sizeof(*rsp) + sizeof(value16)) {
  1453. err = -EPROTO;
  1454. goto done;
  1455. }
  1456. value16 = get_be16(rsp->data);
  1457. params = (uint8_t *) &value16;
  1458. break;
  1459. }
  1460. err = 0;
  1461. done:
  1462. return player->cfm->register_notification(session, err, code, event,
  1463. params, player->user_data);
  1464. }
  1465. int avrcp_register_notification(struct avrcp *session, uint8_t event,
  1466. uint32_t interval)
  1467. {
  1468. struct iovec iov;
  1469. struct register_notification_req req;
  1470. if (event > AVRCP_EVENT_LAST)
  1471. return -EINVAL;
  1472. req.event = event;
  1473. req.interval = cpu_to_be32(interval);
  1474. iov.iov_base = &req;
  1475. iov.iov_len = sizeof(req);
  1476. return avrcp_send_req(session, AVC_CTYPE_NOTIFY, AVC_SUBUNIT_PANEL,
  1477. AVRCP_REGISTER_NOTIFICATION, &iov, 1,
  1478. register_notification_rsp, session);
  1479. }
  1480. static gboolean list_attributes_rsp(struct avctp *conn,
  1481. uint8_t code, uint8_t subunit,
  1482. uint8_t *operands, size_t operand_count,
  1483. void *user_data)
  1484. {
  1485. struct avrcp *session = user_data;
  1486. struct avrcp_player *player = session->player;
  1487. struct avrcp_header *pdu = (void *) operands;
  1488. struct list_attributes_rsp *rsp;
  1489. uint8_t number = 0;
  1490. uint8_t *attrs = NULL;
  1491. int err;
  1492. DBG("");
  1493. if (!player || !player->cfm || !player->cfm->list_attributes)
  1494. return FALSE;
  1495. pdu = parse_pdu(operands, operand_count);
  1496. if (!pdu) {
  1497. err = -EPROTO;
  1498. goto done;
  1499. }
  1500. if (code == AVC_CTYPE_REJECTED) {
  1501. err = parse_status(pdu);
  1502. goto done;
  1503. }
  1504. rsp = (void *) pdu->params;
  1505. if (pdu->params_len < sizeof(*rsp)) {
  1506. err = -EPROTO;
  1507. goto done;
  1508. }
  1509. number = rsp->number;
  1510. if (number > 0)
  1511. attrs = rsp->params;
  1512. err = 0;
  1513. done:
  1514. player->cfm->list_attributes(session, err, number, attrs,
  1515. player->user_data);
  1516. return FALSE;
  1517. }
  1518. int avrcp_list_player_attributes(struct avrcp *session)
  1519. {
  1520. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1521. AVRCP_LIST_PLAYER_ATTRIBUTES, NULL, 0,
  1522. list_attributes_rsp, session);
  1523. }
  1524. static int parse_text_rsp(struct avrcp_header *pdu, uint8_t *number,
  1525. uint8_t *attrs, char **text)
  1526. {
  1527. uint8_t *ptr;
  1528. uint16_t params_len;
  1529. int i;
  1530. if (pdu->params_len < 1)
  1531. return -EPROTO;
  1532. *number = pdu->params[0];
  1533. if (*number > AVRCP_ATTRIBUTE_LAST) {
  1534. *number = 0;
  1535. return -EPROTO;
  1536. }
  1537. params_len = pdu->params_len - 1;
  1538. for (i = 0, ptr = &pdu->params[1]; i < *number && params_len > 0; i++) {
  1539. struct text_value *val;
  1540. if (params_len < sizeof(*val))
  1541. goto fail;
  1542. val = (void *) ptr;
  1543. attrs[i] = val->attr;
  1544. params_len -= sizeof(*val);
  1545. ptr += sizeof(*val);
  1546. if (val->len > params_len)
  1547. goto fail;
  1548. if (val->len > 0) {
  1549. text[i] = g_strndup(val->data, val->len);
  1550. params_len -= val->len;
  1551. ptr += val->len;
  1552. }
  1553. }
  1554. if (i != *number)
  1555. goto fail;
  1556. return 0;
  1557. fail:
  1558. for (i -= 1; i >= 0; i--)
  1559. g_free(text[i]);
  1560. *number = 0;
  1561. return -EPROTO;
  1562. }
  1563. static gboolean get_attribute_text_rsp(struct avctp *conn,
  1564. uint8_t code, uint8_t subunit,
  1565. uint8_t *operands, size_t operand_count,
  1566. void *user_data)
  1567. {
  1568. struct avrcp *session = user_data;
  1569. struct avrcp_player *player = session->player;
  1570. struct avrcp_header *pdu;
  1571. uint8_t number = 0;
  1572. uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
  1573. char *text[AVRCP_ATTRIBUTE_LAST];
  1574. int err;
  1575. DBG("");
  1576. if (!player || !player->cfm || !player->cfm->get_attribute_text)
  1577. return FALSE;
  1578. pdu = parse_pdu(operands, operand_count);
  1579. if (!pdu) {
  1580. err = -EPROTO;
  1581. goto done;
  1582. }
  1583. if (code == AVC_CTYPE_REJECTED) {
  1584. err = parse_status(pdu);
  1585. goto done;
  1586. }
  1587. err = parse_text_rsp(pdu, &number, attrs, text);
  1588. done:
  1589. player->cfm->get_attribute_text(session, err, number, attrs, text,
  1590. player->user_data);
  1591. return FALSE;
  1592. }
  1593. int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t number,
  1594. uint8_t *attrs)
  1595. {
  1596. struct iovec iov[2];
  1597. if (!number || number > AVRCP_ATTRIBUTE_LAST)
  1598. return -EINVAL;
  1599. iov[0].iov_base = &number;
  1600. iov[0].iov_len = sizeof(number);
  1601. iov[1].iov_base = attrs;
  1602. iov[1].iov_len = number;
  1603. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1604. AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, iov, 2,
  1605. get_attribute_text_rsp, session);
  1606. }
  1607. static gboolean list_values_rsp(struct avctp *conn,
  1608. uint8_t code, uint8_t subunit,
  1609. uint8_t *operands, size_t operand_count,
  1610. void *user_data)
  1611. {
  1612. struct avrcp *session = user_data;
  1613. struct avrcp_player *player = session->player;
  1614. struct avrcp_header *pdu;
  1615. struct list_values_rsp *rsp;
  1616. uint8_t number = 0;
  1617. uint8_t *values = NULL;
  1618. int err;
  1619. DBG("");
  1620. if (!player || !player->cfm || !player->cfm->list_values)
  1621. return FALSE;
  1622. pdu = parse_pdu(operands, operand_count);
  1623. if (!pdu) {
  1624. err = -EPROTO;
  1625. goto done;
  1626. }
  1627. if (code == AVC_CTYPE_REJECTED) {
  1628. err = parse_status(pdu);
  1629. goto done;
  1630. }
  1631. if (pdu->params_len < sizeof(*rsp)) {
  1632. err = -EPROTO;
  1633. goto done;
  1634. }
  1635. rsp = (void *) pdu->params;
  1636. if (rsp->number > 0) {
  1637. number = rsp->number;
  1638. values = rsp->params;
  1639. }
  1640. err = 0;
  1641. done:
  1642. player->cfm->list_values(session, err, number, values,
  1643. player->user_data);
  1644. return FALSE;
  1645. }
  1646. int avrcp_list_player_values(struct avrcp *session, uint8_t attr)
  1647. {
  1648. struct iovec iov;
  1649. iov.iov_base = &attr;
  1650. iov.iov_len = sizeof(attr);
  1651. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1652. AVRCP_LIST_PLAYER_VALUES, &iov, 1,
  1653. list_values_rsp, session);
  1654. }
  1655. static gboolean get_value_text_rsp(struct avctp *conn,
  1656. uint8_t code, uint8_t subunit,
  1657. uint8_t *operands, size_t operand_count,
  1658. void *user_data)
  1659. {
  1660. struct avrcp *session = user_data;
  1661. struct avrcp_player *player = session->player;
  1662. struct avrcp_header *pdu;
  1663. uint8_t number = 0;
  1664. uint8_t values[AVRCP_ATTRIBUTE_LAST];
  1665. char *text[AVRCP_ATTRIBUTE_LAST];
  1666. int err;
  1667. DBG("");
  1668. if (!player || !player->cfm || !player->cfm->get_value_text)
  1669. return FALSE;
  1670. pdu = parse_pdu(operands, operand_count);
  1671. if (!pdu) {
  1672. err = -EPROTO;
  1673. goto done;
  1674. }
  1675. if (code == AVC_CTYPE_REJECTED) {
  1676. err = parse_status(pdu);
  1677. goto done;
  1678. }
  1679. err = parse_text_rsp(pdu, &number, values, text);
  1680. done:
  1681. player->cfm->get_value_text(session, err, number, values, text,
  1682. player->user_data);
  1683. return FALSE;
  1684. }
  1685. int avrcp_get_player_value_text(struct avrcp *session, uint8_t attr,
  1686. uint8_t number, uint8_t *values)
  1687. {
  1688. struct iovec iov[2];
  1689. struct get_value_text_req req;
  1690. if (!number)
  1691. return -EINVAL;
  1692. req.attr = attr;
  1693. req.number = number;
  1694. iov[0].iov_base = &req;
  1695. iov[0].iov_len = sizeof(req);
  1696. iov[1].iov_base = values;
  1697. iov[1].iov_len = number;
  1698. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1699. AVRCP_GET_PLAYER_VALUE_TEXT, iov, 2,
  1700. get_value_text_rsp, session);
  1701. }
  1702. static int parse_value(struct avrcp_header *pdu, uint8_t *number,
  1703. uint8_t *attrs, uint8_t *values)
  1704. {
  1705. int i;
  1706. struct value_rsp *rsp;
  1707. if (pdu->params_len < sizeof(*rsp))
  1708. return -EPROTO;
  1709. rsp = (void *) pdu->params;
  1710. /*
  1711. * Check if PDU is big enough to hold the number of (attribute, value)
  1712. * tuples.
  1713. */
  1714. if (rsp->number > AVRCP_ATTRIBUTE_LAST ||
  1715. sizeof(*rsp) + rsp->number * 2 != pdu->params_len) {
  1716. *number = 0;
  1717. return -EPROTO;
  1718. }
  1719. for (i = 0; i < rsp->number; i++) {
  1720. attrs[i] = rsp->values[i].attr;
  1721. values[i] = rsp->values[i].value;
  1722. }
  1723. *number = rsp->number;
  1724. return 0;
  1725. }
  1726. static gboolean get_value_rsp(struct avctp *conn,
  1727. uint8_t code, uint8_t subunit,
  1728. uint8_t *operands, size_t operand_count,
  1729. void *user_data)
  1730. {
  1731. struct avrcp *session = user_data;
  1732. struct avrcp_player *player = session->player;
  1733. struct avrcp_header *pdu;
  1734. uint8_t number = 0;
  1735. uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
  1736. uint8_t values[AVRCP_ATTRIBUTE_LAST];
  1737. int err;
  1738. DBG("");
  1739. if (!player || !player->cfm || !player->cfm->get_value)
  1740. return FALSE;
  1741. pdu = parse_pdu(operands, operand_count);
  1742. if (!pdu) {
  1743. err = -EPROTO;
  1744. goto done;
  1745. }
  1746. if (code == AVC_CTYPE_REJECTED) {
  1747. err = parse_status(pdu);
  1748. goto done;
  1749. }
  1750. err = parse_value(pdu, &number, attrs, values);
  1751. done:
  1752. player->cfm->get_value(session, err, number, attrs, values,
  1753. player->user_data);
  1754. return FALSE;
  1755. }
  1756. int avrcp_get_current_player_value(struct avrcp *session, uint8_t number,
  1757. uint8_t *attrs)
  1758. {
  1759. struct iovec iov[2];
  1760. if (number > AVRCP_ATTRIBUTE_LAST)
  1761. return -EINVAL;
  1762. iov[0].iov_base = &number;
  1763. iov[0].iov_len = sizeof(number);
  1764. iov[1].iov_base = attrs;
  1765. iov[1].iov_len = number;
  1766. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1767. AVRCP_GET_CURRENT_PLAYER_VALUE, iov, 2,
  1768. get_value_rsp, session);
  1769. }
  1770. static gboolean set_value_rsp(struct avctp *conn,
  1771. uint8_t code, uint8_t subunit,
  1772. uint8_t *operands, size_t operand_count,
  1773. void *user_data)
  1774. {
  1775. struct avrcp *session = user_data;
  1776. struct avrcp_player *player = session->player;
  1777. struct avrcp_header *pdu;
  1778. int err;
  1779. DBG("");
  1780. if (!player || !player->cfm || !player->cfm->set_value)
  1781. return FALSE;
  1782. pdu = parse_pdu(operands, operand_count);
  1783. if (!pdu) {
  1784. err = -EPROTO;
  1785. goto done;
  1786. }
  1787. if (code == AVC_CTYPE_REJECTED) {
  1788. err = parse_status(pdu);
  1789. goto done;
  1790. }
  1791. err = 0;
  1792. done:
  1793. player->cfm->set_value(session, err, player->user_data);
  1794. return FALSE;
  1795. }
  1796. int avrcp_set_player_value(struct avrcp *session, uint8_t number,
  1797. uint8_t *attrs, uint8_t *values)
  1798. {
  1799. struct iovec iov[2];
  1800. struct attr_value val[AVRCP_ATTRIBUTE_LAST];
  1801. int i;
  1802. if (number > AVRCP_ATTRIBUTE_LAST)
  1803. return -EINVAL;
  1804. iov[0].iov_base = &number;
  1805. iov[0].iov_len = sizeof(number);
  1806. for (i = 0; i < number; i++) {
  1807. val[i].attr = attrs[i];
  1808. val[i].value = values[i];
  1809. }
  1810. iov[1].iov_base = val;
  1811. iov[1].iov_len = sizeof(*val) * number;
  1812. return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
  1813. AVRCP_SET_PLAYER_VALUE, iov, 2,
  1814. set_value_rsp, session);
  1815. }
  1816. static gboolean get_play_status_rsp(struct avctp *conn,
  1817. uint8_t code, uint8_t subunit,
  1818. uint8_t *operands, size_t operand_count,
  1819. void *user_data)
  1820. {
  1821. struct avrcp *session = user_data;
  1822. struct avrcp_player *player = session->player;
  1823. struct avrcp_header *pdu;
  1824. struct get_play_status_rsp *rsp;
  1825. uint8_t status = 0;
  1826. uint32_t position = 0;
  1827. uint32_t duration = 0;
  1828. int err;
  1829. DBG("");
  1830. if (!player || !player->cfm || !player->cfm->get_play_status)
  1831. return FALSE;
  1832. pdu = parse_pdu(operands, operand_count);
  1833. if (!pdu) {
  1834. err = -EPROTO;
  1835. goto done;
  1836. }
  1837. if (code == AVC_CTYPE_REJECTED) {
  1838. err = parse_status(pdu);
  1839. goto done;
  1840. }
  1841. if (pdu->params_len < sizeof(*rsp)) {
  1842. err = -EPROTO;
  1843. goto done;
  1844. }
  1845. rsp = (void *) pdu->params;
  1846. duration = be32_to_cpu(rsp->duration);
  1847. position = be32_to_cpu(rsp->position);
  1848. status = rsp->status;
  1849. err = 0;
  1850. done:
  1851. player->cfm->get_play_status(session, err, status, position, duration,
  1852. player->user_data);
  1853. return FALSE;
  1854. }
  1855. int avrcp_get_play_status(struct avrcp *session)
  1856. {
  1857. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  1858. AVRCP_GET_PLAY_STATUS, NULL, 0,
  1859. get_play_status_rsp, session);
  1860. }
  1861. static gboolean set_volume_rsp(struct avctp *conn,
  1862. uint8_t code, uint8_t subunit,
  1863. uint8_t *operands, size_t operand_count,
  1864. void *user_data)
  1865. {
  1866. struct avrcp *session = user_data;
  1867. struct avrcp_player *player = session->player;
  1868. struct avrcp_header *pdu;
  1869. struct set_volume_rsp *rsp;
  1870. uint8_t value = 0;
  1871. int err;
  1872. DBG("");
  1873. if (!player || !player->cfm || !player->cfm->set_volume)
  1874. return FALSE;
  1875. pdu = parse_pdu(operands, operand_count);
  1876. if (!pdu) {
  1877. err = -EPROTO;
  1878. goto done;
  1879. }
  1880. if (code == AVC_CTYPE_REJECTED) {
  1881. err = parse_status(pdu);
  1882. goto done;
  1883. }
  1884. if (pdu->params_len < sizeof(*rsp)) {
  1885. err = -EPROTO;
  1886. goto done;
  1887. }
  1888. rsp = (void *) pdu->params;
  1889. value = rsp->value & 0x7f;
  1890. err = 0;
  1891. done:
  1892. player->cfm->set_volume(session, err, value, player->user_data);
  1893. return FALSE;
  1894. }
  1895. int avrcp_set_volume(struct avrcp *session, uint8_t volume)
  1896. {
  1897. struct iovec iov;
  1898. iov.iov_base = &volume;
  1899. iov.iov_len = sizeof(volume);
  1900. return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
  1901. AVRCP_SET_ABSOLUTE_VOLUME, &iov, 1,
  1902. set_volume_rsp, session);
  1903. }
  1904. static int parse_attribute_list(uint8_t *params, uint16_t params_len,
  1905. uint8_t number, uint32_t *attrs, char **text)
  1906. {
  1907. struct media_item *item;
  1908. int i;
  1909. if (number > AVRCP_MEDIA_ATTRIBUTE_LAST)
  1910. return -EPROTO;
  1911. for (i = 0; i < number && params_len >= sizeof(*item); i++) {
  1912. item = (void *) params;
  1913. item->attr = be32_to_cpu(item->attr);
  1914. item->charset = be16_to_cpu(item->charset);
  1915. item->len = be16_to_cpu(item->len);
  1916. params_len -= sizeof(*item);
  1917. params += sizeof(*item);
  1918. if (item->len > params_len)
  1919. goto fail;
  1920. if (item->len > 0) {
  1921. text[i] = g_strndup(item->data, item->len);
  1922. attrs[i] = item->attr;
  1923. params_len -= item->len;
  1924. params += item->len;
  1925. } else {
  1926. text[i] = NULL;
  1927. attrs[i] = 0;
  1928. }
  1929. }
  1930. return 0;
  1931. fail:
  1932. for (i -= 1; i >= 0; i--)
  1933. g_free(text[i]);
  1934. return -EPROTO;
  1935. }
  1936. static void free_attribute_list(uint8_t number, char **text)
  1937. {
  1938. while(number--)
  1939. g_free(text[number]);
  1940. }
  1941. static int parse_elements(struct avrcp_header *pdu, uint8_t *number,
  1942. uint32_t *attrs, char **text)
  1943. {
  1944. struct get_element_attributes_rsp *rsp;
  1945. if (pdu->params_len < sizeof(*rsp))
  1946. return -EPROTO;
  1947. rsp = (void *) pdu->params;
  1948. if (rsp->number > AVRCP_MEDIA_ATTRIBUTE_LAST)
  1949. return -EPROTO;
  1950. *number = rsp->number;
  1951. return parse_attribute_list(pdu->params + sizeof(*rsp),
  1952. pdu->params_len - sizeof(*rsp),
  1953. *number, attrs, text);
  1954. }
  1955. static int parse_items(struct avrcp_browsing_header *pdu, uint8_t *number,
  1956. uint32_t *attrs, char **text)
  1957. {
  1958. struct get_item_attributes_rsp *rsp;
  1959. if (pdu->params_len < sizeof(*rsp))
  1960. return -EPROTO;
  1961. rsp = (void *) pdu->params;
  1962. if (rsp->number > AVRCP_MEDIA_ATTRIBUTE_LAST)
  1963. return -EPROTO;
  1964. *number = rsp->number;
  1965. return parse_attribute_list(pdu->params + sizeof(*rsp),
  1966. pdu->params_len - sizeof(*rsp),
  1967. *number, attrs, text);
  1968. }
  1969. static gboolean get_element_attributes_rsp(struct avctp *conn,
  1970. uint8_t code, uint8_t subunit,
  1971. uint8_t *operands, size_t operand_count,
  1972. void *user_data)
  1973. {
  1974. struct avrcp *session = user_data;
  1975. struct avrcp_player *player = session->player;
  1976. struct avrcp_header *pdu;
  1977. uint8_t number = 0;
  1978. uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST];
  1979. char *text[AVRCP_MEDIA_ATTRIBUTE_LAST];
  1980. int err;
  1981. DBG("");
  1982. if (!player || !player->cfm || !player->cfm->get_element_attributes)
  1983. return FALSE;
  1984. pdu = parse_pdu(operands, operand_count);
  1985. if (!pdu) {
  1986. err = -EPROTO;
  1987. goto done;
  1988. }
  1989. if (code == AVC_CTYPE_REJECTED) {
  1990. err = parse_status(pdu);
  1991. goto done;
  1992. }
  1993. err = parse_elements(pdu, &number, attrs, text);
  1994. done:
  1995. player->cfm->get_element_attributes(session, err, number, attrs, text,
  1996. player->user_data);
  1997. if (err == 0)
  1998. free_attribute_list(number, text);
  1999. return FALSE;
  2000. }
  2001. int avrcp_get_element_attributes(struct avrcp *session)
  2002. {
  2003. struct iovec iov;
  2004. struct get_element_attributes_req req;
  2005. /* This returns all attributes */
  2006. memset(&req, 0, sizeof(req));
  2007. iov.iov_base = &req;
  2008. iov.iov_len = sizeof(req);
  2009. return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
  2010. AVRCP_GET_ELEMENT_ATTRIBUTES, &iov, 1,
  2011. get_element_attributes_rsp, session);
  2012. }
  2013. static gboolean set_addressed_rsp(struct avctp *conn,
  2014. uint8_t code, uint8_t subunit,
  2015. uint8_t *operands, size_t operand_count,
  2016. void *user_data)
  2017. {
  2018. struct avrcp *session = user_data;
  2019. struct avrcp_player *player = session->player;
  2020. struct avrcp_header *pdu;
  2021. int err;
  2022. DBG("");
  2023. if (!player || !player->cfm || !player->cfm->set_addressed)
  2024. return FALSE;
  2025. pdu = parse_pdu(operands, operand_count);
  2026. if (!pdu) {
  2027. err = -EPROTO;
  2028. goto done;
  2029. }
  2030. err = parse_status(pdu);
  2031. done:
  2032. player->cfm->set_addressed(session, err, player->user_data);
  2033. return FALSE;
  2034. }
  2035. int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id)
  2036. {
  2037. struct iovec iov;
  2038. struct set_addressed_req req;
  2039. req.id = cpu_to_be16(player_id);
  2040. iov.iov_base = &req;
  2041. iov.iov_len = sizeof(req);
  2042. return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
  2043. AVRCP_SET_ADDRESSED_PLAYER, &iov, 1,
  2044. set_addressed_rsp, session);
  2045. }
  2046. static char *parse_folder_list(uint8_t *params, uint16_t params_len,
  2047. uint8_t depth)
  2048. {
  2049. char **folders, *path;
  2050. uint8_t count;
  2051. size_t i;
  2052. folders = g_new0(char *, depth + 2);
  2053. folders[0] = g_strdup("/Filesystem");
  2054. for (i = 0, count = 1; count <= depth && i < params_len; count++) {
  2055. uint8_t len;
  2056. len = params[i++];
  2057. if (i + len > params_len || len == 0) {
  2058. g_strfreev(folders);
  2059. return NULL;
  2060. }
  2061. folders[count] = g_memdup(&params[i], len);
  2062. i += len;
  2063. }
  2064. path = g_build_pathv("/", folders);
  2065. g_strfreev(folders);
  2066. return path;
  2067. }
  2068. static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands,
  2069. size_t operand_count, void *user_data)
  2070. {
  2071. struct avrcp *session = user_data;
  2072. struct avrcp_player *player = session->player;
  2073. struct avrcp_browsing_header *pdu;
  2074. struct set_browsed_rsp *rsp;
  2075. uint16_t counter = 0;
  2076. uint32_t items = 0;
  2077. char *path = NULL;
  2078. int err;
  2079. DBG("");
  2080. if (!player || !player->cfm || !player->cfm->set_browsed)
  2081. return FALSE;
  2082. pdu = parse_browsing_pdu(operands, operand_count);
  2083. if (!pdu) {
  2084. err = -EPROTO;
  2085. goto done;
  2086. }
  2087. err = parse_browsing_status(pdu);
  2088. if (err < 0)
  2089. goto done;
  2090. if (pdu->params_len < sizeof(*rsp)) {
  2091. err = -EPROTO;
  2092. goto done;
  2093. }
  2094. rsp = (void *) pdu->params;
  2095. counter = be16_to_cpu(rsp->counter);
  2096. items = be32_to_cpu(rsp->items);
  2097. path = parse_folder_list(rsp->data, pdu->params_len - sizeof(*rsp),
  2098. rsp->depth);
  2099. if (!path)
  2100. err = -EPROTO;
  2101. done:
  2102. player->cfm->set_browsed(session, err, counter, items, path,
  2103. player->user_data);
  2104. return FALSE;
  2105. }
  2106. int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id)
  2107. {
  2108. struct iovec iov;
  2109. struct set_browsed_req req;
  2110. req.id = cpu_to_be16(player_id);
  2111. iov.iov_base = &req;
  2112. iov.iov_len = sizeof(req);
  2113. return avrcp_send_browsing_req(session, AVRCP_SET_BROWSED_PLAYER,
  2114. &iov, 1, set_browsed_rsp, session);
  2115. }
  2116. static gboolean get_folder_items_rsp(struct avctp *conn,
  2117. uint8_t *operands, size_t operand_count,
  2118. void *user_data)
  2119. {
  2120. struct avrcp *session = user_data;
  2121. struct avrcp_player *player = session->player;
  2122. struct avrcp_browsing_header *pdu;
  2123. struct get_folder_items_rsp *rsp;
  2124. uint16_t counter = 0, number = 0;
  2125. uint8_t *params = NULL;
  2126. int err;
  2127. DBG("");
  2128. if (!player || !player->cfm || !player->cfm->get_folder_items)
  2129. return FALSE;
  2130. pdu = parse_browsing_pdu(operands, operand_count);
  2131. if (!pdu) {
  2132. err = -EPROTO;
  2133. goto done;
  2134. }
  2135. err = parse_browsing_status(pdu);
  2136. if (err < 0)
  2137. goto done;
  2138. if (pdu->params_len < sizeof(*rsp)) {
  2139. err = -EPROTO;
  2140. goto done;
  2141. }
  2142. rsp = (void *) pdu->params;
  2143. counter = be16_to_cpu(rsp->counter);
  2144. number = be16_to_cpu(rsp->number);
  2145. params = rsp->data;
  2146. /* FIXME: Add proper parsing for each item type */
  2147. done:
  2148. player->cfm->get_folder_items(session, err, counter, number, params,
  2149. player->user_data);
  2150. return FALSE;
  2151. }
  2152. int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
  2153. uint32_t start, uint32_t end, uint8_t number,
  2154. uint32_t *attrs)
  2155. {
  2156. struct iovec iov[2];
  2157. struct get_folder_items_req req;
  2158. int i;
  2159. req.scope = scope;
  2160. req.start = cpu_to_be32(start);
  2161. req.end = cpu_to_be32(end);
  2162. req.number = number;
  2163. iov[0].iov_base = &req;
  2164. iov[0].iov_len = sizeof(req);
  2165. if (!number)
  2166. return avrcp_send_browsing_req(session, AVRCP_GET_FOLDER_ITEMS,
  2167. iov, 1, get_folder_items_rsp,
  2168. session);
  2169. for (i = 0; i < number; i++)
  2170. attrs[i] = cpu_to_be32(attrs[i]);
  2171. iov[1].iov_base = attrs;
  2172. iov[1].iov_len = number * sizeof(*attrs);
  2173. return avrcp_send_browsing_req(session, AVRCP_GET_FOLDER_ITEMS,
  2174. iov, 2, get_folder_items_rsp, session);
  2175. }
  2176. static gboolean change_path_rsp(struct avctp *conn, uint8_t *operands,
  2177. size_t operand_count, void *user_data)
  2178. {
  2179. struct avrcp *session = user_data;
  2180. struct avrcp_player *player = session->player;
  2181. struct avrcp_browsing_header *pdu;
  2182. struct change_path_rsp *rsp;
  2183. uint32_t items = 0;
  2184. int err;
  2185. DBG("");
  2186. if (!player || !player->cfm || !player->cfm->change_path)
  2187. return FALSE;
  2188. pdu = parse_browsing_pdu(operands, operand_count);
  2189. if (!pdu) {
  2190. err = -EPROTO;
  2191. goto done;
  2192. }
  2193. err = parse_browsing_status(pdu);
  2194. if (err < 0)
  2195. goto done;
  2196. if (pdu->params_len < sizeof(*rsp)) {
  2197. err = -EPROTO;
  2198. goto done;
  2199. }
  2200. rsp = (void *) pdu->params;
  2201. items = be32_to_cpu(rsp->items);
  2202. done:
  2203. player->cfm->change_path(session, err, items, player->user_data);
  2204. return FALSE;
  2205. }
  2206. int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
  2207. uint16_t counter)
  2208. {
  2209. struct iovec iov;
  2210. struct change_path_req req;
  2211. req.counter = cpu_to_be16(counter);
  2212. req.direction = direction;
  2213. req.uid = cpu_to_be64(uid);
  2214. iov.iov_base = &req;
  2215. iov.iov_len = sizeof(req);
  2216. return avrcp_send_browsing_req(session, AVRCP_CHANGE_PATH,
  2217. &iov, 1, change_path_rsp, session);
  2218. }
  2219. static gboolean get_item_attributes_rsp(struct avctp *conn, uint8_t *operands,
  2220. size_t operand_count, void *user_data)
  2221. {
  2222. struct avrcp *session = user_data;
  2223. struct avrcp_player *player = session->player;
  2224. struct avrcp_browsing_header *pdu;
  2225. uint8_t number = 0;
  2226. uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST];
  2227. char *text[AVRCP_MEDIA_ATTRIBUTE_LAST];
  2228. int err;
  2229. DBG("");
  2230. if (!player || !player->cfm || !player->cfm->get_item_attributes)
  2231. return FALSE;
  2232. pdu = parse_browsing_pdu(operands, operand_count);
  2233. if (!pdu) {
  2234. err = -EPROTO;
  2235. goto done;
  2236. }
  2237. err = parse_browsing_status(pdu);
  2238. if (err < 0)
  2239. goto done;
  2240. err = parse_items(pdu, &number, attrs, text);
  2241. done:
  2242. player->cfm->get_item_attributes(session, err, number, attrs, text,
  2243. player->user_data);
  2244. if (err == 0)
  2245. free_attribute_list(number, text);
  2246. return FALSE;
  2247. }
  2248. int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
  2249. uint64_t uid, uint16_t counter, uint8_t number,
  2250. uint32_t *attrs)
  2251. {
  2252. struct iovec iov[2];
  2253. struct get_item_attributes_req req;
  2254. int i;
  2255. req.scope = scope;
  2256. req.uid = cpu_to_be64(uid);
  2257. req.counter = cpu_to_be16(counter);
  2258. req.number = number;
  2259. iov[0].iov_base = &req;
  2260. iov[0].iov_len = sizeof(req);
  2261. if (!number)
  2262. return avrcp_send_browsing_req(session,
  2263. AVRCP_GET_ITEM_ATTRIBUTES,
  2264. iov, 1, get_item_attributes_rsp,
  2265. session);
  2266. if (number > AVRCP_MEDIA_ATTRIBUTE_LAST)
  2267. return -EINVAL;
  2268. for (i = 0; i < number; i++) {
  2269. if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST ||
  2270. attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL)
  2271. return -EINVAL;
  2272. attrs[i] = cpu_to_be32(attrs[i]);
  2273. }
  2274. iov[1].iov_base = attrs;
  2275. iov[1].iov_len = number * sizeof(*attrs);
  2276. return avrcp_send_browsing_req(session, AVRCP_GET_ITEM_ATTRIBUTES,
  2277. iov, 2, get_item_attributes_rsp,
  2278. session);
  2279. }
  2280. static gboolean play_item_rsp(struct avctp *conn, uint8_t *operands,
  2281. size_t operand_count, void *user_data)
  2282. {
  2283. struct avrcp *session = user_data;
  2284. struct avrcp_player *player = session->player;
  2285. struct avrcp_browsing_header *pdu;
  2286. int err;
  2287. DBG("");
  2288. if (!player || !player->cfm || !player->cfm->play_item)
  2289. return FALSE;
  2290. pdu = parse_browsing_pdu(operands, operand_count);
  2291. if (!pdu) {
  2292. err = -EPROTO;
  2293. goto done;
  2294. }
  2295. err = parse_browsing_status(pdu);
  2296. done:
  2297. player->cfm->play_item(session, err, player->user_data);
  2298. return FALSE;
  2299. }
  2300. int avrcp_play_item(struct avrcp *session, uint8_t scope, uint64_t uid,
  2301. uint16_t counter)
  2302. {
  2303. struct iovec iov;
  2304. struct play_item_req req;
  2305. if (scope > AVRCP_MEDIA_NOW_PLAYING)
  2306. return -EINVAL;
  2307. req.scope = scope;
  2308. req.uid = cpu_to_be64(uid);
  2309. req.counter = cpu_to_be16(counter);
  2310. iov.iov_base = &req;
  2311. iov.iov_len = sizeof(req);
  2312. return avrcp_send_browsing_req(session, AVRCP_PLAY_ITEM, &iov, 1,
  2313. play_item_rsp, session);
  2314. }
  2315. static gboolean search_rsp(struct avctp *conn, uint8_t *operands,
  2316. size_t operand_count, void *user_data)
  2317. {
  2318. struct avrcp *session = user_data;
  2319. struct avrcp_player *player = session->player;
  2320. struct avrcp_browsing_header *pdu;
  2321. struct search_rsp *rsp;
  2322. uint16_t counter = 0;
  2323. uint32_t items = 0;
  2324. int err;
  2325. DBG("");
  2326. if (!player || !player->cfm || !player->cfm->search)
  2327. return FALSE;
  2328. pdu = parse_browsing_pdu(operands, operand_count);
  2329. if (!pdu) {
  2330. err = -EPROTO;
  2331. goto done;
  2332. }
  2333. err = parse_browsing_status(pdu);
  2334. if (err < 0)
  2335. goto done;
  2336. if (pdu->params_len < sizeof(*rsp)) {
  2337. err = -EPROTO;
  2338. goto done;
  2339. }
  2340. rsp = (void *) pdu->params;
  2341. counter = be16_to_cpu(rsp->counter);
  2342. items = be32_to_cpu(rsp->items);
  2343. err = 0;
  2344. done:
  2345. player->cfm->search(session, err, counter, items, player->user_data);
  2346. return FALSE;
  2347. }
  2348. int avrcp_search(struct avrcp *session, const char *string)
  2349. {
  2350. struct iovec iov[2];
  2351. struct search_req req;
  2352. size_t len;
  2353. if (!string)
  2354. return -EINVAL;
  2355. len = strnlen(string, UINT8_MAX);
  2356. req.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
  2357. req.len = cpu_to_be16(len);
  2358. iov[0].iov_base = &req;
  2359. iov[0].iov_len = sizeof(req);
  2360. iov[1].iov_base = (void *) string;
  2361. iov[1].iov_len = len;
  2362. return avrcp_send_browsing_req(session, AVRCP_SEARCH, iov, 2,
  2363. search_rsp, session);
  2364. }
  2365. static gboolean add_to_now_playing_rsp(struct avctp *conn, uint8_t *operands,
  2366. size_t operand_count, void *user_data)
  2367. {
  2368. struct avrcp *session = user_data;
  2369. struct avrcp_player *player = session->player;
  2370. struct avrcp_browsing_header *pdu;
  2371. int err;
  2372. DBG("");
  2373. if (!player || !player->cfm || !player->cfm->add_to_now_playing)
  2374. return FALSE;
  2375. pdu = parse_browsing_pdu(operands, operand_count);
  2376. if (!pdu) {
  2377. err = -EPROTO;
  2378. goto done;
  2379. }
  2380. err = parse_browsing_status(pdu);
  2381. done:
  2382. player->cfm->add_to_now_playing(session, err, player->user_data);
  2383. return FALSE;
  2384. }
  2385. int avrcp_add_to_now_playing(struct avrcp *session, uint8_t scope, uint64_t uid,
  2386. uint16_t counter)
  2387. {
  2388. struct iovec iov;
  2389. struct add_to_now_playing_req req;
  2390. if (scope > AVRCP_MEDIA_NOW_PLAYING)
  2391. return -EINVAL;
  2392. req.scope = scope;
  2393. req.uid = cpu_to_be64(uid);
  2394. req.counter = cpu_to_be16(counter);
  2395. iov.iov_base = &req;
  2396. iov.iov_len = sizeof(req);
  2397. return avrcp_send_browsing_req(session, AVRCP_ADD_TO_NOW_PLAYING,
  2398. &iov, 1, add_to_now_playing_rsp,
  2399. session);
  2400. }
  2401. int avrcp_get_capabilities_rsp(struct avrcp *session, uint8_t transaction,
  2402. uint8_t number, uint8_t *events)
  2403. {
  2404. struct iovec iov[2];
  2405. struct get_capabilities_rsp rsp;
  2406. if (number > AVRCP_EVENT_LAST)
  2407. return -EINVAL;
  2408. rsp.cap = CAP_EVENTS_SUPPORTED;
  2409. rsp.number = number;
  2410. iov[0].iov_base = &rsp;
  2411. iov[0].iov_len = sizeof(rsp);
  2412. iov[1].iov_base = events;
  2413. iov[1].iov_len = number;
  2414. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2415. AVC_SUBUNIT_PANEL, AVRCP_GET_CAPABILITIES,
  2416. iov, 2);
  2417. }
  2418. int avrcp_list_player_attributes_rsp(struct avrcp *session, uint8_t transaction,
  2419. uint8_t number, uint8_t *attrs)
  2420. {
  2421. struct iovec iov[2];
  2422. struct list_attributes_rsp rsp;
  2423. if (number > AVRCP_ATTRIBUTE_LAST)
  2424. return -EINVAL;
  2425. rsp.number = number;
  2426. iov[0].iov_base = &rsp;
  2427. iov[0].iov_len = sizeof(rsp);
  2428. if (!number)
  2429. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2430. AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_ATTRIBUTES,
  2431. iov, 1);
  2432. iov[1].iov_base = attrs;
  2433. iov[1].iov_len = number;
  2434. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2435. AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_ATTRIBUTES,
  2436. iov, 2);
  2437. }
  2438. int avrcp_get_player_attribute_text_rsp(struct avrcp *session,
  2439. uint8_t transaction, uint8_t number,
  2440. uint8_t *attrs, const char **text)
  2441. {
  2442. struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST * 2];
  2443. struct text_value val[AVRCP_ATTRIBUTE_LAST];
  2444. int i;
  2445. if (number > AVRCP_ATTRIBUTE_LAST)
  2446. return -EINVAL;
  2447. iov[0].iov_base = &number;
  2448. iov[0].iov_len = sizeof(number);
  2449. for (i = 0; i < number; i++) {
  2450. uint8_t len = 0;
  2451. if (attrs[i] > AVRCP_ATTRIBUTE_LAST ||
  2452. attrs[i] == AVRCP_ATTRIBUTE_ILEGAL)
  2453. return -EINVAL;
  2454. if (text[i])
  2455. len = strlen(text[i]);
  2456. val[i].attr = attrs[i];
  2457. val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
  2458. val[i].len = len;
  2459. iov[i + 1].iov_base = &val[i];
  2460. iov[i + 1].iov_len = sizeof(val[i]);
  2461. iov[i + 2].iov_base = (void *) text[i];
  2462. iov[i + 2].iov_len = len;
  2463. }
  2464. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2465. AVC_SUBUNIT_PANEL, AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
  2466. iov, 1 + i * 2);
  2467. }
  2468. int avrcp_list_player_values_rsp(struct avrcp *session, uint8_t transaction,
  2469. uint8_t number, uint8_t *values)
  2470. {
  2471. struct iovec iov[2];
  2472. if (number > AVRCP_ATTRIBUTE_LAST)
  2473. return -EINVAL;
  2474. iov[0].iov_base = &number;
  2475. iov[0].iov_len = sizeof(number);
  2476. iov[1].iov_base = values;
  2477. iov[1].iov_len = number;
  2478. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2479. AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_VALUES,
  2480. iov, 2);
  2481. }
  2482. int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
  2483. uint32_t position, uint32_t duration,
  2484. uint8_t status)
  2485. {
  2486. struct iovec iov;
  2487. struct get_play_status_rsp rsp;
  2488. rsp.duration = cpu_to_be32(duration);
  2489. rsp.position = cpu_to_be32(position);
  2490. rsp.status = status;
  2491. iov.iov_base = &rsp;
  2492. iov.iov_len = sizeof(rsp);
  2493. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2494. AVC_SUBUNIT_PANEL, AVRCP_GET_PLAY_STATUS,
  2495. &iov, 1);
  2496. }
  2497. int avrcp_get_player_values_text_rsp(struct avrcp *session,
  2498. uint8_t transaction, uint8_t number,
  2499. uint8_t *values, const char **text)
  2500. {
  2501. struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST * 2];
  2502. struct text_value val[AVRCP_ATTRIBUTE_LAST];
  2503. int i;
  2504. if (number > AVRCP_ATTRIBUTE_LAST)
  2505. return -EINVAL;
  2506. iov[0].iov_base = &number;
  2507. iov[0].iov_len = sizeof(number);
  2508. for (i = 0; i < number; i++) {
  2509. uint8_t len = 0;
  2510. if (text[i])
  2511. len = strlen(text[i]);
  2512. val[i].attr = values[i];
  2513. val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
  2514. val[i].len = len;
  2515. iov[i + 1].iov_base = &val[i];
  2516. iov[i + 1].iov_len = sizeof(val[i]);
  2517. iov[i + 2].iov_base = (void *) text[i];
  2518. iov[i + 2].iov_len = len;
  2519. }
  2520. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2521. AVC_SUBUNIT_PANEL, AVRCP_GET_PLAYER_VALUE_TEXT,
  2522. iov, 1 + i * 2);
  2523. }
  2524. int avrcp_get_current_player_value_rsp(struct avrcp *session,
  2525. uint8_t transaction, uint8_t number,
  2526. uint8_t *attrs, uint8_t *values)
  2527. {
  2528. struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST];
  2529. struct attr_value val[AVRCP_ATTRIBUTE_LAST];
  2530. int i;
  2531. if (number > AVRCP_ATTRIBUTE_LAST)
  2532. return -EINVAL;
  2533. iov[0].iov_base = &number;
  2534. iov[0].iov_len = sizeof(number);
  2535. for (i = 0; i < number; i++) {
  2536. val[i].attr = attrs[i];
  2537. val[i].value = values[i];
  2538. iov[i + 1].iov_base = &val[i];
  2539. iov[i + 1].iov_len = sizeof(val[i]);
  2540. }
  2541. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2542. AVC_SUBUNIT_PANEL, AVRCP_GET_CURRENT_PLAYER_VALUE,
  2543. iov, 1 + i);
  2544. }
  2545. int avrcp_set_player_value_rsp(struct avrcp *session, uint8_t transaction)
  2546. {
  2547. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2548. AVC_SUBUNIT_PANEL, AVRCP_SET_PLAYER_VALUE, NULL, 0);
  2549. }
  2550. int avrcp_get_element_attrs_rsp(struct avrcp *session, uint8_t transaction,
  2551. uint8_t *params, size_t params_len)
  2552. {
  2553. struct iovec iov;
  2554. iov.iov_base = params;
  2555. iov.iov_len = params_len;
  2556. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2557. AVC_SUBUNIT_PANEL, AVRCP_GET_ELEMENT_ATTRIBUTES,
  2558. &iov, 1);
  2559. }
  2560. int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
  2561. uint8_t code, uint8_t event,
  2562. void *data, size_t len)
  2563. {
  2564. struct iovec iov[2];
  2565. uint16_t *player;
  2566. uint8_t *volume;
  2567. if (event > AVRCP_EVENT_LAST)
  2568. return -EINVAL;
  2569. iov[0].iov_base = &event;
  2570. iov[0].iov_len = sizeof(event);
  2571. switch (event) {
  2572. case AVRCP_EVENT_STATUS_CHANGED:
  2573. if (len != sizeof(uint8_t))
  2574. return -EINVAL;
  2575. break;
  2576. case AVRCP_EVENT_VOLUME_CHANGED:
  2577. if (len != sizeof(uint8_t))
  2578. return -EINVAL;
  2579. volume = data;
  2580. if (volume[0] > 127)
  2581. return -EINVAL;
  2582. break;
  2583. case AVRCP_EVENT_TRACK_CHANGED:
  2584. if (len != sizeof(uint64_t))
  2585. return -EINVAL;
  2586. put_be64(*(uint64_t *) data, data);
  2587. break;
  2588. case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
  2589. if (len != sizeof(uint32_t))
  2590. return -EINVAL;
  2591. put_be32(*(uint32_t *) data, data);
  2592. break;
  2593. case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
  2594. if (len != 4)
  2595. return -EINVAL;
  2596. player = data;
  2597. player[0] = cpu_to_be16(player[0]);
  2598. player[1] = cpu_to_be16(player[1]);
  2599. break;
  2600. case AVRCP_EVENT_SETTINGS_CHANGED:
  2601. if (len < sizeof(uint8_t))
  2602. return -EINVAL;
  2603. break;
  2604. case AVRCP_EVENT_UIDS_CHANGED:
  2605. if (len != sizeof(uint16_t))
  2606. return -EINVAL;
  2607. put_be16(*(uint16_t *) data, data);
  2608. break;
  2609. default:
  2610. return avrcp_send(session, transaction, code, AVC_SUBUNIT_PANEL,
  2611. AVRCP_REGISTER_NOTIFICATION, iov, 1);
  2612. }
  2613. iov[1].iov_base = data;
  2614. iov[1].iov_len = len;
  2615. return avrcp_send(session, transaction, code, AVC_SUBUNIT_PANEL,
  2616. AVRCP_REGISTER_NOTIFICATION, iov, 2);
  2617. }
  2618. int avrcp_set_volume_rsp(struct avrcp *session, uint8_t transaction,
  2619. uint8_t volume)
  2620. {
  2621. struct iovec iov;
  2622. if (volume > 127)
  2623. return -EINVAL;
  2624. iov.iov_base = &volume;
  2625. iov.iov_len = sizeof(volume);
  2626. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2627. AVC_SUBUNIT_PANEL, AVRCP_SET_ABSOLUTE_VOLUME,
  2628. &iov, 1);
  2629. }
  2630. int avrcp_set_addressed_player_rsp(struct avrcp *session, uint8_t transaction,
  2631. uint8_t status)
  2632. {
  2633. struct iovec iov;
  2634. iov.iov_base = &status;
  2635. iov.iov_len = sizeof(status);
  2636. return avrcp_send(session, transaction, AVC_CTYPE_STABLE,
  2637. AVC_SUBUNIT_PANEL, AVRCP_SET_ADDRESSED_PLAYER,
  2638. &iov, 1);
  2639. }
  2640. static int avrcp_status_rsp(struct avrcp *session, uint8_t transaction,
  2641. uint8_t pdu_id, uint8_t status)
  2642. {
  2643. struct iovec iov;
  2644. if (status > AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED)
  2645. return -EINVAL;
  2646. iov.iov_base = &status;
  2647. iov.iov_len = sizeof(status);
  2648. return avrcp_send_browsing(session, transaction, pdu_id, &iov, 1);
  2649. }
  2650. int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
  2651. uint8_t status, uint16_t counter,
  2652. uint32_t items, uint8_t depth,
  2653. const char **folders)
  2654. {
  2655. struct iovec iov[UINT8_MAX * 2 + 1];
  2656. struct set_browsed_rsp rsp;
  2657. uint16_t len[UINT8_MAX];
  2658. int i;
  2659. if (status != AVRCP_STATUS_SUCCESS)
  2660. return avrcp_status_rsp(session, transaction,
  2661. AVRCP_SET_BROWSED_PLAYER, status);
  2662. rsp.status = status;
  2663. rsp.counter = cpu_to_be16(counter);
  2664. rsp.items = cpu_to_be32(items);
  2665. rsp.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
  2666. rsp.depth = depth;
  2667. iov[0].iov_base = &rsp;
  2668. iov[0].iov_len = sizeof(rsp);
  2669. if (!depth)
  2670. return avrcp_send_browsing(session, transaction,
  2671. AVRCP_SET_BROWSED_PLAYER,
  2672. iov, 1);
  2673. for (i = 0; i < depth; i++) {
  2674. if (!folders[i])
  2675. return -EINVAL;
  2676. len[i] = strlen(folders[i]);
  2677. iov[i * 2 + 2].iov_base = (void *) folders[i];
  2678. iov[i * 2 + 2].iov_len = len[i];
  2679. len[i] = cpu_to_be16(len[i]);
  2680. iov[i * 2 + 1].iov_base = &len[i];
  2681. iov[i * 2 + 1].iov_len = sizeof(len[i]);
  2682. }
  2683. return avrcp_send_browsing(session, transaction,
  2684. AVRCP_SET_BROWSED_PLAYER, iov,
  2685. depth * 2 + 1);
  2686. }
  2687. int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
  2688. uint8_t status, uint16_t counter,
  2689. uint8_t number, uint8_t *type,
  2690. uint16_t *len, uint8_t **params)
  2691. {
  2692. struct iovec iov[UINT8_MAX * 2 + 1];
  2693. struct get_folder_items_rsp rsp;
  2694. uint8_t item[UINT8_MAX][3];
  2695. int i;
  2696. if (status != AVRCP_STATUS_SUCCESS)
  2697. return avrcp_status_rsp(session, transaction,
  2698. AVRCP_GET_FOLDER_ITEMS, status);
  2699. rsp.status = status;
  2700. rsp.counter = cpu_to_be16(counter);
  2701. rsp.number = cpu_to_be16(number);
  2702. iov[0].iov_base = &rsp;
  2703. iov[0].iov_len = sizeof(rsp);
  2704. for (i = 0; i < number; i++) {
  2705. item[i][0] = type[i];
  2706. put_be16(len[i], &item[i][1]);
  2707. iov[i * 2 + 1].iov_base = item[i];
  2708. iov[i * 2 + 1].iov_len = sizeof(item[i]);
  2709. iov[i * 2 + 2].iov_base = params[i];
  2710. iov[i * 2 + 2].iov_len = len[i];
  2711. }
  2712. return avrcp_send_browsing(session, transaction, AVRCP_GET_FOLDER_ITEMS,
  2713. iov, number * 2 + 1);
  2714. }
  2715. int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction,
  2716. uint8_t status, uint32_t items)
  2717. {
  2718. struct iovec iov;
  2719. struct change_path_rsp rsp;
  2720. if (status != AVRCP_STATUS_SUCCESS)
  2721. return avrcp_status_rsp(session, transaction, AVRCP_CHANGE_PATH,
  2722. status);
  2723. rsp.status = status;
  2724. rsp.items = cpu_to_be32(items);
  2725. iov.iov_base = &rsp;
  2726. iov.iov_len = sizeof(rsp);
  2727. return avrcp_send_browsing(session, transaction, AVRCP_CHANGE_PATH,
  2728. &iov, 1);
  2729. }
  2730. static bool pack_attribute_list(struct iovec *iov, uint8_t number,
  2731. uint32_t *attrs, const char **text)
  2732. {
  2733. int i;
  2734. struct media_item val[AVRCP_MEDIA_ATTRIBUTE_LAST];
  2735. for (i = 0; i < number; i++) {
  2736. uint16_t len = 0;
  2737. if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST ||
  2738. attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL)
  2739. return false;
  2740. if (text[i])
  2741. len = strlen(text[i]);
  2742. val[i].attr = cpu_to_be32(attrs[i]);
  2743. val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
  2744. val[i].len = cpu_to_be16(len);
  2745. iov[i].iov_base = &val[i];
  2746. iov[i].iov_len = sizeof(val[i]);
  2747. iov[i + 1].iov_base = (void *) text[i];
  2748. iov[i + 1].iov_len = len;
  2749. }
  2750. return true;
  2751. }
  2752. int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction,
  2753. uint8_t status, uint8_t number,
  2754. uint32_t *attrs, const char **text)
  2755. {
  2756. struct iovec iov[AVRCP_MEDIA_ATTRIBUTE_LAST * 2 + 1];
  2757. struct get_item_attributes_rsp rsp;
  2758. if (number > AVRCP_MEDIA_ATTRIBUTE_LAST)
  2759. return -EINVAL;
  2760. if (status != AVRCP_STATUS_SUCCESS)
  2761. return avrcp_status_rsp(session, transaction,
  2762. AVRCP_GET_ITEM_ATTRIBUTES, status);
  2763. rsp.status = status;
  2764. rsp.number = number;
  2765. iov[0].iov_base = &rsp;
  2766. iov[0].iov_len = sizeof(rsp);
  2767. if (!pack_attribute_list(&iov[1], number, attrs, text))
  2768. return -EINVAL;
  2769. return avrcp_send_browsing(session, transaction,
  2770. AVRCP_GET_ITEM_ATTRIBUTES, iov,
  2771. number * 2 + 1);
  2772. }
  2773. int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction,
  2774. uint8_t status)
  2775. {
  2776. return avrcp_status_rsp(session, transaction, AVRCP_PLAY_ITEM,
  2777. status);
  2778. }
  2779. int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status,
  2780. uint16_t counter, uint32_t items)
  2781. {
  2782. struct iovec iov;
  2783. struct search_rsp rsp;
  2784. if (status != AVRCP_STATUS_SUCCESS)
  2785. return avrcp_status_rsp(session, transaction, AVRCP_SEARCH,
  2786. status);
  2787. rsp.status = status;
  2788. rsp.counter = cpu_to_be16(counter);
  2789. rsp.items = cpu_to_be32(items);
  2790. iov.iov_base = &rsp;
  2791. iov.iov_len = sizeof(rsp);
  2792. return avrcp_send_browsing(session, transaction, AVRCP_SEARCH,
  2793. &iov, 1);
  2794. }
  2795. int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction,
  2796. uint8_t status)
  2797. {
  2798. return avrcp_status_rsp(session, transaction, AVRCP_ADD_TO_NOW_PLAYING,
  2799. status);
  2800. }
  2801. int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op)
  2802. {
  2803. uint8_t params[5];
  2804. if (!vendor)
  2805. return avctp_send_passthrough(session->conn, op, NULL, 0);
  2806. hton24(params, vendor);
  2807. put_be16(op, &params[3]);
  2808. return avctp_send_passthrough(session->conn, AVC_VENDOR_UNIQUE, params,
  2809. sizeof(params));
  2810. }