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