avrc_api.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2003-2012 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * Interface to AVRCP mandatory commands
  21. *
  22. ******************************************************************************/
  23. // #include <assert.h>
  24. #include "bt_trace.h"
  25. #include <string.h>
  26. #include "bt_target.h"
  27. #include "gki.h"
  28. #include "avrc_api.h"
  29. #include "avrc_int.h"
  30. #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)
  31. /*****************************************************************************
  32. ** Global data
  33. *****************************************************************************/
  34. #define AVRC_MAX_RCV_CTRL_EVT AVCT_BROWSE_UNCONG_IND_EVT
  35. #ifndef MAX
  36. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  37. #endif
  38. static const UINT8 avrc_ctrl_event_map[] = {
  39. AVRC_OPEN_IND_EVT, /* AVCT_CONNECT_CFM_EVT */
  40. AVRC_OPEN_IND_EVT, /* AVCT_CONNECT_IND_EVT */
  41. AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_CFM_EVT */
  42. AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_IND_EVT */
  43. AVRC_CONG_IND_EVT, /* AVCT_CONG_IND_EVT */
  44. AVRC_UNCONG_IND_EVT,/* AVCT_UNCONG_IND_EVT */
  45. AVRC_BROWSE_OPEN_IND_EVT, /* AVCT_BROWSE_CONN_CFM_EVT */
  46. AVRC_BROWSE_OPEN_IND_EVT, /* AVCT_BROWSE_CONN_IND_EVT */
  47. AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_CFM_EVT */
  48. AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_IND_EVT */
  49. AVRC_BROWSE_CONG_IND_EVT, /* AVCT_BROWSE_CONG_IND_EVT */
  50. AVRC_BROWSE_UNCONG_IND_EVT /* AVCT_BROWSE_UNCONG_IND_EVT */
  51. };
  52. #define AVRC_OP_DROP 0xFE /* use this unused opcode to indication no need to call the callback function */
  53. #define AVRC_OP_DROP_N_FREE 0xFD /* use this unused opcode to indication no need to call the callback function & free buffer */
  54. #define AVRC_OP_UNIT_INFO_RSP_LEN 8
  55. #define AVRC_OP_SUB_UNIT_INFO_RSP_LEN 8
  56. #define AVRC_OP_REJ_MSG_LEN 11
  57. /******************************************************************************
  58. **
  59. ** Function avrc_ctrl_cback
  60. **
  61. ** Description This is the callback function used by AVCTP to report
  62. ** received link events.
  63. **
  64. ** Returns Nothing.
  65. **
  66. ******************************************************************************/
  67. static void avrc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result,
  68. BD_ADDR peer_addr)
  69. {
  70. UINT8 avrc_event;
  71. if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].p_ctrl_cback) {
  72. avrc_event = avrc_ctrl_event_map[event];
  73. if (event == AVCT_CONNECT_CFM_EVT) {
  74. if (result != 0) { /* failed */
  75. avrc_event = AVRC_CLOSE_IND_EVT;
  76. }
  77. }
  78. (*avrc_cb.ccb[handle].p_ctrl_cback)(handle, avrc_event, result, peer_addr);
  79. }
  80. /* else drop the unknown event*/
  81. }
  82. /******************************************************************************
  83. **
  84. ** Function avrc_get_data_ptr
  85. **
  86. ** Description Gets a pointer to the data payload in the packet.
  87. **
  88. ** Returns A pointer to the data payload.
  89. **
  90. ******************************************************************************/
  91. static UINT8 *avrc_get_data_ptr(BT_HDR *p_pkt)
  92. {
  93. return (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  94. }
  95. /******************************************************************************
  96. **
  97. ** Function avrc_copy_packet
  98. **
  99. ** Description Copies an AVRC packet to a new buffer. In the new buffer,
  100. ** the payload offset is at least AVCT_MSG_OFFSET octets.
  101. **
  102. ** Returns The buffer with the copied data.
  103. **
  104. ******************************************************************************/
  105. static BT_HDR *avrc_copy_packet(BT_HDR *p_pkt, int rsp_pkt_len)
  106. {
  107. const int offset = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
  108. const int pkt_len = MAX(rsp_pkt_len, p_pkt->len);
  109. BT_HDR *p_pkt_copy =
  110. (BT_HDR *)GKI_getbuf((UINT16)(BT_HDR_SIZE + offset + pkt_len));
  111. /* Copy the packet header, set the new offset, and copy the payload */
  112. if (p_pkt_copy != NULL) {
  113. memcpy(p_pkt_copy, p_pkt, BT_HDR_SIZE);
  114. p_pkt_copy->offset = offset;
  115. UINT8 *p_data = avrc_get_data_ptr(p_pkt);
  116. UINT8 *p_data_copy = avrc_get_data_ptr(p_pkt_copy);
  117. memcpy(p_data_copy, p_data, p_pkt->len);
  118. }
  119. return p_pkt_copy;
  120. }
  121. #if (AVRC_METADATA_INCLUDED == TRUE)
  122. /******************************************************************************
  123. **
  124. ** Function avrc_prep_end_frag
  125. **
  126. ** Description This function prepares an end response fragment
  127. **
  128. ** Returns Nothing.
  129. **
  130. ******************************************************************************/
  131. static void avrc_prep_end_frag(UINT8 handle)
  132. {
  133. tAVRC_FRAG_CB *p_fcb;
  134. BT_HDR *p_pkt_new;
  135. UINT8 *p_data, *p_orig_data;
  136. UINT8 rsp_type;
  137. AVRC_TRACE_DEBUG ("avrc_prep_end_frag" );
  138. p_fcb = &avrc_cb.fcb[handle];
  139. /* The response type of the end fragment should be the same as the the PDU of "End Fragment
  140. ** Response" Errata: https://www.bluetooth.org/errata/errata_view.cfm?errata_id=4383
  141. */
  142. p_orig_data = ((UINT8 *)(p_fcb->p_fmsg + 1) + p_fcb->p_fmsg->offset);
  143. rsp_type = ((*p_orig_data) & AVRC_CTYPE_MASK);
  144. p_pkt_new = p_fcb->p_fmsg;
  145. p_pkt_new->len -= (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
  146. p_pkt_new->offset += (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
  147. p_data = (UINT8 *)(p_pkt_new + 1) + p_pkt_new->offset;
  148. *p_data++ = rsp_type;
  149. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  150. *p_data++ = AVRC_OP_VENDOR;
  151. AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
  152. *p_data++ = p_fcb->frag_pdu;
  153. *p_data++ = AVRC_PKT_END;
  154. /* 4=pdu, pkt_type & len */
  155. UINT16_TO_BE_STREAM(p_data, (p_pkt_new->len - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE));
  156. }
  157. /******************************************************************************
  158. **
  159. ** Function avrc_send_continue_frag
  160. **
  161. ** Description This function sends a continue response fragment
  162. **
  163. ** Returns Nothing.
  164. **
  165. ******************************************************************************/
  166. static void avrc_send_continue_frag(UINT8 handle, UINT8 label)
  167. {
  168. tAVRC_FRAG_CB *p_fcb;
  169. BT_HDR *p_pkt_old, *p_pkt;
  170. UINT8 *p_old, *p_data;
  171. UINT8 cr = AVCT_RSP;
  172. tAVRC_RSP rej_rsp;
  173. p_fcb = &avrc_cb.fcb[handle];
  174. p_pkt = p_fcb->p_fmsg;
  175. AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d",
  176. __func__, handle, label, p_pkt->len);
  177. if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
  178. int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
  179. p_pkt_old = p_fcb->p_fmsg;
  180. p_pkt = (BT_HDR *)GKI_getbuf((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE));
  181. if (p_pkt) {
  182. p_pkt->len = AVRC_MAX_CTRL_DATA_LEN;
  183. p_pkt->offset = AVCT_MSG_OFFSET;
  184. p_pkt->layer_specific = p_pkt_old->layer_specific;
  185. p_pkt->event = p_pkt_old->event;
  186. p_old = (UINT8 *)(p_pkt_old + 1) + p_pkt_old->offset;
  187. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  188. memcpy (p_data, p_old, AVRC_MAX_CTRL_DATA_LEN);
  189. /* use AVRC continue packet type */
  190. p_data += AVRC_VENDOR_HDR_SIZE;
  191. p_data++; /* pdu */
  192. *p_data++ = AVRC_PKT_CONTINUE;
  193. /* 4=pdu, pkt_type & len */
  194. UINT16_TO_BE_STREAM(p_data, (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4));
  195. /* prepare the left over for as an end fragment */
  196. avrc_prep_end_frag (handle);
  197. } else {
  198. /* use the current GKI buffer to send Internal error status */
  199. p_pkt = p_fcb->p_fmsg;
  200. p_fcb->p_fmsg = NULL;
  201. p_fcb->frag_enabled = FALSE;
  202. AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation - send internal error" );
  203. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  204. *p_data++ = AVRC_PDU_REQUEST_CONTINUATION_RSP;
  205. *p_data++ = 0;
  206. UINT16_TO_BE_STREAM(p_data, 0);
  207. p_pkt->len = 4;
  208. rej_rsp.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
  209. rej_rsp.status = AVRC_STS_INTERNAL_ERR;
  210. AVRC_BldResponse( handle, (tAVRC_RESPONSE *)&rej_rsp, &p_pkt);
  211. cr = AVCT_RSP;
  212. }
  213. } else {
  214. /* end fragment. clean the control block */
  215. p_fcb->frag_enabled = FALSE;
  216. p_fcb->p_fmsg = NULL;
  217. }
  218. AVCT_MsgReq( handle, label, cr, p_pkt);
  219. }
  220. /******************************************************************************
  221. **
  222. ** Function avrc_proc_vendor_command
  223. **
  224. ** Description This function processes received vendor command.
  225. **
  226. ** Returns if not NULL, the response to send right away.
  227. **
  228. ******************************************************************************/
  229. static BT_HDR *avrc_proc_vendor_command(UINT8 handle, UINT8 label,
  230. BT_HDR *p_pkt, tAVRC_MSG_VENDOR *p_msg)
  231. {
  232. BT_HDR *p_rsp = NULL;
  233. UINT8 *p_data;
  234. UINT8 *p_begin;
  235. UINT8 pkt_type;
  236. BOOLEAN abort_frag = FALSE;
  237. tAVRC_STS status = AVRC_STS_NO_ERROR;
  238. tAVRC_FRAG_CB *p_fcb;
  239. p_begin = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  240. p_data = p_begin + AVRC_VENDOR_HDR_SIZE;
  241. pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
  242. if (pkt_type != AVRC_PKT_SINGLE) {
  243. /* reject - commands can only be in single packets at AVRCP level */
  244. AVRC_TRACE_ERROR ("commands must be in single packet pdu:0x%x", *p_data );
  245. /* use the current GKI buffer to send the reject */
  246. status = AVRC_STS_BAD_CMD;
  247. }
  248. /* check if there are fragments waiting to be sent */
  249. else if (avrc_cb.fcb[handle].frag_enabled) {
  250. p_fcb = &avrc_cb.fcb[handle];
  251. if (p_msg->company_id == AVRC_CO_METADATA) {
  252. switch (*p_data) {
  253. case AVRC_PDU_ABORT_CONTINUATION_RSP:
  254. /* aborted by CT - send accept response */
  255. abort_frag = TRUE;
  256. p_begin = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  257. *p_begin = (AVRC_RSP_ACCEPT & AVRC_CTYPE_MASK);
  258. if (*(p_data + 4) != p_fcb->frag_pdu) {
  259. *p_begin = (AVRC_RSP_REJ & AVRC_CTYPE_MASK);
  260. *(p_data + 4) = AVRC_STS_BAD_PARAM;
  261. } else {
  262. p_data = (p_begin + AVRC_VENDOR_HDR_SIZE + 2);
  263. UINT16_TO_BE_STREAM(p_data, 0);
  264. p_pkt->len = (p_data - p_begin);
  265. }
  266. AVCT_MsgReq( handle, label, AVCT_RSP, p_pkt);
  267. p_msg->hdr.opcode = AVRC_OP_DROP; /* used the p_pkt to send response */
  268. break;
  269. case AVRC_PDU_REQUEST_CONTINUATION_RSP:
  270. if (*(p_data + 4) == p_fcb->frag_pdu) {
  271. avrc_send_continue_frag(handle, label);
  272. p_msg->hdr.opcode = AVRC_OP_DROP_N_FREE;
  273. } else {
  274. /* the pdu id does not match - reject the command using the current GKI buffer */
  275. AVRC_TRACE_ERROR("avrc_proc_vendor_command continue pdu: 0x%x does not match \
  276. current re-assembly pdu: 0x%x",
  277. *(p_data + 4), p_fcb->frag_pdu);
  278. status = AVRC_STS_BAD_PARAM;
  279. abort_frag = TRUE;
  280. }
  281. break;
  282. default:
  283. /* implicit abort */
  284. abort_frag = TRUE;
  285. }
  286. } else {
  287. abort_frag = TRUE;
  288. /* implicit abort */
  289. }
  290. if (abort_frag) {
  291. if (p_fcb->p_fmsg) {
  292. GKI_freebuf(p_fcb->p_fmsg);
  293. }
  294. p_fcb->p_fmsg = NULL;
  295. p_fcb->frag_enabled = FALSE;
  296. }
  297. }
  298. if (status != AVRC_STS_NO_ERROR) {
  299. /* use the current GKI buffer to build/send the reject message */
  300. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  301. *p_data++ = AVRC_RSP_REJ;
  302. p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
  303. *p_data++ = 0; /* pkt_type */
  304. UINT16_TO_BE_STREAM(p_data, 1); /* len */
  305. *p_data++ = status; /* error code */
  306. p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
  307. p_rsp = p_pkt;
  308. }
  309. return p_rsp;
  310. }
  311. /******************************************************************************
  312. **
  313. ** Function avrc_proc_far_msg
  314. **
  315. ** Description This function processes metadata fragmenation
  316. ** and reassembly
  317. **
  318. ** Returns 0, to report the message with msg_cback .
  319. **
  320. ******************************************************************************/
  321. static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_pkt,
  322. tAVRC_MSG_VENDOR *p_msg)
  323. {
  324. BT_HDR *p_pkt = *pp_pkt;
  325. UINT8 *p_data;
  326. UINT8 drop_code = 0;
  327. BT_HDR *p_rsp = NULL;
  328. BT_HDR *p_cmd = NULL;
  329. BOOLEAN req_continue = FALSE;
  330. BT_HDR *p_pkt_new = NULL;
  331. UINT8 pkt_type;
  332. UINT16 buf_len;
  333. tAVRC_RASM_CB *p_rcb;
  334. tAVRC_NEXT_CMD avrc_cmd;
  335. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  336. /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
  337. p_data += AVRC_VENDOR_HDR_SIZE;
  338. pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
  339. AVRC_TRACE_DEBUG ("pkt_type %d", pkt_type );
  340. p_rcb = &avrc_cb.rcb[handle];
  341. if (p_msg->company_id == AVRC_CO_METADATA) {
  342. /* check if the message needs to be re-assembled */
  343. if (pkt_type == AVRC_PKT_SINGLE || pkt_type == AVRC_PKT_START) {
  344. /* previous fragments need to be dropped, when received another new message */
  345. p_rcb->rasm_offset = 0;
  346. if (p_rcb->p_rmsg) {
  347. GKI_freebuf(p_rcb->p_rmsg);
  348. p_rcb->p_rmsg = NULL;
  349. }
  350. }
  351. if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP) {
  352. /* not a single response packet - need to re-assemble metadata messages */
  353. if (pkt_type == AVRC_PKT_START) {
  354. /* Allocate buffer for re-assembly */
  355. p_rcb->rasm_pdu = *p_data;
  356. if ((p_rcb->p_rmsg = (BT_HDR *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL) {
  357. /* Copy START packet to buffer for re-assembling fragments*/
  358. memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
  359. /* Copy metadata message */
  360. memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
  361. (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
  362. /* offset of start of metadata response in reassembly buffer */
  363. p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
  364. /* Free original START packet, replace with pointer to reassembly buffer */
  365. GKI_freebuf(p_pkt);
  366. *pp_pkt = p_rcb->p_rmsg;
  367. } else {
  368. /* Unable to allocate buffer for fragmented avrc message. Reuse START
  369. buffer for reassembly (re-assembled message may fit into ACL buf) */
  370. AVRC_TRACE_DEBUG ("Unable to allocate buffer for fragmented avrc message, \
  371. reusing START buffer for reassembly");
  372. p_rcb->rasm_offset = p_pkt->offset;
  373. p_rcb->p_rmsg = p_pkt;
  374. }
  375. /* set offset to point to where to copy next - use the same re-asm logic as AVCT */
  376. p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
  377. req_continue = TRUE;
  378. } else if (p_rcb->p_rmsg == NULL) {
  379. /* Received a CONTINUE/END, but no corresponding START
  380. (or previous fragmented response was dropped) */
  381. AVRC_TRACE_DEBUG ("Received a CONTINUE/END without no corresponding START \
  382. (or previous fragmented response was dropped)");
  383. drop_code = 5;
  384. GKI_freebuf(p_pkt);
  385. *pp_pkt = NULL;
  386. } else {
  387. /* get size of buffer holding assembled message */
  388. buf_len = GKI_get_buf_size (p_rcb->p_rmsg) - sizeof(BT_HDR);
  389. /* adjust offset and len of fragment for header byte */
  390. p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
  391. p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
  392. /* verify length */
  393. if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len) {
  394. AVRC_TRACE_WARNING("Fragmented message too big! - report the partial message");
  395. p_pkt->len = buf_len - p_rcb->p_rmsg->offset;
  396. pkt_type = AVRC_PKT_END;
  397. }
  398. /* copy contents of p_pkt to p_rx_msg */
  399. memcpy((UINT8 *)(p_rcb->p_rmsg + 1) + p_rcb->p_rmsg->offset,
  400. (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
  401. if (pkt_type == AVRC_PKT_END) {
  402. p_rcb->p_rmsg->offset = p_rcb->rasm_offset;
  403. p_rcb->p_rmsg->len += p_pkt->len;
  404. p_pkt_new = p_rcb->p_rmsg;
  405. p_rcb->rasm_offset = 0;
  406. p_rcb->p_rmsg = NULL;
  407. p_msg->p_vendor_data = (UINT8 *)(p_pkt_new + 1) + p_pkt_new->offset;
  408. p_msg->hdr.ctype = p_msg->p_vendor_data[0] & AVRC_CTYPE_MASK;
  409. /* 6 = ctype, subunit*, opcode & CO_ID */
  410. p_msg->p_vendor_data += AVRC_VENDOR_HDR_SIZE;
  411. p_msg->vendor_len = p_pkt_new->len - AVRC_VENDOR_HDR_SIZE;
  412. p_data = p_msg->p_vendor_data + 1; /* skip pdu */
  413. *p_data++ = AVRC_PKT_SINGLE;
  414. UINT16_TO_BE_STREAM(p_data, (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE));
  415. AVRC_TRACE_DEBUG("end frag:%d, total len:%d, offset:%d", p_pkt->len,
  416. p_pkt_new->len, p_pkt_new->offset);
  417. } else {
  418. p_rcb->p_rmsg->offset += p_pkt->len;
  419. p_rcb->p_rmsg->len += p_pkt->len;
  420. p_pkt_new = NULL;
  421. req_continue = TRUE;
  422. }
  423. GKI_freebuf(p_pkt);
  424. *pp_pkt = p_pkt_new;
  425. }
  426. }
  427. if (cr == AVCT_CMD) {
  428. p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg);
  429. if (p_rsp) {
  430. AVCT_MsgReq( handle, label, AVCT_RSP, p_rsp);
  431. drop_code = 3;
  432. } else if (p_msg->hdr.opcode == AVRC_OP_DROP) {
  433. drop_code = 1;
  434. } else if (p_msg->hdr.opcode == AVRC_OP_DROP_N_FREE) {
  435. drop_code = 4;
  436. }
  437. } else if (cr == AVCT_RSP && req_continue == TRUE) {
  438. avrc_cmd.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
  439. avrc_cmd.status = AVRC_STS_NO_ERROR;
  440. avrc_cmd.target_pdu = p_rcb->rasm_pdu;
  441. if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR) {
  442. drop_code = 2;
  443. AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
  444. }
  445. }
  446. }
  447. return drop_code;
  448. }
  449. #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
  450. /******************************************************************************
  451. **
  452. ** Function avrc_msg_cback
  453. **
  454. ** Description This is the callback function used by AVCTP to report
  455. ** received AV control messages.
  456. **
  457. ** Returns Nothing.
  458. **
  459. ******************************************************************************/
  460. static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
  461. BT_HDR *p_pkt)
  462. {
  463. UINT8 opcode;
  464. tAVRC_MSG msg;
  465. UINT8 *p_data;
  466. UINT8 *p_begin;
  467. BOOLEAN drop = FALSE;
  468. BOOLEAN do_free = TRUE;
  469. BT_HDR *p_rsp = NULL;
  470. UINT8 *p_rsp_data;
  471. int xx;
  472. BOOLEAN reject = FALSE;
  473. #if (BT_USE_TRACES == TRUE)
  474. char *p_drop_msg = "dropped";
  475. #endif
  476. tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
  477. if (cr == AVCT_CMD &&
  478. (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len))) {
  479. /* Ignore the invalid AV/C command frame */
  480. #if (BT_USE_TRACES == TRUE)
  481. p_drop_msg = "dropped - too long AV/C cmd frame size";
  482. #endif
  483. GKI_freebuf(p_pkt);
  484. return;
  485. }
  486. if (cr == AVCT_REJ) {
  487. /* The peer thinks that this PID is no longer open - remove this handle */
  488. /* */
  489. GKI_freebuf(p_pkt);
  490. AVCT_RemoveConn(handle);
  491. return;
  492. }
  493. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  494. memset(&msg, 0, sizeof(tAVRC_MSG) );
  495. {
  496. msg.hdr.ctype = p_data[0] & AVRC_CTYPE_MASK;
  497. AVRC_TRACE_DEBUG("avrc_msg_cback handle:%d, ctype:%d, offset:%d, len: %d",
  498. handle, msg.hdr.ctype, p_pkt->offset, p_pkt->len);
  499. msg.hdr.subunit_type = (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
  500. msg.hdr.subunit_id = p_data[1] & AVRC_SUBID_MASK;
  501. opcode = p_data[2];
  502. }
  503. if ( ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) ||
  504. ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP)) ) {
  505. switch (opcode) {
  506. case AVRC_OP_UNIT_INFO:
  507. if (cr == AVCT_CMD) {
  508. /* send the response to the peer */
  509. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_UNIT_INFO_RSP_LEN);
  510. p_rsp_data = avrc_get_data_ptr(p_rsp);
  511. *p_rsp_data = AVRC_RSP_IMPL_STBL;
  512. /* check & set the offset. set response code, set subunit_type & subunit_id,
  513. set AVRC_OP_UNIT_INFO */
  514. /* 3 bytes: ctype, subunit*, opcode */
  515. p_rsp_data += AVRC_AVC_HDR_SIZE;
  516. *p_rsp_data++ = 7;
  517. /* Panel subunit & id=0 */
  518. *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  519. AVRC_CO_ID_TO_BE_STREAM(p_rsp_data, avrc_cb.ccb[handle].company_id);
  520. p_rsp->len = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
  521. cr = AVCT_RSP;
  522. #if (BT_USE_TRACES == TRUE)
  523. p_drop_msg = "auto respond";
  524. #endif
  525. } else {
  526. /* parse response */
  527. p_data += 4; /* 3 bytes: ctype, subunit*, opcode + octet 3 (is 7)*/
  528. msg.unit.unit_type = (*p_data & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
  529. msg.unit.unit = *p_data & AVRC_SUBID_MASK;
  530. p_data++;
  531. AVRC_BE_STREAM_TO_CO_ID(msg.unit.company_id, p_data);
  532. }
  533. break;
  534. case AVRC_OP_SUB_INFO:
  535. if (cr == AVCT_CMD) {
  536. /* send the response to the peer */
  537. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_SUB_UNIT_INFO_RSP_LEN);
  538. p_rsp_data = avrc_get_data_ptr(p_rsp);
  539. *p_rsp_data = AVRC_RSP_IMPL_STBL;
  540. /* check & set the offset. set response code, set (subunit_type & subunit_id),
  541. set AVRC_OP_SUB_INFO, set (page & extention code) */
  542. p_rsp_data += 4;
  543. /* Panel subunit & id=0 */
  544. *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  545. memset(p_rsp_data, AVRC_CMD_OPRND_PAD, AVRC_SUBRSP_OPRND_BYTES);
  546. p_rsp_data += AVRC_SUBRSP_OPRND_BYTES;
  547. p_rsp->len = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
  548. cr = AVCT_RSP;
  549. #if (BT_USE_TRACES == TRUE)
  550. p_drop_msg = "auto responded";
  551. #endif
  552. } else {
  553. /* parse response */
  554. p_data += AVRC_AVC_HDR_SIZE; /* 3 bytes: ctype, subunit*, opcode */
  555. msg.sub.page = (*p_data++ >> AVRC_SUB_PAGE_SHIFT) & AVRC_SUB_PAGE_MASK;
  556. xx = 0;
  557. while (*p_data != AVRC_CMD_OPRND_PAD && xx < AVRC_SUB_TYPE_LEN) {
  558. msg.sub.subunit_type[xx] = *p_data++ >> AVRC_SUBTYPE_SHIFT;
  559. if (msg.sub.subunit_type[xx] == AVRC_SUB_PANEL) {
  560. msg.sub.panel = TRUE;
  561. }
  562. xx++;
  563. }
  564. }
  565. break;
  566. case AVRC_OP_VENDOR:
  567. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  568. p_begin = p_data;
  569. if (p_pkt->len < AVRC_VENDOR_HDR_SIZE) { /* 6 = ctype, subunit*, opcode & CO_ID */
  570. if (cr == AVCT_CMD) {
  571. reject = TRUE;
  572. } else {
  573. drop = TRUE;
  574. }
  575. break;
  576. }
  577. p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
  578. AVRC_BE_STREAM_TO_CO_ID(p_msg->company_id, p_data);
  579. p_msg->p_vendor_data = p_data;
  580. p_msg->vendor_len = p_pkt->len - (p_data - p_begin);
  581. #if (AVRC_METADATA_INCLUDED == TRUE)
  582. UINT8 drop_code = 0;
  583. if (p_msg->company_id == AVRC_CO_METADATA) {
  584. /* Validate length for metadata message */
  585. if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE)) {
  586. if (cr == AVCT_CMD) {
  587. reject = TRUE;
  588. } else {
  589. drop = TRUE;
  590. }
  591. break;
  592. }
  593. /* Check+handle fragmented messages */
  594. drop_code = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg);
  595. if (drop_code > 0) {
  596. drop = TRUE;
  597. }
  598. }
  599. if (drop_code > 0) {
  600. if (drop_code != 4) {
  601. do_free = FALSE;
  602. }
  603. #if (BT_USE_TRACES == TRUE)
  604. switch (drop_code) {
  605. case 1:
  606. p_drop_msg = "sent_frag";
  607. break;
  608. case 2:
  609. p_drop_msg = "req_cont";
  610. break;
  611. case 3:
  612. p_drop_msg = "sent_frag3";
  613. break;
  614. case 4:
  615. p_drop_msg = "sent_frag_free";
  616. break;
  617. default:
  618. p_drop_msg = "sent_fragd";
  619. }
  620. #endif
  621. }
  622. #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
  623. break;
  624. case AVRC_OP_PASS_THRU:
  625. if (p_pkt->len < 5) { /* 3 bytes: ctype, subunit*, opcode & op_id & len */
  626. if (cr == AVCT_CMD) {
  627. reject = TRUE;
  628. } else {
  629. drop = TRUE;
  630. }
  631. break;
  632. }
  633. p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
  634. msg.pass.op_id = (AVRC_PASS_OP_ID_MASK & *p_data);
  635. if (AVRC_PASS_STATE_MASK & *p_data) {
  636. msg.pass.state = TRUE;
  637. } else {
  638. msg.pass.state = FALSE;
  639. }
  640. p_data++;
  641. msg.pass.pass_len = *p_data++;
  642. if (msg.pass.pass_len != p_pkt->len - 5) {
  643. msg.pass.pass_len = p_pkt->len - 5;
  644. }
  645. if (msg.pass.pass_len) {
  646. msg.pass.p_pass_data = p_data;
  647. } else {
  648. msg.pass.p_pass_data = NULL;
  649. }
  650. break;
  651. default:
  652. if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) {
  653. /* reject unsupported opcode */
  654. reject = TRUE;
  655. }
  656. drop = TRUE;
  657. break;
  658. }
  659. } else { /* drop the event */
  660. drop = TRUE;
  661. }
  662. if (reject) {
  663. /* reject unsupported opcode */
  664. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN);
  665. p_rsp_data = avrc_get_data_ptr(p_rsp);
  666. *p_rsp_data = AVRC_RSP_REJ;
  667. #if (BT_USE_TRACES == TRUE)
  668. p_drop_msg = "rejected";
  669. #endif
  670. cr = AVCT_RSP;
  671. drop = TRUE;
  672. }
  673. if (p_rsp) {
  674. /* set to send response right away */
  675. AVCT_MsgReq( handle, label, cr, p_rsp);
  676. drop = TRUE;
  677. }
  678. if (drop == FALSE) {
  679. msg.hdr.opcode = opcode;
  680. (*avrc_cb.ccb[handle].p_msg_cback)(handle, label, opcode, &msg);
  681. }
  682. #if (BT_USE_TRACES == TRUE)
  683. else {
  684. AVRC_TRACE_WARNING("avrc_msg_cback %s msg handle:%d, control:%d, cr:%d, opcode:x%x",
  685. p_drop_msg,
  686. handle, avrc_cb.ccb[handle].control, cr, opcode);
  687. }
  688. #endif
  689. if (do_free) {
  690. GKI_freebuf(p_pkt);
  691. }
  692. }
  693. /******************************************************************************
  694. **
  695. ** Function avrc_pass_msg
  696. **
  697. ** Description Compose a PASS THROUGH command according to p_msg
  698. **
  699. ** Input Parameters:
  700. ** p_msg: Pointer to PASS THROUGH message structure.
  701. **
  702. ** Output Parameters:
  703. ** None.
  704. **
  705. ** Returns pointer to a valid GKI buffer if successful.
  706. ** NULL if p_msg is NULL.
  707. **
  708. ******************************************************************************/
  709. static BT_HDR *avrc_pass_msg(tAVRC_MSG_PASS *p_msg)
  710. {
  711. BT_HDR *p_cmd = NULL;
  712. UINT8 *p_data;
  713. assert(p_msg != NULL);
  714. assert(AVRC_CMD_POOL_SIZE > (AVRC_MIN_CMD_LEN + p_msg->pass_len));
  715. if ((p_cmd = (BT_HDR *) GKI_getpoolbuf(AVRC_CMD_POOL_ID)) != NULL) {
  716. p_cmd->offset = AVCT_MSG_OFFSET;
  717. p_cmd->layer_specific = AVCT_DATA_CTRL;
  718. p_data = (UINT8 *)(p_cmd + 1) + p_cmd->offset;
  719. *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK);
  720. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); /* Panel subunit & id=0 */
  721. *p_data++ = AVRC_OP_PASS_THRU;
  722. *p_data = (AVRC_PASS_OP_ID_MASK & p_msg->op_id);
  723. if (p_msg->state) {
  724. *p_data |= AVRC_PASS_STATE_MASK;
  725. }
  726. p_data++;
  727. if (p_msg->op_id == AVRC_ID_VENDOR) {
  728. *p_data++ = p_msg->pass_len;
  729. if (p_msg->pass_len && p_msg->p_pass_data) {
  730. memcpy(p_data, p_msg->p_pass_data, p_msg->pass_len);
  731. p_data += p_msg->pass_len;
  732. }
  733. } else { /* set msg len to 0 for other op_id */
  734. /* set msg len to 0 for other op_id */
  735. *p_data++ = 0;
  736. }
  737. p_cmd->len = (UINT16) (p_data - (UINT8 *)(p_cmd + 1) - p_cmd->offset);
  738. }
  739. return p_cmd;
  740. }
  741. /******************************************************************************
  742. **
  743. ** Function AVRC_Open
  744. **
  745. ** Description This function is called to open a connection to AVCTP.
  746. ** The connection can be either an initiator or acceptor, as
  747. ** determined by the p_ccb->stream parameter.
  748. ** The connection can be a target, a controller or for both role,
  749. ** as determined by the p_ccb->control parameter.
  750. ** By definition, a target connection is an acceptor connection
  751. ** that waits for an incoming AVCTP connection from the peer.
  752. ** The connection remains available to the application until
  753. ** the application closes it by calling AVRC_Close(). The
  754. ** application does not need to reopen the connection after an
  755. ** AVRC_CLOSE_IND_EVT is received.
  756. **
  757. ** Input Parameters:
  758. ** p_ccb->company_id: Company Identifier.
  759. **
  760. ** p_ccb->p_ctrl_cback: Pointer to control callback function.
  761. **
  762. ** p_ccb->p_msg_cback: Pointer to message callback function.
  763. **
  764. ** p_ccb->conn: AVCTP connection role. This is set to
  765. ** AVCTP_INT for initiator connections and AVCTP_ACP
  766. ** for acceptor connections.
  767. **
  768. ** p_ccb->control: Control role. This is set to
  769. ** AVRC_CT_TARGET for target connections, AVRC_CT_CONTROL
  770. ** for control connections or (AVRC_CT_TARGET|AVRC_CT_CONTROL)
  771. ** for connections that support both roles.
  772. **
  773. ** peer_addr: BD address of peer device. This value is
  774. ** only used for initiator connections; for acceptor
  775. ** connections it can be set to NULL.
  776. **
  777. ** Output Parameters:
  778. ** p_handle: Pointer to handle. This parameter is only
  779. ** valid if AVRC_SUCCESS is returned.
  780. **
  781. ** Returns AVRC_SUCCESS if successful.
  782. ** AVRC_NO_RESOURCES if there are not enough resources to open
  783. ** the connection.
  784. **
  785. ******************************************************************************/
  786. UINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, BD_ADDR_PTR peer_addr)
  787. {
  788. UINT16 status;
  789. tAVCT_CC cc;
  790. cc.p_ctrl_cback = avrc_ctrl_cback; /* Control callback */
  791. cc.p_msg_cback = avrc_msg_cback; /* Message callback */
  792. cc.pid = UUID_SERVCLASS_AV_REMOTE_CONTROL; /* Profile ID */
  793. cc.role = p_ccb->conn; /* Initiator/acceptor role */
  794. cc.control = p_ccb->control; /* Control role (Control/Target) */
  795. status = AVCT_CreateConn(p_handle, &cc, peer_addr);
  796. if (status == AVCT_SUCCESS) {
  797. memcpy(&avrc_cb.ccb[*p_handle], p_ccb, sizeof(tAVRC_CONN_CB));
  798. #if (AVRC_METADATA_INCLUDED == TRUE)
  799. memset(&avrc_cb.fcb[*p_handle], 0, sizeof(tAVRC_FRAG_CB));
  800. memset(&avrc_cb.rcb[*p_handle], 0, sizeof(tAVRC_RASM_CB));
  801. #endif
  802. }
  803. AVRC_TRACE_DEBUG("AVRC_Open role: %d, control:%d status:%d, handle:%d", cc.role, cc.control,
  804. status, *p_handle);
  805. return status;
  806. }
  807. /******************************************************************************
  808. **
  809. ** Function AVRC_Close
  810. **
  811. ** Description Close a connection opened with AVRC_Open().
  812. ** This function is called when the
  813. ** application is no longer using a connection.
  814. **
  815. ** Input Parameters:
  816. ** handle: Handle of this connection.
  817. **
  818. ** Output Parameters:
  819. ** None.
  820. **
  821. ** Returns AVRC_SUCCESS if successful.
  822. ** AVRC_BAD_HANDLE if handle is invalid.
  823. **
  824. ******************************************************************************/
  825. UINT16 AVRC_Close(UINT8 handle)
  826. {
  827. AVRC_TRACE_DEBUG("AVRC_Close handle:%d", handle);
  828. return AVCT_RemoveConn(handle);
  829. }
  830. /******************************************************************************
  831. **
  832. ** Function AVRC_MsgReq
  833. **
  834. ** Description This function is used to send the AVRCP byte stream in p_pkt
  835. ** down to AVCTP.
  836. **
  837. ** It is expected that p_pkt->offset is at least AVCT_MSG_OFFSET
  838. ** p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE
  839. ** p_pkt->event is AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSE
  840. ** The above BT_HDR settings are set by the AVRC_Bld* functions.
  841. **
  842. ** Returns AVRC_SUCCESS if successful.
  843. ** AVRC_BAD_HANDLE if handle is invalid.
  844. **
  845. ******************************************************************************/
  846. UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
  847. {
  848. #if (AVRC_METADATA_INCLUDED == TRUE)
  849. UINT8 *p_data;
  850. UINT8 cr = AVCT_CMD;
  851. BOOLEAN chk_frag = TRUE;
  852. UINT8 *p_start = NULL;
  853. tAVRC_FRAG_CB *p_fcb;
  854. UINT16 len;
  855. BT_HDR *p_pkt_new;
  856. if (!p_pkt) {
  857. return AVRC_BAD_PARAM;
  858. }
  859. AVRC_TRACE_DEBUG("%s handle = %u label = %u ctype = %u len = %d",
  860. __func__, handle, label, ctype, p_pkt->len);
  861. if (ctype >= AVRC_RSP_NOT_IMPL) {
  862. cr = AVCT_RSP;
  863. }
  864. if (p_pkt->event == AVRC_OP_VENDOR) {
  865. /* add AVRCP Vendor Dependent headers */
  866. p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
  867. p_pkt->offset -= AVRC_VENDOR_HDR_SIZE;
  868. p_pkt->len += AVRC_VENDOR_HDR_SIZE;
  869. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  870. *p_data++ = (ctype & AVRC_CTYPE_MASK);
  871. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  872. *p_data++ = AVRC_OP_VENDOR;
  873. AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
  874. } else if (p_pkt->event == AVRC_OP_PASS_THRU) {
  875. /* add AVRCP Pass Through headers */
  876. p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
  877. p_pkt->offset -= AVRC_PASS_THRU_SIZE;
  878. p_pkt->len += AVRC_PASS_THRU_SIZE;
  879. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  880. *p_data++ = (ctype & AVRC_CTYPE_MASK);
  881. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  882. *p_data++ = AVRC_OP_PASS_THRU;/* opcode */
  883. *p_data++ = AVRC_ID_VENDOR; /* operation id */
  884. *p_data++ = 5; /* operation data len */
  885. AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
  886. }
  887. /* abandon previous fragments */
  888. p_fcb = &avrc_cb.fcb[handle];
  889. if (p_fcb->frag_enabled) {
  890. p_fcb->frag_enabled = FALSE;
  891. }
  892. if (p_fcb->p_fmsg) {
  893. GKI_freebuf(p_fcb->p_fmsg);
  894. p_fcb->p_fmsg = NULL;
  895. }
  896. /* AVRCP spec has not defined any control channel commands that needs fragmentation at this level
  897. * check for fragmentation only on the response */
  898. if ((cr == AVCT_RSP) && (chk_frag == TRUE)) {
  899. if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
  900. int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
  901. p_pkt_new = (BT_HDR *)GKI_getbuf((UINT16)(AVRC_PACKET_LEN + offset_len
  902. + BT_HDR_SIZE));
  903. if (p_pkt_new && (p_start != NULL)) {
  904. p_fcb->frag_enabled = TRUE;
  905. p_fcb->p_fmsg = p_pkt;
  906. p_fcb->frag_pdu = *p_start;
  907. p_pkt = p_pkt_new;
  908. p_pkt_new = p_fcb->p_fmsg;
  909. p_pkt->len = AVRC_MAX_CTRL_DATA_LEN;
  910. p_pkt->offset = p_pkt_new->offset;
  911. p_pkt->layer_specific = p_pkt_new->layer_specific;
  912. p_pkt->event = p_pkt_new->event;
  913. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  914. p_start -= AVRC_VENDOR_HDR_SIZE;
  915. memcpy (p_data, p_start, AVRC_MAX_CTRL_DATA_LEN);
  916. /* use AVRC start packet type */
  917. p_data += AVRC_VENDOR_HDR_SIZE;
  918. p_data++; /* pdu */
  919. *p_data++ = AVRC_PKT_START;
  920. /* 4 pdu, pkt_type & len */
  921. len = (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
  922. UINT16_TO_BE_STREAM(p_data, len);
  923. /* prepare the left over for as an end fragment */
  924. avrc_prep_end_frag (handle);
  925. AVRC_TRACE_DEBUG ("%s p_pkt len:%d/%d, next len:%d", __func__,
  926. p_pkt->len, len, p_fcb->p_fmsg->len );
  927. } else {
  928. AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation" );
  929. GKI_freebuf(p_pkt);
  930. return AVRC_NO_RESOURCES;
  931. }
  932. }
  933. }
  934. return AVCT_MsgReq( handle, label, cr, p_pkt);
  935. #else
  936. return AVRC_NO_RESOURCES;
  937. #endif
  938. }
  939. /******************************************************************************
  940. **
  941. ** Function AVRC_PassCmd
  942. **
  943. ** Description Send a PASS THROUGH command to the peer device. This
  944. ** function can only be called for controller role connections.
  945. ** Any response message from the peer is passed back through
  946. ** the tAVRC_MSG_CBACK callback function.
  947. **
  948. ** Input Parameters:
  949. ** handle: Handle of this connection.
  950. **
  951. ** label: Transaction label.
  952. **
  953. ** p_msg: Pointer to PASS THROUGH message structure.
  954. **
  955. ** Output Parameters:
  956. ** None.
  957. **
  958. ** Returns AVRC_SUCCESS if successful.
  959. ** AVRC_BAD_HANDLE if handle is invalid.
  960. **
  961. ******************************************************************************/
  962. UINT16 AVRC_PassCmd(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
  963. {
  964. BT_HDR *p_buf;
  965. assert(p_msg != NULL);
  966. if (p_msg) {
  967. p_msg->hdr.ctype = AVRC_CMD_CTRL;
  968. p_buf = avrc_pass_msg(p_msg);
  969. if (p_buf) {
  970. return AVCT_MsgReq( handle, label, AVCT_CMD, p_buf);
  971. }
  972. }
  973. return AVRC_NO_RESOURCES;
  974. }
  975. /******************************************************************************
  976. **
  977. ** Function AVRC_PassRsp
  978. **
  979. ** Description Send a PASS THROUGH response to the peer device. This
  980. ** function can only be called for target role connections.
  981. ** This function must be called when a PASS THROUGH command
  982. ** message is received from the peer through the
  983. ** tAVRC_MSG_CBACK callback function.
  984. **
  985. ** Input Parameters:
  986. ** handle: Handle of this connection.
  987. **
  988. ** label: Transaction label. Must be the same value as
  989. ** passed with the command message in the callback function.
  990. **
  991. ** p_msg: Pointer to PASS THROUGH message structure.
  992. **
  993. ** Output Parameters:
  994. ** None.
  995. **
  996. ** Returns AVRC_SUCCESS if successful.
  997. ** AVRC_BAD_HANDLE if handle is invalid.
  998. **
  999. ******************************************************************************/
  1000. UINT16 AVRC_PassRsp(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
  1001. {
  1002. BT_HDR *p_buf;
  1003. assert(p_msg != NULL);
  1004. if (p_msg) {
  1005. p_buf = avrc_pass_msg(p_msg);
  1006. if (p_buf) {
  1007. return AVCT_MsgReq( handle, label, AVCT_RSP, p_buf);
  1008. }
  1009. }
  1010. return AVRC_NO_RESOURCES;
  1011. }
  1012. #endif /* #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE) */