Home | History | Annotate | Download | only in avct
      1 /******************************************************************************
      2  *
      3  *  Copyright 2003-2016 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 module contains API of the audio/video control transport protocol.
     22  *
     23  ******************************************************************************/
     24 
     25 #include "avct_api.h"
     26 #include <string.h>
     27 #include "avct_int.h"
     28 #include "bt_common.h"
     29 #include "bt_target.h"
     30 #include "bt_types.h"
     31 #include "bt_utils.h"
     32 #include "btm_api.h"
     33 #include "l2c_api.h"
     34 #include "l2cdefs.h"
     35 #include "osi/include/osi.h"
     36 
     37 /* Control block for AVCT */
     38 tAVCT_CB avct_cb;
     39 
     40 /*******************************************************************************
     41  *
     42  * Function         AVCT_Register
     43  *
     44  * Description      This is the system level registration function for the
     45  *                  AVCTP protocol.  This function initializes AVCTP and
     46  *                  prepares the protocol stack for its use.  This function
     47  *                  must be called once by the system or platform using AVCTP
     48  *                  before the other functions of the API an be used.
     49  *
     50  *
     51  * Returns          void
     52  *
     53  ******************************************************************************/
     54 void AVCT_Register(uint16_t mtu, UNUSED_ATTR uint16_t mtu_br,
     55                    uint8_t sec_mask) {
     56   AVCT_TRACE_API("AVCT_Register");
     57 
     58   /* register PSM with L2CAP */
     59   L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_appl);
     60 
     61   /* set security level */
     62   BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0,
     63                        0);
     64   BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0,
     65                        0);
     66 
     67   /* initialize AVCTP data structures */
     68   memset(&avct_cb, 0, sizeof(tAVCT_CB));
     69 
     70   /* Include the browsing channel which uses eFCR */
     71   L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_br_appl);
     72 
     73   /* AVCTP browsing channel uses the same security service as AVCTP control
     74    * channel */
     75   BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM,
     76                        0, 0);
     77   BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_BR_PSM,
     78                        0, 0);
     79 
     80   if (mtu_br < AVCT_MIN_BROWSE_MTU) mtu_br = AVCT_MIN_BROWSE_MTU;
     81   avct_cb.mtu_br = mtu_br;
     82 
     83 #if defined(AVCT_INITIAL_TRACE_LEVEL)
     84   avct_cb.trace_level = AVCT_INITIAL_TRACE_LEVEL;
     85 #else
     86   avct_cb.trace_level = BT_TRACE_LEVEL_NONE;
     87 #endif
     88 
     89   if (mtu < AVCT_MIN_CONTROL_MTU) mtu = AVCT_MIN_CONTROL_MTU;
     90   /* store mtu */
     91   avct_cb.mtu = mtu;
     92 }
     93 
     94 /*******************************************************************************
     95  *
     96  * Function         AVCT_Deregister
     97  *
     98  * Description      This function is called to deregister use AVCTP protocol.
     99  *                  It is called when AVCTP is no longer being used by any
    100  *                  application in the system.  Before this function can be
    101  *                  called, all connections must be removed with
    102  *                  AVCT_RemoveConn().
    103  *
    104  *
    105  * Returns          void
    106  *
    107  ******************************************************************************/
    108 void AVCT_Deregister(void) {
    109   AVCT_TRACE_API("AVCT_Deregister");
    110 
    111   /* deregister PSM with L2CAP */
    112   L2CA_Deregister(AVCT_PSM);
    113 }
    114 
    115 /*******************************************************************************
    116  *
    117  * Function         AVCT_CreateConn
    118  *
    119  * Description      Create an AVCTP connection.  There are two types of
    120  *                  connections, initiator and acceptor, as determined by
    121  *                  the p_cc->role parameter.  When this function is called to
    122  *                  create an initiator connection, an AVCTP connection to
    123  *                  the peer device is initiated if one does not already exist.
    124  *                  If an acceptor connection is created, the connection waits
    125  *                  passively for an incoming AVCTP connection from a peer
    126  *                  device.
    127  *
    128  *
    129  * Returns          AVCT_SUCCESS if successful, otherwise error.
    130  *
    131  ******************************************************************************/
    132 uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc,
    133                          const RawAddress& peer_addr) {
    134   uint16_t result = AVCT_SUCCESS;
    135   tAVCT_CCB* p_ccb;
    136   tAVCT_LCB* p_lcb;
    137 
    138   AVCT_TRACE_API("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control);
    139 
    140   /* Allocate ccb; if no ccbs, return failure */
    141   p_ccb = avct_ccb_alloc(p_cc);
    142   if (p_ccb == NULL) {
    143     result = AVCT_NO_RESOURCES;
    144   } else {
    145     /* get handle */
    146     *p_handle = avct_ccb_to_idx(p_ccb);
    147 
    148     /* if initiator connection */
    149     if (p_cc->role == AVCT_INT) {
    150       /* find link; if none allocate a new one */
    151       p_lcb = avct_lcb_by_bd(peer_addr);
    152       if (p_lcb == NULL) {
    153         p_lcb = avct_lcb_alloc(peer_addr);
    154         if (p_lcb == NULL) {
    155           /* no link resources; free ccb as well */
    156           avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
    157           result = AVCT_NO_RESOURCES;
    158         }
    159       }
    160       /* check if PID already in use */
    161       else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) {
    162         avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
    163         result = AVCT_PID_IN_USE;
    164       }
    165 
    166       if (result == AVCT_SUCCESS) {
    167         /* bind lcb to ccb */
    168         p_ccb->p_lcb = p_lcb;
    169         AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
    170         tAVCT_LCB_EVT avct_lcb_evt;
    171         avct_lcb_evt.p_ccb = p_ccb;
    172         avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
    173       }
    174     }
    175   }
    176   return result;
    177 }
    178 
    179 /*******************************************************************************
    180  *
    181  * Function         AVCT_RemoveConn
    182  *
    183  * Description      Remove an AVCTP connection.  This function is called when
    184  *                  the application is no longer using a connection.  If this
    185  *                  is the last connection to a peer the L2CAP channel for AVCTP
    186  *                  will be closed.
    187  *
    188  *
    189  * Returns          AVCT_SUCCESS if successful, otherwise error.
    190  *
    191  ******************************************************************************/
    192 uint16_t AVCT_RemoveConn(uint8_t handle) {
    193   uint16_t result = AVCT_SUCCESS;
    194   tAVCT_CCB* p_ccb;
    195 
    196   AVCT_TRACE_API("AVCT_RemoveConn");
    197 
    198   /* map handle to ccb */
    199   p_ccb = avct_ccb_by_idx(handle);
    200   if (p_ccb == NULL) {
    201     result = AVCT_BAD_HANDLE;
    202   }
    203   /* if connection not bound to lcb, dealloc */
    204   else if (p_ccb->p_lcb == NULL) {
    205     avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
    206   }
    207   /* send unbind event to lcb */
    208   else {
    209     tAVCT_LCB_EVT avct_lcb_evt;
    210     avct_lcb_evt.p_ccb = p_ccb;
    211     avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
    212   }
    213   return result;
    214 }
    215 
    216 /*******************************************************************************
    217  *
    218  * Function         AVCT_CreateBrowse
    219  *
    220  * Description      Create an AVCTP Browse channel.  There are two types of
    221  *                  connections, initiator and acceptor, as determined by
    222  *                  the role parameter.  When this function is called to
    223  *                  create an initiator connection, the Browse channel to
    224  *                  the peer device is initiated if one does not already exist.
    225  *                  If an acceptor connection is created, the connection waits
    226  *                  passively for an incoming AVCTP connection from a peer
    227  *                  device.
    228  *
    229  *
    230  * Returns          AVCT_SUCCESS if successful, otherwise error.
    231  *
    232  ******************************************************************************/
    233 uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
    234   uint16_t result = AVCT_SUCCESS;
    235   tAVCT_CCB* p_ccb;
    236   tAVCT_BCB* p_bcb;
    237   int index;
    238 
    239   AVCT_TRACE_API("AVCT_CreateBrowse: %d", role);
    240 
    241   /* map handle to ccb */
    242   p_ccb = avct_ccb_by_idx(handle);
    243   if (p_ccb == NULL) {
    244     return AVCT_BAD_HANDLE;
    245   } else {
    246     /* mark this CCB as supporting browsing channel */
    247     if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
    248       p_ccb->allocated |= AVCT_ALOC_BCB;
    249     }
    250   }
    251 
    252   /* if initiator connection */
    253   if (role == AVCT_INT) {
    254     /* the link control block must exist before this function is called as INT.
    255      */
    256     if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
    257       result = AVCT_NOT_OPEN;
    258     } else {
    259       /* find link; if none allocate a new one */
    260       index = p_ccb->p_lcb->allocated;
    261       if (index > AVCT_NUM_LINKS) {
    262         result = AVCT_BAD_HANDLE;
    263       } else {
    264         p_bcb = &avct_cb.bcb[index - 1];
    265         p_bcb->allocated = index;
    266       }
    267     }
    268 
    269     if (result == AVCT_SUCCESS) {
    270       /* bind bcb to ccb */
    271       p_ccb->p_bcb = p_bcb;
    272       p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
    273       AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state);
    274       tAVCT_LCB_EVT avct_lcb_evt;
    275       avct_lcb_evt.p_ccb = p_ccb;
    276       avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
    277     }
    278   }
    279 
    280   return result;
    281 }
    282 
    283 /*******************************************************************************
    284  *
    285  * Function         AVCT_RemoveBrowse
    286  *
    287  * Description      Remove an AVCTP Browse channel.  This function is called
    288  *                  when the application is no longer using a connection.  If
    289  *                  this is the last connection to a peer the L2CAP channel for
    290  *                  AVCTP will be closed.
    291  *
    292  *
    293  * Returns          AVCT_SUCCESS if successful, otherwise error.
    294  *
    295  ******************************************************************************/
    296 uint16_t AVCT_RemoveBrowse(uint8_t handle) {
    297   uint16_t result = AVCT_SUCCESS;
    298   tAVCT_CCB* p_ccb;
    299 
    300   AVCT_TRACE_API("AVCT_RemoveBrowse");
    301 
    302   /* map handle to ccb */
    303   p_ccb = avct_ccb_by_idx(handle);
    304   if (p_ccb == NULL) {
    305     result = AVCT_BAD_HANDLE;
    306   } else if (p_ccb->p_bcb != NULL)
    307   /* send unbind event to bcb */
    308   {
    309     tAVCT_LCB_EVT avct_lcb_evt;
    310     avct_lcb_evt.p_ccb = p_ccb;
    311     avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
    312   }
    313 
    314   return result;
    315 }
    316 
    317 /*******************************************************************************
    318  *
    319  * Function         AVCT_GetBrowseMtu
    320  *
    321  * Description      Get the peer_mtu for the AVCTP Browse channel of the given
    322  *                  connection.
    323  *
    324  * Returns          the peer browsing channel MTU.
    325  *
    326  ******************************************************************************/
    327 uint16_t AVCT_GetBrowseMtu(uint8_t handle) {
    328   uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU;
    329 
    330   tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
    331 
    332   if (p_ccb != NULL && p_ccb->p_bcb != NULL) {
    333     peer_mtu = p_ccb->p_bcb->peer_mtu;
    334   }
    335 
    336   return peer_mtu;
    337 }
    338 
    339 /*******************************************************************************
    340  *
    341  * Function         AVCT_GetPeerMtu
    342  *
    343  * Description      Get the peer_mtu for the AVCTP channel of the given
    344  *                  connection.
    345  *
    346  * Returns          the peer MTU size.
    347  *
    348  ******************************************************************************/
    349 uint16_t AVCT_GetPeerMtu(uint8_t handle) {
    350   uint16_t peer_mtu = L2CAP_DEFAULT_MTU;
    351   tAVCT_CCB* p_ccb;
    352 
    353   /* map handle to ccb */
    354   p_ccb = avct_ccb_by_idx(handle);
    355   if (p_ccb != NULL) {
    356     if (p_ccb->p_lcb) {
    357       peer_mtu = p_ccb->p_lcb->peer_mtu;
    358     }
    359   }
    360 
    361   return peer_mtu;
    362 }
    363 
    364 /*******************************************************************************
    365  *
    366  * Function         AVCT_MsgReq
    367  *
    368  * Description      Send an AVCTP message to a peer device.  In calling
    369  *                  AVCT_MsgReq(), the application should keep track of the
    370  *                  congestion state of AVCTP as communicated with events
    371  *                  AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT.   If the
    372  *                  application calls AVCT_MsgReq() when AVCTP is congested
    373  *                  the message may be discarded.  The application may make its
    374  *                  first call to AVCT_MsgReq() after it receives an
    375  *                  AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control
    376  *                  channel or AVCT_BROWSE_CONN_CFM_EVT or
    377  *                  AVCT_BROWSE_CONN_IND_EVT on browsing channel.
    378  *
    379  *                  p_msg->layer_specific must be set to
    380  *                  AVCT_DATA_CTRL for control channel traffic;
    381  *                  AVCT_DATA_BROWSE for for browse channel traffic.
    382  *
    383  * Returns          AVCT_SUCCESS if successful, otherwise error.
    384  *
    385  ******************************************************************************/
    386 uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
    387   uint16_t result = AVCT_SUCCESS;
    388   tAVCT_CCB* p_ccb;
    389   tAVCT_UL_MSG ul_msg;
    390 
    391   AVCT_TRACE_API("%s", __func__);
    392 
    393   /* verify p_msg parameter */
    394   if (p_msg == NULL) {
    395     return AVCT_NO_RESOURCES;
    396   }
    397   AVCT_TRACE_API("%s len: %d layer_specific: %d", __func__, p_msg->len,
    398                  p_msg->layer_specific);
    399 
    400   /* map handle to ccb */
    401   p_ccb = avct_ccb_by_idx(handle);
    402   if (p_ccb == NULL) {
    403     result = AVCT_BAD_HANDLE;
    404     osi_free(p_msg);
    405   }
    406   /* verify channel is bound to link */
    407   else if (p_ccb->p_lcb == NULL) {
    408     result = AVCT_NOT_OPEN;
    409     osi_free(p_msg);
    410   }
    411 
    412   if (result == AVCT_SUCCESS) {
    413     ul_msg.p_buf = p_msg;
    414     ul_msg.p_ccb = p_ccb;
    415     ul_msg.label = label;
    416     ul_msg.cr = cr;
    417 
    418     /* send msg event to bcb */
    419     if (p_msg->layer_specific == AVCT_DATA_BROWSE) {
    420       if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
    421         /* BCB channel is not open and not allocated */
    422         result = AVCT_BAD_HANDLE;
    423         osi_free(p_msg);
    424       } else {
    425         p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
    426         tAVCT_LCB_EVT avct_lcb_evt;
    427         avct_lcb_evt.ul_msg = ul_msg;
    428         avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
    429       }
    430     }
    431     /* send msg event to lcb */
    432     else {
    433       tAVCT_LCB_EVT avct_lcb_evt;
    434       avct_lcb_evt.ul_msg = ul_msg;
    435       avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
    436     }
    437   }
    438   return result;
    439 }
    440