• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2011-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  *
21  *  This is the implementation of the API for the advanced audio/video (AV)
22  *  subsystem of BTA, Broadcom's Bluetooth application layer for mobile
23  *  phones.
24  *
25  ******************************************************************************/
26 
27 #include "bt_target.h"
28 #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
29 
30 #include "bta_api.h"
31 #include "bd.h"
32 #include "bta_sys.h"
33 #include "bta_av_api.h"
34 #include "bta_av_int.h"
35 #include "gki.h"
36 #include <string.h>
37 
38 /*****************************************************************************
39 **  Constants
40 *****************************************************************************/
41 
42 static const tBTA_SYS_REG bta_av_reg =
43 {
44     bta_av_hdl_event,
45     BTA_AvDisable
46 };
47 
48 /*******************************************************************************
49 **
50 ** Function         BTA_AvEnable
51 **
52 ** Description      Enable the advanced audio/video service. When the enable
53 **                  operation is complete the callback function will be
54 **                  called with a BTA_AV_ENABLE_EVT. This function must
55 **                  be called before other function in the AV API are
56 **                  called.
57 **
58 ** Returns          void
59 **
60 *******************************************************************************/
BTA_AvEnable(tBTA_SEC sec_mask,tBTA_AV_FEAT features,tBTA_AV_CBACK * p_cback)61 void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, tBTA_AV_CBACK *p_cback)
62 {
63     tBTA_AV_API_ENABLE  *p_buf;
64 
65     /* register with BTA system manager */
66     bta_sys_register(BTA_ID_AV, &bta_av_reg);
67 
68     if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL)
69     {
70         p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
71         p_buf->p_cback  = p_cback;
72         p_buf->features = features;
73         p_buf->sec_mask = sec_mask;
74         bta_sys_sendmsg(p_buf);
75     }
76 }
77 
78 /*******************************************************************************
79 **
80 ** Function         BTA_AvDisable
81 **
82 ** Description      Disable the advanced audio/video service.
83 **
84 ** Returns          void
85 **
86 *******************************************************************************/
BTA_AvDisable(void)87 void BTA_AvDisable(void)
88 {
89     BT_HDR  *p_buf;
90 
91     bta_sys_deregister(BTA_ID_AV);
92     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
93     {
94         p_buf->event = BTA_AV_API_DISABLE_EVT;
95         bta_sys_sendmsg(p_buf);
96     }
97 }
98 
99 /*******************************************************************************
100 **
101 ** Function         BTA_AvRegister
102 **
103 ** Description      Register the audio or video service to stack. When the
104 **                  operation is complete the callback function will be
105 **                  called with a BTA_AV_REGISTER_EVT. This function must
106 **                  be called before AVDT stream is open.
107 **
108 **
109 ** Returns          void
110 **
111 *******************************************************************************/
BTA_AvRegister(tBTA_AV_CHNL chnl,const char * p_service_name,UINT8 app_id,tBTA_AV_DATA_CBACK * p_data_cback)112 void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback)
113 {
114     tBTA_AV_API_REG  *p_buf;
115 
116 
117     if ((p_buf = (tBTA_AV_API_REG *) GKI_getbuf(sizeof(tBTA_AV_API_REG))) != NULL)
118     {
119         p_buf->hdr.layer_specific   = chnl;
120         p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
121         if(p_service_name)
122         {
123             BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
124             p_buf->p_service_name[BTA_SERVICE_NAME_LEN-1] = 0;
125         }
126         else
127         {
128             p_buf->p_service_name[0] = 0;
129         }
130         p_buf->app_id = app_id;
131         p_buf->p_app_data_cback = p_data_cback;
132         bta_sys_sendmsg(p_buf);
133     }
134 }
135 
136 /*******************************************************************************
137 **
138 ** Function         BTA_AvDeregister
139 **
140 ** Description      Deregister the audio or video service
141 **
142 ** Returns          void
143 **
144 *******************************************************************************/
BTA_AvDeregister(tBTA_AV_HNDL hndl)145 void BTA_AvDeregister(tBTA_AV_HNDL hndl)
146 {
147     BT_HDR  *p_buf;
148 
149     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
150     {
151         p_buf->layer_specific   = hndl;
152         p_buf->event = BTA_AV_API_DEREGISTER_EVT;
153         bta_sys_sendmsg(p_buf);
154     }
155 }
156 
157 /*******************************************************************************
158 **
159 ** Function         BTA_AvOpen
160 **
161 ** Description      Opens an advanced audio/video connection to a peer device.
162 **                  When connection is open callback function is called
163 **                  with a BTA_AV_OPEN_EVT.
164 **
165 ** Returns          void
166 **
167 *******************************************************************************/
BTA_AvOpen(BD_ADDR bd_addr,tBTA_AV_HNDL handle,BOOLEAN use_rc,tBTA_SEC sec_mask,UINT16 uuid)168 void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask,
169                                                                              UINT16 uuid)
170 {
171     tBTA_AV_API_OPEN  *p_buf;
172 
173     if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL)
174     {
175         p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
176         p_buf->hdr.layer_specific   = handle;
177         bdcpy(p_buf->bd_addr, bd_addr);
178         p_buf->use_rc = use_rc;
179         p_buf->sec_mask = sec_mask;
180         p_buf->switch_res = BTA_AV_RS_NONE;
181         p_buf->uuid = uuid;
182         bta_sys_sendmsg(p_buf);
183     }
184 }
185 
186 /*******************************************************************************
187 **
188 ** Function         BTA_AvClose
189 **
190 ** Description      Close the current streams.
191 **
192 ** Returns          void
193 **
194 *******************************************************************************/
BTA_AvClose(tBTA_AV_HNDL handle)195 void BTA_AvClose(tBTA_AV_HNDL handle)
196 {
197     BT_HDR  *p_buf;
198 
199     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
200     {
201         p_buf->event = BTA_AV_API_CLOSE_EVT;
202         p_buf->layer_specific   = handle;
203         bta_sys_sendmsg(p_buf);
204     }
205 }
206 
207 /*******************************************************************************
208 **
209 ** Function         BTA_AvDisconnect
210 **
211 ** Description      Close the connection to the address.
212 **
213 ** Returns          void
214 **
215 *******************************************************************************/
BTA_AvDisconnect(BD_ADDR bd_addr)216 void BTA_AvDisconnect(BD_ADDR bd_addr)
217 {
218     tBTA_AV_API_DISCNT  *p_buf;
219 
220     if ((p_buf = (tBTA_AV_API_DISCNT *) GKI_getbuf(sizeof(tBTA_AV_API_DISCNT))) != NULL)
221     {
222         p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
223         bdcpy(p_buf->bd_addr, bd_addr);
224         bta_sys_sendmsg(p_buf);
225     }
226 }
227 
228 /*******************************************************************************
229 **
230 ** Function         BTA_AvStart
231 **
232 ** Description      Start audio/video stream data transfer.
233 **
234 ** Returns          void
235 **
236 *******************************************************************************/
BTA_AvStart(void)237 void BTA_AvStart(void)
238 {
239     BT_HDR  *p_buf;
240 
241     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
242     {
243         p_buf->event = BTA_AV_API_START_EVT;
244         bta_sys_sendmsg(p_buf);
245     }
246 }
247 
248 /*******************************************************************************
249 **
250 ** Function         BTA_AvEnable_Sink
251 **
252 ** Description      Enable/Disable A2DP Sink..
253 **
254 ** Returns          void
255 **
256 *******************************************************************************/
BTA_AvEnable_Sink(int enable)257 void BTA_AvEnable_Sink(int enable)
258 {
259     BT_HDR  *p_buf;
260 
261 #if (BTA_AV_SINK_INCLUDED == TRUE)
262     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
263     {
264         p_buf->event = BTA_AV_API_SINK_ENABLE_EVT;
265         p_buf->layer_specific = enable;
266         bta_sys_sendmsg(p_buf);
267     }
268 #else
269     return;
270 #endif
271 }
272 
273 /*******************************************************************************
274 **
275 ** Function         BTA_AvStop
276 **
277 ** Description      Stop audio/video stream data transfer.
278 **                  If suspend is TRUE, this function sends AVDT suspend signal
279 **                  to the connected peer(s).
280 **
281 ** Returns          void
282 **
283 *******************************************************************************/
BTA_AvStop(BOOLEAN suspend)284 void BTA_AvStop(BOOLEAN suspend)
285 {
286     tBTA_AV_API_STOP  *p_buf;
287 
288     if ((p_buf = (tBTA_AV_API_STOP *) GKI_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL)
289     {
290         p_buf->hdr.event = BTA_AV_API_STOP_EVT;
291         p_buf->flush   = TRUE;
292         p_buf->suspend = suspend;
293         bta_sys_sendmsg(p_buf);
294     }
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function         BTA_AvReconfig
300 **
301 ** Description      Reconfigure the audio/video stream.
302 **                  If suspend is TRUE, this function tries the suspend/reconfigure
303 **                  procedure first.
304 **                  If suspend is FALSE or when suspend/reconfigure fails,
305 **                  this function closes and re-opens the AVDT connection.
306 **
307 ** Returns          void
308 **
309 *******************************************************************************/
BTA_AvReconfig(tBTA_AV_HNDL hndl,BOOLEAN suspend,UINT8 sep_info_idx,UINT8 * p_codec_info,UINT8 num_protect,UINT8 * p_protect_info)310 void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
311                     UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info)
312 {
313     tBTA_AV_API_RCFG  *p_buf;
314 
315     if ((p_buf = (tBTA_AV_API_RCFG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL)
316     {
317         p_buf->hdr.layer_specific   = hndl;
318         p_buf->hdr.event    = BTA_AV_API_RECONFIG_EVT;
319         p_buf->num_protect  = num_protect;
320         p_buf->suspend      = suspend;
321         p_buf->sep_info_idx = sep_info_idx;
322         p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
323         memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
324         memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
325         bta_sys_sendmsg(p_buf);
326     }
327 }
328 
329 /*******************************************************************************
330 **
331 ** Function         BTA_AvProtectReq
332 **
333 ** Description      Send a content protection request.  This function can only
334 **                  be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
335 **
336 ** Returns          void
337 **
338 *******************************************************************************/
BTA_AvProtectReq(tBTA_AV_HNDL hndl,UINT8 * p_data,UINT16 len)339 void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len)
340 {
341     tBTA_AV_API_PROTECT_REQ  *p_buf;
342 
343     if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL)
344     {
345         p_buf->hdr.layer_specific   = hndl;
346         p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
347         p_buf->len       = len;
348         if (p_data == NULL)
349         {
350             p_buf->p_data = NULL;
351         }
352         else
353         {
354             p_buf->p_data = (UINT8 *) (p_buf + 1);
355             memcpy(p_buf->p_data, p_data, len);
356         }
357         bta_sys_sendmsg(p_buf);
358     }
359 }
360 
361 /*******************************************************************************
362 **
363 ** Function         BTA_AvProtectRsp
364 **
365 ** Description      Send a content protection response.  This function must
366 **                  be called if a BTA_AV_PROTECT_REQ_EVT is received.
367 **                  This function can only be used if AV is enabled with
368 **                  feature BTA_AV_FEAT_PROTECT.
369 **
370 ** Returns          void
371 **
372 *******************************************************************************/
BTA_AvProtectRsp(tBTA_AV_HNDL hndl,UINT8 error_code,UINT8 * p_data,UINT16 len)373 void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len)
374 {
375     tBTA_AV_API_PROTECT_RSP  *p_buf;
376 
377     if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL)
378     {
379         p_buf->hdr.layer_specific   = hndl;
380         p_buf->hdr.event    = BTA_AV_API_PROTECT_RSP_EVT;
381         p_buf->len          = len;
382         p_buf->error_code   = error_code;
383         if (p_data == NULL)
384         {
385             p_buf->p_data = NULL;
386         }
387         else
388         {
389             p_buf->p_data = (UINT8 *) (p_buf + 1);
390             memcpy(p_buf->p_data, p_data, len);
391         }
392         bta_sys_sendmsg(p_buf);
393     }
394 }
395 
396 /*******************************************************************************
397 **
398 ** Function         BTA_AvRemoteCmd
399 **
400 ** Description      Send a remote control command.  This function can only
401 **                  be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
402 **
403 ** Returns          void
404 **
405 *******************************************************************************/
BTA_AvRemoteCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_RC rc_id,tBTA_AV_STATE key_state)406 void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state)
407 {
408     tBTA_AV_API_REMOTE_CMD  *p_buf;
409 
410     if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) GKI_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL)
411     {
412         p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
413         p_buf->hdr.layer_specific   = rc_handle;
414         p_buf->msg.op_id = rc_id;
415         p_buf->msg.state = key_state;
416         p_buf->msg.p_pass_data = NULL;
417         p_buf->msg.pass_len = 0;
418         p_buf->label = label;
419         bta_sys_sendmsg(p_buf);
420     }
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         BTA_AvVendorCmd
426 **
427 ** Description      Send a vendor dependent remote control command.  This
428 **                  function can only be used if AV is enabled with feature
429 **                  BTA_AV_FEAT_VENDOR.
430 **
431 ** Returns          void
432 **
433 *******************************************************************************/
BTA_AvVendorCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE cmd_code,UINT8 * p_data,UINT16 len)434 void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len)
435 {
436     tBTA_AV_API_VENDOR  *p_buf;
437 
438     if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
439     {
440         p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
441         p_buf->hdr.layer_specific   = rc_handle;
442         p_buf->msg.hdr.ctype = cmd_code;
443         p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
444         p_buf->msg.hdr.subunit_id = 0;
445         p_buf->msg.company_id = p_bta_av_cfg->company_id;
446         p_buf->label = label;
447         p_buf->msg.vendor_len = len;
448         if (p_data == NULL)
449         {
450             p_buf->msg.p_vendor_data = NULL;
451         }
452         else
453         {
454             p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
455             memcpy(p_buf->msg.p_vendor_data, p_data, len);
456         }
457         bta_sys_sendmsg(p_buf);
458     }
459 }
460 
461 /*******************************************************************************
462 **
463 ** Function         BTA_AvVendorRsp
464 **
465 ** Description      Send a vendor dependent remote control response.
466 **                  This function must be called if a BTA_AV_VENDOR_CMD_EVT
467 **                  is received. This function can only be used if AV is
468 **                  enabled with feature BTA_AV_FEAT_VENDOR.
469 **
470 ** Returns          void
471 **
472 *******************************************************************************/
BTA_AvVendorRsp(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE rsp_code,UINT8 * p_data,UINT16 len,UINT32 company_id)473 void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id)
474 {
475     tBTA_AV_API_VENDOR  *p_buf;
476 
477     if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
478     {
479         p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
480         p_buf->hdr.layer_specific   = rc_handle;
481         p_buf->msg.hdr.ctype = rsp_code;
482         p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
483         p_buf->msg.hdr.subunit_id = 0;
484         if(company_id)
485             p_buf->msg.company_id = company_id;
486         else
487             p_buf->msg.company_id = p_bta_av_cfg->company_id;
488         p_buf->label = label;
489         p_buf->msg.vendor_len = len;
490         if (p_data == NULL)
491         {
492             p_buf->msg.p_vendor_data = NULL;
493         }
494         else
495         {
496             p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
497             memcpy(p_buf->msg.p_vendor_data, p_data, len);
498         }
499         bta_sys_sendmsg(p_buf);
500     }
501 }
502 
503 /*******************************************************************************
504 **
505 ** Function         BTA_AvOpenRc
506 **
507 ** Description      Open an AVRCP connection toward the device with the
508 **                  specified handle
509 **
510 ** Returns          void
511 **
512 *******************************************************************************/
BTA_AvOpenRc(tBTA_AV_HNDL handle)513 void BTA_AvOpenRc(tBTA_AV_HNDL handle)
514 {
515     tBTA_AV_API_OPEN_RC  *p_buf;
516 
517     if ((p_buf = (tBTA_AV_API_OPEN_RC *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL)
518     {
519         p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
520         p_buf->hdr.layer_specific   = handle;
521         bta_sys_sendmsg(p_buf);
522     }
523 }
524 
525 /*******************************************************************************
526 **
527 ** Function         BTA_AvCloseRc
528 **
529 ** Description      Close an AVRCP connection
530 **
531 ** Returns          void
532 **
533 *******************************************************************************/
BTA_AvCloseRc(UINT8 rc_handle)534 void BTA_AvCloseRc(UINT8 rc_handle)
535 {
536     tBTA_AV_API_CLOSE_RC  *p_buf;
537 
538     if ((p_buf = (tBTA_AV_API_CLOSE_RC *) GKI_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL)
539     {
540         p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
541         p_buf->hdr.layer_specific   = rc_handle;
542         bta_sys_sendmsg(p_buf);
543     }
544 }
545 
546 /*******************************************************************************
547 **
548 ** Function         BTA_AvMetaRsp
549 **
550 ** Description      Send a Metadata/Advanced Control response. The message contained
551 **                  in p_pkt can be composed with AVRC utility functions.
552 **                  This function can only be used if AV is enabled with feature
553 **                  BTA_AV_FEAT_METADATA.
554 **
555 ** Returns          void
556 **
557 *******************************************************************************/
BTA_AvMetaRsp(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE rsp_code,BT_HDR * p_pkt)558 void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
559                                BT_HDR *p_pkt)
560 {
561     tBTA_AV_API_META_RSP  *p_buf;
562 
563     if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
564     {
565         p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
566         p_buf->hdr.layer_specific   = rc_handle;
567         p_buf->rsp_code = rsp_code;
568         p_buf->p_pkt = p_pkt;
569         p_buf->is_rsp = TRUE;
570         p_buf->label = label;
571 
572         bta_sys_sendmsg(p_buf);
573     } else if (p_pkt) {
574         GKI_freebuf(p_pkt);
575     }
576 }
577 
578 /*******************************************************************************
579 **
580 ** Function         BTA_AvMetaCmd
581 **
582 ** Description      Send a Metadata/Advanced Control command. The message contained
583 **                  in p_pkt can be composed with AVRC utility functions.
584 **                  This function can only be used if AV is enabled with feature
585 **                  BTA_AV_FEAT_METADATA.
586 **                  This message is sent only when the peer supports the TG role.
587 *8                  The only command makes sense right now is the absolute volume command.
588 **
589 ** Returns          void
590 **
591 *******************************************************************************/
BTA_AvMetaCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_CMD cmd_code,BT_HDR * p_pkt)592 void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt)
593 {
594     tBTA_AV_API_META_RSP  *p_buf;
595 
596     if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
597     {
598         p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
599         p_buf->hdr.layer_specific   = rc_handle;
600         p_buf->p_pkt = p_pkt;
601         p_buf->rsp_code = cmd_code;
602         p_buf->is_rsp = FALSE;
603         p_buf->label = label;
604 
605         bta_sys_sendmsg(p_buf);
606     }
607 }
608 
609 #endif /* BTA_AV_INCLUDED */
610