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