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