avrc_api.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  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 "common/bt_trace.h"
  25. #include <string.h>
  26. #include "common/bt_target.h"
  27. #include "stack/avrc_api.h"
  28. #include "avrc_int.h"
  29. #include "osi/allocator.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 *)osi_malloc((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 *)osi_malloc((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. osi_free(p_fcb->p_fmsg);
  293. p_fcb->p_fmsg = NULL;
  294. }
  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. tAVRC_RASM_CB *p_rcb;
  333. tAVRC_NEXT_CMD avrc_cmd;
  334. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  335. /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
  336. p_data += AVRC_VENDOR_HDR_SIZE;
  337. pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
  338. AVRC_TRACE_DEBUG ("pkt_type %d", pkt_type );
  339. p_rcb = &avrc_cb.rcb[handle];
  340. if (p_msg->company_id == AVRC_CO_METADATA) {
  341. /* check if the message needs to be re-assembled */
  342. if (pkt_type == AVRC_PKT_SINGLE || pkt_type == AVRC_PKT_START) {
  343. /* previous fragments need to be dropped, when received another new message */
  344. p_rcb->rasm_offset = 0;
  345. if (p_rcb->p_rmsg) {
  346. osi_free(p_rcb->p_rmsg);
  347. p_rcb->p_rmsg = NULL;
  348. }
  349. }
  350. if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP) {
  351. /* not a single response packet - need to re-assemble metadata messages */
  352. if (pkt_type == AVRC_PKT_START) {
  353. /* Allocate buffer for re-assembly */
  354. p_rcb->rasm_pdu = *p_data;
  355. if ((p_rcb->p_rmsg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE)) != NULL) {
  356. /* Copy START packet to buffer for re-assembling fragments*/
  357. memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
  358. /* Copy metadata message */
  359. memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
  360. (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
  361. /* offset of start of metadata response in reassembly buffer */
  362. p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
  363. /* Free original START packet, replace with pointer to reassembly buffer */
  364. osi_free(p_pkt);
  365. *pp_pkt = p_rcb->p_rmsg;
  366. } else {
  367. /* Unable to allocate buffer for fragmented avrc message. Reuse START
  368. buffer for reassembly (re-assembled message may fit into ACL buf) */
  369. AVRC_TRACE_DEBUG ("Unable to allocate buffer for fragmented avrc message, \
  370. reusing START buffer for reassembly");
  371. p_rcb->rasm_offset = p_pkt->offset;
  372. p_rcb->p_rmsg = p_pkt;
  373. }
  374. /* set offset to point to where to copy next - use the same re-asm logic as AVCT */
  375. p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
  376. req_continue = TRUE;
  377. } else if (p_rcb->p_rmsg == NULL) {
  378. /* Received a CONTINUE/END, but no corresponding START
  379. (or previous fragmented response was dropped) */
  380. AVRC_TRACE_DEBUG ("Received a CONTINUE/END without no corresponding START \
  381. (or previous fragmented response was dropped)");
  382. drop_code = 5;
  383. osi_free(p_pkt);
  384. *pp_pkt = NULL;
  385. } else {
  386. /* get size of buffer holding assembled message */
  387. /*
  388. * NOTE: The buffer is allocated above at the beginning of the
  389. * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
  390. */
  391. UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
  392. /* adjust offset and len of fragment for header byte */
  393. p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
  394. p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
  395. /* verify length */
  396. if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len) {
  397. AVRC_TRACE_WARNING("Fragmented message too big! - report the partial message");
  398. p_pkt->len = buf_len - p_rcb->p_rmsg->offset;
  399. pkt_type = AVRC_PKT_END;
  400. }
  401. /* copy contents of p_pkt to p_rx_msg */
  402. memcpy((UINT8 *)(p_rcb->p_rmsg + 1) + p_rcb->p_rmsg->offset,
  403. (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
  404. if (pkt_type == AVRC_PKT_END) {
  405. p_rcb->p_rmsg->offset = p_rcb->rasm_offset;
  406. p_rcb->p_rmsg->len += p_pkt->len;
  407. p_pkt_new = p_rcb->p_rmsg;
  408. p_rcb->rasm_offset = 0;
  409. p_rcb->p_rmsg = NULL;
  410. p_msg->p_vendor_data = (UINT8 *)(p_pkt_new + 1) + p_pkt_new->offset;
  411. p_msg->hdr.ctype = p_msg->p_vendor_data[0] & AVRC_CTYPE_MASK;
  412. /* 6 = ctype, subunit*, opcode & CO_ID */
  413. p_msg->p_vendor_data += AVRC_VENDOR_HDR_SIZE;
  414. p_msg->vendor_len = p_pkt_new->len - AVRC_VENDOR_HDR_SIZE;
  415. p_data = p_msg->p_vendor_data + 1; /* skip pdu */
  416. *p_data++ = AVRC_PKT_SINGLE;
  417. UINT16_TO_BE_STREAM(p_data, (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE));
  418. AVRC_TRACE_DEBUG("end frag:%d, total len:%d, offset:%d", p_pkt->len,
  419. p_pkt_new->len, p_pkt_new->offset);
  420. } else {
  421. p_rcb->p_rmsg->offset += p_pkt->len;
  422. p_rcb->p_rmsg->len += p_pkt->len;
  423. p_pkt_new = NULL;
  424. req_continue = TRUE;
  425. }
  426. osi_free(p_pkt);
  427. *pp_pkt = p_pkt_new;
  428. }
  429. }
  430. if (cr == AVCT_CMD) {
  431. p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg);
  432. if (p_rsp) {
  433. AVCT_MsgReq( handle, label, AVCT_RSP, p_rsp);
  434. drop_code = 3;
  435. } else if (p_msg->hdr.opcode == AVRC_OP_DROP) {
  436. drop_code = 1;
  437. } else if (p_msg->hdr.opcode == AVRC_OP_DROP_N_FREE) {
  438. drop_code = 4;
  439. }
  440. } else if (cr == AVCT_RSP && req_continue == TRUE) {
  441. avrc_cmd.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
  442. avrc_cmd.status = AVRC_STS_NO_ERROR;
  443. avrc_cmd.target_pdu = p_rcb->rasm_pdu;
  444. if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR) {
  445. drop_code = 2;
  446. AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
  447. }
  448. }
  449. }
  450. return drop_code;
  451. }
  452. #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
  453. /******************************************************************************
  454. **
  455. ** Function avrc_msg_cback
  456. **
  457. ** Description This is the callback function used by AVCTP to report
  458. ** received AV control messages.
  459. **
  460. ** Returns Nothing.
  461. **
  462. ******************************************************************************/
  463. static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
  464. BT_HDR *p_pkt)
  465. {
  466. UINT8 opcode;
  467. tAVRC_MSG msg;
  468. UINT8 *p_data;
  469. UINT8 *p_begin;
  470. BOOLEAN drop = FALSE;
  471. BOOLEAN do_free = TRUE;
  472. BT_HDR *p_rsp = NULL;
  473. UINT8 *p_rsp_data;
  474. int xx;
  475. BOOLEAN reject = FALSE;
  476. #if (BT_USE_TRACES == TRUE)
  477. char *p_drop_msg = "dropped";
  478. #endif
  479. tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
  480. if (cr == AVCT_CMD &&
  481. (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len))) {
  482. /* Ignore the invalid AV/C command frame */
  483. #if (BT_USE_TRACES == TRUE)
  484. p_drop_msg = "dropped - too long AV/C cmd frame size";
  485. #endif
  486. osi_free(p_pkt);
  487. return;
  488. }
  489. if (cr == AVCT_REJ) {
  490. /* The peer thinks that this PID is no longer open - remove this handle */
  491. /* */
  492. osi_free(p_pkt);
  493. AVCT_RemoveConn(handle);
  494. return;
  495. }
  496. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  497. memset(&msg, 0, sizeof(tAVRC_MSG) );
  498. {
  499. msg.hdr.ctype = p_data[0] & AVRC_CTYPE_MASK;
  500. AVRC_TRACE_DEBUG("avrc_msg_cback handle:%d, ctype:%d, offset:%d, len: %d",
  501. handle, msg.hdr.ctype, p_pkt->offset, p_pkt->len);
  502. msg.hdr.subunit_type = (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
  503. msg.hdr.subunit_id = p_data[1] & AVRC_SUBID_MASK;
  504. opcode = p_data[2];
  505. }
  506. if ( ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) ||
  507. ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP)) ) {
  508. switch (opcode) {
  509. case AVRC_OP_UNIT_INFO:
  510. if (cr == AVCT_CMD) {
  511. /* send the response to the peer */
  512. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_UNIT_INFO_RSP_LEN);
  513. p_rsp_data = avrc_get_data_ptr(p_rsp);
  514. *p_rsp_data = AVRC_RSP_IMPL_STBL;
  515. /* check & set the offset. set response code, set subunit_type & subunit_id,
  516. set AVRC_OP_UNIT_INFO */
  517. /* 3 bytes: ctype, subunit*, opcode */
  518. p_rsp_data += AVRC_AVC_HDR_SIZE;
  519. *p_rsp_data++ = 7;
  520. /* Panel subunit & id=0 */
  521. *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  522. AVRC_CO_ID_TO_BE_STREAM(p_rsp_data, avrc_cb.ccb[handle].company_id);
  523. p_rsp->len = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
  524. cr = AVCT_RSP;
  525. #if (BT_USE_TRACES == TRUE)
  526. p_drop_msg = "auto respond";
  527. #endif
  528. } else {
  529. /* parse response */
  530. p_data += 4; /* 3 bytes: ctype, subunit*, opcode + octet 3 (is 7)*/
  531. msg.unit.unit_type = (*p_data & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
  532. msg.unit.unit = *p_data & AVRC_SUBID_MASK;
  533. p_data++;
  534. AVRC_BE_STREAM_TO_CO_ID(msg.unit.company_id, p_data);
  535. }
  536. break;
  537. case AVRC_OP_SUB_INFO:
  538. if (cr == AVCT_CMD) {
  539. /* send the response to the peer */
  540. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_SUB_UNIT_INFO_RSP_LEN);
  541. p_rsp_data = avrc_get_data_ptr(p_rsp);
  542. *p_rsp_data = AVRC_RSP_IMPL_STBL;
  543. /* check & set the offset. set response code, set (subunit_type & subunit_id),
  544. set AVRC_OP_SUB_INFO, set (page & extention code) */
  545. p_rsp_data += 4;
  546. /* Panel subunit & id=0 */
  547. *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  548. memset(p_rsp_data, AVRC_CMD_OPRND_PAD, AVRC_SUBRSP_OPRND_BYTES);
  549. p_rsp_data += AVRC_SUBRSP_OPRND_BYTES;
  550. p_rsp->len = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
  551. cr = AVCT_RSP;
  552. #if (BT_USE_TRACES == TRUE)
  553. p_drop_msg = "auto responded";
  554. #endif
  555. } else {
  556. /* parse response */
  557. p_data += AVRC_AVC_HDR_SIZE; /* 3 bytes: ctype, subunit*, opcode */
  558. msg.sub.page = (*p_data++ >> AVRC_SUB_PAGE_SHIFT) & AVRC_SUB_PAGE_MASK;
  559. xx = 0;
  560. while (*p_data != AVRC_CMD_OPRND_PAD && xx < AVRC_SUB_TYPE_LEN) {
  561. msg.sub.subunit_type[xx] = *p_data++ >> AVRC_SUBTYPE_SHIFT;
  562. if (msg.sub.subunit_type[xx] == AVRC_SUB_PANEL) {
  563. msg.sub.panel = TRUE;
  564. }
  565. xx++;
  566. }
  567. }
  568. break;
  569. case AVRC_OP_VENDOR:
  570. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  571. p_begin = p_data;
  572. if (p_pkt->len < AVRC_VENDOR_HDR_SIZE) { /* 6 = ctype, subunit*, opcode & CO_ID */
  573. if (cr == AVCT_CMD) {
  574. reject = TRUE;
  575. } else {
  576. drop = TRUE;
  577. }
  578. break;
  579. }
  580. p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
  581. AVRC_BE_STREAM_TO_CO_ID(p_msg->company_id, p_data);
  582. p_msg->p_vendor_data = p_data;
  583. p_msg->vendor_len = p_pkt->len - (p_data - p_begin);
  584. #if (AVRC_METADATA_INCLUDED == TRUE)
  585. UINT8 drop_code = 0;
  586. if (p_msg->company_id == AVRC_CO_METADATA) {
  587. /* Validate length for metadata message */
  588. if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE)) {
  589. if (cr == AVCT_CMD) {
  590. reject = TRUE;
  591. } else {
  592. drop = TRUE;
  593. }
  594. break;
  595. }
  596. /* Check+handle fragmented messages */
  597. drop_code = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg);
  598. if (drop_code > 0) {
  599. drop = TRUE;
  600. }
  601. }
  602. if (drop_code > 0) {
  603. if (drop_code != 4) {
  604. do_free = FALSE;
  605. }
  606. #if (BT_USE_TRACES == TRUE)
  607. switch (drop_code) {
  608. case 1:
  609. p_drop_msg = "sent_frag";
  610. break;
  611. case 2:
  612. p_drop_msg = "req_cont";
  613. break;
  614. case 3:
  615. p_drop_msg = "sent_frag3";
  616. break;
  617. case 4:
  618. p_drop_msg = "sent_frag_free";
  619. break;
  620. default:
  621. p_drop_msg = "sent_fragd";
  622. }
  623. #endif
  624. }
  625. #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
  626. break;
  627. case AVRC_OP_PASS_THRU:
  628. if (p_pkt->len < 5) { /* 3 bytes: ctype, subunit*, opcode & op_id & len */
  629. if (cr == AVCT_CMD) {
  630. reject = TRUE;
  631. } else {
  632. drop = TRUE;
  633. }
  634. break;
  635. }
  636. p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
  637. msg.pass.op_id = (AVRC_PASS_OP_ID_MASK & *p_data);
  638. if (AVRC_PASS_STATE_MASK & *p_data) {
  639. msg.pass.state = TRUE;
  640. } else {
  641. msg.pass.state = FALSE;
  642. }
  643. p_data++;
  644. msg.pass.pass_len = *p_data++;
  645. if (msg.pass.pass_len != p_pkt->len - 5) {
  646. msg.pass.pass_len = p_pkt->len - 5;
  647. }
  648. if (msg.pass.pass_len) {
  649. msg.pass.p_pass_data = p_data;
  650. } else {
  651. msg.pass.p_pass_data = NULL;
  652. }
  653. break;
  654. default:
  655. if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) {
  656. /* reject unsupported opcode */
  657. reject = TRUE;
  658. }
  659. drop = TRUE;
  660. break;
  661. }
  662. } else { /* drop the event */
  663. drop = TRUE;
  664. }
  665. if (reject) {
  666. /* reject unsupported opcode */
  667. p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN);
  668. p_rsp_data = avrc_get_data_ptr(p_rsp);
  669. *p_rsp_data = AVRC_RSP_REJ;
  670. #if (BT_USE_TRACES == TRUE)
  671. p_drop_msg = "rejected";
  672. #endif
  673. cr = AVCT_RSP;
  674. drop = TRUE;
  675. }
  676. if (p_rsp) {
  677. /* set to send response right away */
  678. AVCT_MsgReq( handle, label, cr, p_rsp);
  679. drop = TRUE;
  680. }
  681. if (drop == FALSE) {
  682. msg.hdr.opcode = opcode;
  683. (*avrc_cb.ccb[handle].p_msg_cback)(handle, label, opcode, &msg);
  684. }
  685. #if (BT_USE_TRACES == TRUE)
  686. else {
  687. AVRC_TRACE_WARNING("avrc_msg_cback %s msg handle:%d, control:%d, cr:%d, opcode:x%x",
  688. p_drop_msg,
  689. handle, avrc_cb.ccb[handle].control, cr, opcode);
  690. }
  691. #endif
  692. if (do_free) {
  693. osi_free(p_pkt);
  694. }
  695. }
  696. /******************************************************************************
  697. **
  698. ** Function avrc_pass_msg
  699. **
  700. ** Description Compose a PASS THROUGH command according to p_msg
  701. **
  702. ** Input Parameters:
  703. ** p_msg: Pointer to PASS THROUGH message structure.
  704. **
  705. ** Output Parameters:
  706. ** None.
  707. **
  708. ** Returns pointer to a valid GKI buffer if successful.
  709. ** NULL if p_msg is NULL.
  710. **
  711. ******************************************************************************/
  712. static BT_HDR *avrc_pass_msg(tAVRC_MSG_PASS *p_msg)
  713. {
  714. BT_HDR *p_cmd = NULL;
  715. UINT8 *p_data;
  716. assert(p_msg != NULL);
  717. assert(AVRC_CMD_BUF_SIZE > (AVRC_MIN_CMD_LEN+p_msg->pass_len));
  718. if ((p_cmd = (BT_HDR *) osi_malloc(AVRC_CMD_BUF_SIZE)) != NULL) {
  719. p_cmd->offset = AVCT_MSG_OFFSET;
  720. p_cmd->layer_specific = AVCT_DATA_CTRL;
  721. p_data = (UINT8 *)(p_cmd + 1) + p_cmd->offset;
  722. *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK);
  723. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); /* Panel subunit & id=0 */
  724. *p_data++ = AVRC_OP_PASS_THRU;
  725. *p_data = (AVRC_PASS_OP_ID_MASK & p_msg->op_id);
  726. if (p_msg->state) {
  727. *p_data |= AVRC_PASS_STATE_MASK;
  728. }
  729. p_data++;
  730. if (p_msg->op_id == AVRC_ID_VENDOR) {
  731. *p_data++ = p_msg->pass_len;
  732. if (p_msg->pass_len && p_msg->p_pass_data) {
  733. memcpy(p_data, p_msg->p_pass_data, p_msg->pass_len);
  734. p_data += p_msg->pass_len;
  735. }
  736. } else { /* set msg len to 0 for other op_id */
  737. /* set msg len to 0 for other op_id */
  738. *p_data++ = 0;
  739. }
  740. p_cmd->len = (UINT16) (p_data - (UINT8 *)(p_cmd + 1) - p_cmd->offset);
  741. }
  742. return p_cmd;
  743. }
  744. /******************************************************************************
  745. **
  746. ** Function AVRC_Open
  747. **
  748. ** Description This function is called to open a connection to AVCTP.
  749. ** The connection can be either an initiator or acceptor, as
  750. ** determined by the p_ccb->stream parameter.
  751. ** The connection can be a target, a controller or for both role,
  752. ** as determined by the p_ccb->control parameter.
  753. ** By definition, a target connection is an acceptor connection
  754. ** that waits for an incoming AVCTP connection from the peer.
  755. ** The connection remains available to the application until
  756. ** the application closes it by calling AVRC_Close(). The
  757. ** application does not need to reopen the connection after an
  758. ** AVRC_CLOSE_IND_EVT is received.
  759. **
  760. ** Input Parameters:
  761. ** p_ccb->company_id: Company Identifier.
  762. **
  763. ** p_ccb->p_ctrl_cback: Pointer to control callback function.
  764. **
  765. ** p_ccb->p_msg_cback: Pointer to message callback function.
  766. **
  767. ** p_ccb->conn: AVCTP connection role. This is set to
  768. ** AVCTP_INT for initiator connections and AVCTP_ACP
  769. ** for acceptor connections.
  770. **
  771. ** p_ccb->control: Control role. This is set to
  772. ** AVRC_CT_TARGET for target connections, AVRC_CT_CONTROL
  773. ** for control connections or (AVRC_CT_TARGET|AVRC_CT_CONTROL)
  774. ** for connections that support both roles.
  775. **
  776. ** peer_addr: BD address of peer device. This value is
  777. ** only used for initiator connections; for acceptor
  778. ** connections it can be set to NULL.
  779. **
  780. ** Output Parameters:
  781. ** p_handle: Pointer to handle. This parameter is only
  782. ** valid if AVRC_SUCCESS is returned.
  783. **
  784. ** Returns AVRC_SUCCESS if successful.
  785. ** AVRC_NO_RESOURCES if there are not enough resources to open
  786. ** the connection.
  787. **
  788. ******************************************************************************/
  789. UINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, BD_ADDR_PTR peer_addr)
  790. {
  791. UINT16 status;
  792. tAVCT_CC cc;
  793. cc.p_ctrl_cback = avrc_ctrl_cback; /* Control callback */
  794. cc.p_msg_cback = avrc_msg_cback; /* Message callback */
  795. cc.pid = UUID_SERVCLASS_AV_REMOTE_CONTROL; /* Profile ID */
  796. cc.role = p_ccb->conn; /* Initiator/acceptor role */
  797. cc.control = p_ccb->control; /* Control role (Control/Target) */
  798. status = AVCT_CreateConn(p_handle, &cc, peer_addr);
  799. if (status == AVCT_SUCCESS) {
  800. memcpy(&avrc_cb.ccb[*p_handle], p_ccb, sizeof(tAVRC_CONN_CB));
  801. #if (AVRC_METADATA_INCLUDED == TRUE)
  802. memset(&avrc_cb.fcb[*p_handle], 0, sizeof(tAVRC_FRAG_CB));
  803. memset(&avrc_cb.rcb[*p_handle], 0, sizeof(tAVRC_RASM_CB));
  804. #endif
  805. }
  806. AVRC_TRACE_DEBUG("AVRC_Open role: %d, control:%d status:%d, handle:%d", cc.role, cc.control,
  807. status, *p_handle);
  808. return status;
  809. }
  810. /******************************************************************************
  811. **
  812. ** Function AVRC_Close
  813. **
  814. ** Description Close a connection opened with AVRC_Open().
  815. ** This function is called when the
  816. ** application is no longer using a connection.
  817. **
  818. ** Input Parameters:
  819. ** handle: Handle of this connection.
  820. **
  821. ** Output Parameters:
  822. ** None.
  823. **
  824. ** Returns AVRC_SUCCESS if successful.
  825. ** AVRC_BAD_HANDLE if handle is invalid.
  826. **
  827. ******************************************************************************/
  828. UINT16 AVRC_Close(UINT8 handle)
  829. {
  830. AVRC_TRACE_DEBUG("AVRC_Close handle:%d", handle);
  831. return AVCT_RemoveConn(handle);
  832. }
  833. /******************************************************************************
  834. **
  835. ** Function AVRC_MsgReq
  836. **
  837. ** Description This function is used to send the AVRCP byte stream in p_pkt
  838. ** down to AVCTP.
  839. **
  840. ** It is expected that p_pkt->offset is at least AVCT_MSG_OFFSET
  841. ** p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE
  842. ** p_pkt->event is AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSE
  843. ** The above BT_HDR settings are set by the AVRC_Bld* functions.
  844. **
  845. ** Returns AVRC_SUCCESS if successful.
  846. ** AVRC_BAD_HANDLE if handle is invalid.
  847. **
  848. ******************************************************************************/
  849. UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
  850. {
  851. #if (AVRC_METADATA_INCLUDED == TRUE)
  852. UINT8 *p_data;
  853. UINT8 cr = AVCT_CMD;
  854. BOOLEAN chk_frag = TRUE;
  855. UINT8 *p_start = NULL;
  856. tAVRC_FRAG_CB *p_fcb;
  857. UINT16 len;
  858. BT_HDR *p_pkt_new;
  859. if (!p_pkt) {
  860. return AVRC_BAD_PARAM;
  861. }
  862. AVRC_TRACE_DEBUG("%s handle = %u label = %u ctype = %u len = %d",
  863. __func__, handle, label, ctype, p_pkt->len);
  864. if (ctype >= AVRC_RSP_NOT_IMPL) {
  865. cr = AVCT_RSP;
  866. }
  867. if (p_pkt->event == AVRC_OP_VENDOR) {
  868. /* add AVRCP Vendor Dependent headers */
  869. p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
  870. p_pkt->offset -= AVRC_VENDOR_HDR_SIZE;
  871. p_pkt->len += AVRC_VENDOR_HDR_SIZE;
  872. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  873. *p_data++ = (ctype & AVRC_CTYPE_MASK);
  874. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  875. *p_data++ = AVRC_OP_VENDOR;
  876. AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
  877. } else if (p_pkt->event == AVRC_OP_PASS_THRU) {
  878. /* add AVRCP Pass Through headers */
  879. p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
  880. p_pkt->offset -= AVRC_PASS_THRU_SIZE;
  881. p_pkt->len += AVRC_PASS_THRU_SIZE;
  882. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  883. *p_data++ = (ctype & AVRC_CTYPE_MASK);
  884. *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
  885. *p_data++ = AVRC_OP_PASS_THRU;/* opcode */
  886. *p_data++ = AVRC_ID_VENDOR; /* operation id */
  887. *p_data++ = 5; /* operation data len */
  888. AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
  889. }
  890. /* abandon previous fragments */
  891. p_fcb = &avrc_cb.fcb[handle];
  892. if (p_fcb->frag_enabled) {
  893. p_fcb->frag_enabled = FALSE;
  894. }
  895. if (p_fcb->p_fmsg) {
  896. osi_free(p_fcb->p_fmsg);
  897. p_fcb->p_fmsg = NULL;
  898. }
  899. /* AVRCP spec has not defined any control channel commands that needs fragmentation at this level
  900. * check for fragmentation only on the response */
  901. if ((cr == AVCT_RSP) && (chk_frag == TRUE)) {
  902. if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
  903. int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
  904. p_pkt_new = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len
  905. + BT_HDR_SIZE));
  906. if (p_pkt_new && (p_start != NULL)) {
  907. p_fcb->frag_enabled = TRUE;
  908. p_fcb->p_fmsg = p_pkt;
  909. p_fcb->frag_pdu = *p_start;
  910. p_pkt = p_pkt_new;
  911. p_pkt_new = p_fcb->p_fmsg;
  912. p_pkt->len = AVRC_MAX_CTRL_DATA_LEN;
  913. p_pkt->offset = p_pkt_new->offset;
  914. p_pkt->layer_specific = p_pkt_new->layer_specific;
  915. p_pkt->event = p_pkt_new->event;
  916. p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
  917. p_start -= AVRC_VENDOR_HDR_SIZE;
  918. memcpy (p_data, p_start, AVRC_MAX_CTRL_DATA_LEN);
  919. /* use AVRC start packet type */
  920. p_data += AVRC_VENDOR_HDR_SIZE;
  921. p_data++; /* pdu */
  922. *p_data++ = AVRC_PKT_START;
  923. /* 4 pdu, pkt_type & len */
  924. len = (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
  925. UINT16_TO_BE_STREAM(p_data, len);
  926. /* prepare the left over for as an end fragment */
  927. avrc_prep_end_frag (handle);
  928. AVRC_TRACE_DEBUG ("%s p_pkt len:%d/%d, next len:%d", __func__,
  929. p_pkt->len, len, p_fcb->p_fmsg->len );
  930. } else {
  931. AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation" );
  932. osi_free(p_pkt);
  933. return AVRC_NO_RESOURCES;
  934. }
  935. }
  936. }
  937. return AVCT_MsgReq( handle, label, cr, p_pkt);
  938. #else
  939. return AVRC_NO_RESOURCES;
  940. #endif
  941. }
  942. /******************************************************************************
  943. **
  944. ** Function AVRC_PassCmd
  945. **
  946. ** Description Send a PASS THROUGH command to the peer device. This
  947. ** function can only be called for controller role connections.
  948. ** Any response message from the peer is passed back through
  949. ** the tAVRC_MSG_CBACK callback function.
  950. **
  951. ** Input Parameters:
  952. ** handle: Handle of this connection.
  953. **
  954. ** label: Transaction label.
  955. **
  956. ** p_msg: Pointer to PASS THROUGH message structure.
  957. **
  958. ** Output Parameters:
  959. ** None.
  960. **
  961. ** Returns AVRC_SUCCESS if successful.
  962. ** AVRC_BAD_HANDLE if handle is invalid.
  963. **
  964. ******************************************************************************/
  965. UINT16 AVRC_PassCmd(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
  966. {
  967. BT_HDR *p_buf;
  968. assert(p_msg != NULL);
  969. if (p_msg) {
  970. p_msg->hdr.ctype = AVRC_CMD_CTRL;
  971. p_buf = avrc_pass_msg(p_msg);
  972. if (p_buf) {
  973. return AVCT_MsgReq( handle, label, AVCT_CMD, p_buf);
  974. }
  975. }
  976. return AVRC_NO_RESOURCES;
  977. }
  978. /******************************************************************************
  979. **
  980. ** Function AVRC_PassRsp
  981. **
  982. ** Description Send a PASS THROUGH response to the peer device. This
  983. ** function can only be called for target role connections.
  984. ** This function must be called when a PASS THROUGH command
  985. ** message is received from the peer through the
  986. ** tAVRC_MSG_CBACK callback function.
  987. **
  988. ** Input Parameters:
  989. ** handle: Handle of this connection.
  990. **
  991. ** label: Transaction label. Must be the same value as
  992. ** passed with the command message in the callback function.
  993. **
  994. ** p_msg: Pointer to PASS THROUGH message structure.
  995. **
  996. ** Output Parameters:
  997. ** None.
  998. **
  999. ** Returns AVRC_SUCCESS if successful.
  1000. ** AVRC_BAD_HANDLE if handle is invalid.
  1001. **
  1002. ******************************************************************************/
  1003. UINT16 AVRC_PassRsp(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
  1004. {
  1005. BT_HDR *p_buf;
  1006. assert(p_msg != NULL);
  1007. if (p_msg) {
  1008. p_buf = avrc_pass_msg(p_msg);
  1009. if (p_buf) {
  1010. return AVCT_MsgReq( handle, label, AVCT_RSP, p_buf);
  1011. }
  1012. }
  1013. return AVRC_NO_RESOURCES;
  1014. }
  1015. #endif /* #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE) */