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