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