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