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  *  Name:           avct_bcb_act.cc
     22  *
     23  *  Description:    This module contains action functions of the browsing
     24  *                  control state machine.
     25  *
     26  *****************************************************************************/
     27 
     28 #include <log/log.h>
     29 #include <string.h>
     30 #include "avct_api.h"
     31 #include "avct_int.h"
     32 #include "bt_target.h"
     33 #include "bt_utils.h"
     34 #include "btm_api.h"
     35 #include "osi/include/osi.h"
     36 
     37 /* action function list */
     38 const tAVCT_BCB_ACTION avct_bcb_action[] = {
     39     avct_bcb_chnl_open,   /* AVCT_LCB_CHNL_OPEN */
     40     avct_bcb_chnl_disc,   /* AVCT_LCB_CHNL_DISC */
     41     avct_bcb_send_msg,    /* AVCT_LCB_SEND_MSG */
     42     avct_bcb_open_ind,    /* AVCT_LCB_OPEN_IND */
     43     avct_bcb_open_fail,   /* AVCT_LCB_OPEN_FAIL */
     44     avct_bcb_close_ind,   /* AVCT_LCB_CLOSE_IND */
     45     avct_bcb_close_cfm,   /* AVCT_LCB_CLOSE_CFM */
     46     avct_bcb_msg_ind,     /* AVCT_LCB_MSG_IND */
     47     avct_bcb_cong_ind,    /* AVCT_LCB_CONG_IND */
     48     avct_bcb_bind_conn,   /* AVCT_LCB_BIND_CONN */
     49     avct_bcb_bind_fail,   /* AVCT_LCB_BIND_FAIL */
     50     avct_bcb_unbind_disc, /* AVCT_LCB_UNBIND_DISC */
     51     avct_bcb_chk_disc,    /* AVCT_LCB_CHK_DISC */
     52     avct_bcb_discard_msg, /* AVCT_LCB_DISCARD_MSG */
     53     avct_bcb_dealloc,     /* AVCT_LCB_DEALLOC */
     54     avct_bcb_free_msg_ind /* AVCT_LCB_FREE_MSG_IND */
     55 };
     56 
     57 /*******************************************************************************
     58  *
     59  * Function         avct_bcb_msg_asmbl
     60  *
     61  * Description      Reassemble incoming message.
     62  *
     63  *
     64  * Returns          Pointer to reassembled message;  NULL if no message
     65  *                  available.
     66  *
     67  ******************************************************************************/
     68 static BT_HDR* avct_bcb_msg_asmbl(UNUSED_ATTR tAVCT_BCB* p_bcb, BT_HDR* p_buf) {
     69   uint8_t* p;
     70   uint8_t pkt_type;
     71 
     72   if (p_buf->len == 0) {
     73     osi_free_and_reset((void**)&p_buf);
     74     android_errorWriteLog(0x534e4554, "79944113");
     75     return nullptr;
     76   }
     77 
     78   /* parse the message header */
     79   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
     80   pkt_type = AVCT_PKT_TYPE(p);
     81 
     82   /* must be single packet - can not fragment */
     83   if (pkt_type != AVCT_PKT_TYPE_SINGLE) {
     84     osi_free_and_reset((void**)&p_buf);
     85     AVCT_TRACE_WARNING("Pkt type=%d - fragmentation not allowed. drop it",
     86                        pkt_type);
     87   }
     88   return p_buf;
     89 }
     90 
     91 /*******************************************************************************
     92  *
     93  * Function         avct_bcb_chnl_open
     94  *
     95  * Description      Open L2CAP channel to peer
     96  *
     97  *
     98  * Returns          Nothing.
     99  *
    100  ******************************************************************************/
    101 void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
    102   uint16_t result = AVCT_RESULT_FAIL;
    103   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
    104   tL2CAP_ERTM_INFO ertm_info;
    105 
    106   BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP_BROWSE, 0);
    107 
    108   /* Set the FCR options: Browsing channel mandates ERTM */
    109   ertm_info.preferred_mode = avct_l2c_br_fcr_opts_def.mode;
    110   ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM;
    111   ertm_info.user_rx_buf_size = BT_DEFAULT_BUFFER_SIZE;
    112   ertm_info.user_tx_buf_size = BT_DEFAULT_BUFFER_SIZE;
    113   ertm_info.fcr_rx_buf_size = BT_DEFAULT_BUFFER_SIZE;
    114   ertm_info.fcr_tx_buf_size = BT_DEFAULT_BUFFER_SIZE;
    115 
    116   /* call l2cap connect req */
    117   p_bcb->ch_state = AVCT_CH_CONN;
    118   p_bcb->ch_lcid =
    119       L2CA_ErtmConnectReq(AVCT_BR_PSM, p_lcb->peer_addr, &ertm_info);
    120   if (p_bcb->ch_lcid == 0) {
    121     /* if connect req failed, send ourselves close event */
    122     tAVCT_LCB_EVT avct_lcb_evt;
    123     avct_lcb_evt.result = result;
    124     avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
    125   }
    126 }
    127 
    128 /*******************************************************************************
    129  *
    130  * Function         avct_bcb_unbind_disc
    131  *
    132  * Description      call callback with disconnect event.
    133  *
    134  *
    135  * Returns          Nothing.
    136  *
    137  ******************************************************************************/
    138 void avct_bcb_unbind_disc(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    139   p_data->p_ccb->p_bcb = NULL;
    140   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
    141                                     AVCT_BROWSE_DISCONN_CFM_EVT, 0, NULL);
    142 }
    143 
    144 /*******************************************************************************
    145  *
    146  * Function         avct_bcb_open_ind
    147  *
    148  * Description      Handle an LL_OPEN event.
    149  *                  For the allocated ccb already bound to the bcb, send a
    150  *                  connect event. For the unbound ccb with a new PID, bind that
    151  *                  ccb to the bcb with the same bd_addr and send a connect
    152  *                  event.
    153  *
    154  *
    155  * Returns          Nothing.
    156  *
    157  ******************************************************************************/
    158 void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    159   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    160   tAVCT_CCB* p_ccb_bind = NULL;
    161   bool bind = false;
    162   tAVCT_UL_MSG ul_msg;
    163 
    164   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    165     /* if ccb allocated and */
    166     if (p_ccb->allocated) {
    167       /* if bound to this bcb send connect confirm event */
    168       if (p_ccb->p_bcb == p_bcb) {
    169         bind = true;
    170         p_ccb_bind = p_ccb;
    171         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT,
    172                                0, &p_ccb->p_lcb->peer_addr);
    173       }
    174       /* if unbound acceptor and lcb allocated and bd_addr are the same for bcb
    175          and lcb */
    176       else if ((p_ccb->p_bcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
    177                (p_ccb->p_lcb != NULL) &&
    178                p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
    179         /* bind bcb to ccb and send connect ind event */
    180         bind = true;
    181         p_ccb_bind = p_ccb;
    182         p_ccb->p_bcb = p_bcb;
    183         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT,
    184                                0, &p_ccb->p_lcb->peer_addr);
    185       }
    186     }
    187   }
    188 
    189   /* if no ccbs bound to this lcb, disconnect */
    190   if (!bind) {
    191     avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
    192     return;
    193   }
    194 
    195   if (!p_bcb->p_tx_msg || !p_ccb_bind) {
    196     return;
    197   }
    198 
    199   ul_msg.p_buf = p_bcb->p_tx_msg;
    200   ul_msg.p_ccb = p_ccb_bind;
    201   ul_msg.label = (uint8_t)(p_bcb->p_tx_msg->layer_specific & 0xFF);
    202   ul_msg.cr = (uint8_t)((p_bcb->p_tx_msg->layer_specific & 0xFF00) >> 8);
    203   p_bcb->p_tx_msg->layer_specific = AVCT_DATA_BROWSE;
    204   p_bcb->p_tx_msg = NULL;
    205 
    206   /* send msg event to bcb */
    207   tAVCT_LCB_EVT avct_lcb_evt;
    208   avct_lcb_evt.ul_msg = ul_msg;
    209   avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
    210 }
    211 
    212 /*******************************************************************************
    213  *
    214  * Function         avct_bcb_open_fail
    215  *
    216  * Description      L2CAP channel open attempt failed.  Mark the ccbs
    217  *                  as NULL bcb.
    218  *
    219  *
    220  * Returns          Nothing.
    221  *
    222  ******************************************************************************/
    223 void avct_bcb_open_fail(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
    224   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    225 
    226   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    227     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
    228       p_ccb->p_bcb = NULL;
    229     }
    230   }
    231 }
    232 
    233 /*******************************************************************************
    234  *
    235  * Function         avct_bcb_close_ind
    236  *
    237  * Description      L2CAP channel closed by peer.  Deallocate any initiator
    238  *                  ccbs on this lcb and send disconnect ind event.
    239  *
    240  *
    241  * Returns          Nothing.
    242  *
    243  ******************************************************************************/
    244 void avct_bcb_close_ind(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
    245   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    246   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
    247 
    248   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    249     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
    250       if (p_ccb->cc.role == AVCT_INT) {
    251         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
    252                                   AVCT_BROWSE_DISCONN_CFM_EVT, 0,
    253                                   &p_lcb->peer_addr);
    254       } else {
    255         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
    256                                   AVCT_BROWSE_DISCONN_IND_EVT, 0, NULL);
    257       }
    258       p_ccb->p_bcb = NULL;
    259     }
    260   }
    261 }
    262 
    263 /*******************************************************************************
    264  *
    265  * Function         avct_bcb_close_cfm
    266  *
    267  * Description      L2CAP channel closed by us.  Deallocate any initiator
    268  *                  ccbs on this lcb and send disconnect ind or cfm event.
    269  *
    270  *
    271  * Returns          Nothing.
    272  *
    273  ******************************************************************************/
    274 void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    275   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    276   uint8_t event = 0;
    277   /* Whether BCB initiated channel close */
    278   bool ch_close = p_bcb->ch_close;
    279   tAVCT_CTRL_CBACK* p_cback;
    280 
    281   p_bcb->ch_close = false;
    282   p_bcb->allocated = 0;
    283   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    284     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
    285       /* if this ccb initiated close send disconnect cfm otherwise ind */
    286       if (ch_close) {
    287         event = AVCT_BROWSE_DISCONN_CFM_EVT;
    288       } else {
    289         event = AVCT_BROWSE_DISCONN_IND_EVT;
    290       }
    291 
    292       p_cback = p_ccb->cc.p_ctrl_cback;
    293       p_ccb->p_bcb = NULL;
    294       if (p_ccb->p_lcb == NULL) avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
    295       (*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
    296                  &p_bcb->peer_addr);
    297     }
    298   }
    299 }
    300 
    301 /*******************************************************************************
    302  *
    303  * Function         avct_bcb_bind_conn
    304  *
    305  * Description      Bind ccb to lcb and send connect cfm event.
    306  *
    307  *
    308  * Returns          Nothing.
    309  *
    310  ******************************************************************************/
    311 void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    312   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
    313   p_data->p_ccb->p_bcb = p_bcb;
    314   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
    315                                     AVCT_BROWSE_CONN_CFM_EVT, 0,
    316                                     &p_lcb->peer_addr);
    317 }
    318 
    319 /*******************************************************************************
    320  *
    321  * Function         avct_bcb_chk_disc
    322  *
    323  * Description      A ccb wants to close; if it is the last ccb on this lcb,
    324  *                  close channel.  Otherwise just deallocate and call
    325  *                  callback.
    326  *
    327  *
    328  * Returns          Nothing.
    329  *
    330  ******************************************************************************/
    331 void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    332   p_bcb->ch_close = avct_bcb_get_last_ccb_index(p_bcb, p_data->p_ccb);
    333   if (p_bcb->ch_close) {
    334     avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
    335     return;
    336   }
    337 
    338   avct_bcb_unbind_disc(p_bcb, p_data);
    339 }
    340 
    341 /*******************************************************************************
    342  *
    343  * Function         avct_bcb_chnl_disc
    344  *
    345  * Description      Disconnect L2CAP channel.
    346  *
    347  *
    348  * Returns          Nothing.
    349  *
    350  ******************************************************************************/
    351 void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
    352   L2CA_DisconnectReq(p_bcb->ch_lcid);
    353 }
    354 
    355 /*******************************************************************************
    356  *
    357  * Function         avct_bcb_bind_fail
    358  *
    359  * Description      Deallocate ccb and call callback with connect event
    360  *                  with failure result.
    361  *
    362  *
    363  * Returns          Nothing.
    364  *
    365  ******************************************************************************/
    366 void avct_bcb_bind_fail(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    367   p_data->p_ccb->p_bcb = NULL;
    368   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
    369                                     AVCT_BROWSE_CONN_CFM_EVT, AVCT_RESULT_FAIL,
    370                                     NULL);
    371 }
    372 
    373 /*******************************************************************************
    374  *
    375  * Function         avct_bcb_cong_ind
    376  *
    377  * Description      Handle congestion indication from L2CAP.
    378  *
    379  *
    380  * Returns          Nothing.
    381  *
    382  ******************************************************************************/
    383 void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    384   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    385   uint8_t event;
    386   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
    387 
    388   /* set event */
    389   event =
    390       (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;
    391 
    392   /* send event to all ccbs on this lcb */
    393   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    394     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
    395       (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
    396                                 &p_lcb->peer_addr);
    397     }
    398   }
    399 }
    400 
    401 /*******************************************************************************
    402  *
    403  * Function         avct_bcb_discard_msg
    404  *
    405  * Description      Discard a message sent in from the API.
    406  *
    407  *
    408  * Returns          Nothing.
    409  *
    410  ******************************************************************************/
    411 void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    412   osi_free_and_reset((void**)&p_bcb->p_tx_msg);
    413 
    414   /* if control channel is up, save the message and open the browsing channel */
    415   if (p_data->ul_msg.p_ccb->p_lcb == NULL) {
    416     osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
    417     return;
    418   }
    419   p_bcb->p_tx_msg = p_data->ul_msg.p_buf;
    420 
    421   if (p_bcb->p_tx_msg) {
    422     p_bcb->p_tx_msg->layer_specific =
    423         (p_data->ul_msg.cr << 8) + p_data->ul_msg.label;
    424 
    425     /* the channel is closed, opening or closing - open it again */
    426     AVCT_TRACE_DEBUG("ch_state: %d, allocated:%d->%d", p_bcb->ch_state,
    427                      p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated);
    428     p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated;
    429     avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT,
    430                    (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb);
    431   }
    432 }
    433 
    434 /*******************************************************************************
    435  *
    436  * Function         avct_bcb_send_msg
    437  *
    438  * Description      Build and send an AVCTP message.
    439  *
    440  *
    441  * Returns          Nothing.
    442  *
    443  ******************************************************************************/
    444 void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    445   uint16_t curr_msg_len;
    446   uint8_t pkt_type = AVCT_PKT_TYPE_SINGLE;
    447   uint8_t hdr_len;
    448   BT_HDR* p_buf;
    449   uint8_t* p;
    450 
    451   /* store msg len */
    452   curr_msg_len = p_data->ul_msg.p_buf->len;
    453 
    454   /* initialize packet type and other stuff */
    455   if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
    456     AVCT_TRACE_ERROR("%s msg len (%d) exceeds peer mtu(%d-%d)!!", __func__,
    457                      curr_msg_len, p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE);
    458     osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
    459     return;
    460   }
    461 
    462   /* set header len */
    463   hdr_len = avct_lcb_pkt_type_len[pkt_type];
    464   p_buf = p_data->ul_msg.p_buf;
    465 
    466   /* set up to build header */
    467   p_buf->len += hdr_len;
    468   p_buf->offset -= hdr_len;
    469   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
    470 
    471   /* build header */
    472   AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
    473   UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
    474 
    475   p_buf->layer_specific = AVCT_DATA_BROWSE;
    476 
    477   /* send message to L2CAP */
    478   L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
    479 }
    480 
    481 /*******************************************************************************
    482  *
    483  * Function         avct_bcb_free_msg_ind
    484  *
    485  * Description      Discard an incoming AVCTP message.
    486  *
    487  *
    488  * Returns          Nothing.
    489  *
    490  ******************************************************************************/
    491 void avct_bcb_free_msg_ind(UNUSED_ATTR tAVCT_BCB* p_bcb,
    492                            tAVCT_LCB_EVT* p_data) {
    493   if (p_data) osi_free_and_reset((void**)&p_data->p_buf);
    494 }
    495 
    496 /*******************************************************************************
    497  *
    498  * Function         avct_bcb_msg_ind
    499  *
    500  * Description      Handle an incoming AVCTP message.
    501  *
    502  *
    503  * Returns          Nothing.
    504  *
    505  ******************************************************************************/
    506 void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
    507   uint8_t* p;
    508   uint8_t label, type, cr_ipid;
    509   uint16_t pid;
    510   tAVCT_CCB* p_ccb;
    511   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
    512 
    513   if ((p_data == NULL) || (p_data->p_buf == NULL)) {
    514     AVCT_TRACE_WARNING("%s p_data is NULL, returning!", __func__);
    515     return;
    516   }
    517 
    518   /* this p_buf is to be reported through p_msg_cback. The layer_specific
    519    * needs to be set properly to indicate that it is received through
    520    * browsing channel */
    521   p_data->p_buf->layer_specific = AVCT_DATA_BROWSE;
    522 
    523   /* reassemble message; if no message available (we received a fragment) return
    524    */
    525   p_data->p_buf = avct_bcb_msg_asmbl(p_bcb, p_data->p_buf);
    526   if (p_data->p_buf == NULL) {
    527     return;
    528   }
    529 
    530   if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
    531     AVCT_TRACE_WARNING("Invalid AVCTP packet length %d: must be at least %d",
    532                        p_data->p_buf->len, AVCT_HDR_LEN_SINGLE);
    533     osi_free_and_reset((void**)&p_data->p_buf);
    534     android_errorWriteLog(0x534e4554, "79944113");
    535     return;
    536   }
    537 
    538   p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;
    539 
    540   /* parse header byte */
    541   AVCT_PARSE_HDR(p, label, type, cr_ipid);
    542 
    543   /* check for invalid cr_ipid */
    544   if (cr_ipid == AVCT_CR_IPID_INVALID) {
    545     AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
    546     osi_free_and_reset((void**)&p_data->p_buf);
    547     return;
    548   }
    549 
    550   /* parse and lookup PID */
    551   BE_STREAM_TO_UINT16(pid, p);
    552   p_ccb = avct_lcb_has_pid(p_lcb, pid);
    553   if (p_ccb) {
    554     /* PID found; send msg up, adjust bt hdr and call msg callback */
    555     p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
    556     p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
    557     (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid,
    558                              p_data->p_buf);
    559     return;
    560   }
    561 
    562   /* PID not found; drop message */
    563   AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
    564   osi_free_and_reset((void**)&p_data->p_buf);
    565 
    566   /* if command send reject */
    567   if (cr_ipid == AVCT_CMD) {
    568     BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVRC_CMD_BUF_SIZE);
    569     p_buf->len = AVCT_HDR_LEN_SINGLE;
    570     p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
    571     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
    572     AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
    573     UINT16_TO_BE_STREAM(p, pid);
    574     p_buf->layer_specific = AVCT_DATA_BROWSE;
    575     L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
    576   }
    577 }
    578 
    579 /*******************************************************************************
    580  *
    581  * Function         avct_bcb_dealloc
    582  *
    583  * Description      Deallocate a browse control block.
    584  *
    585  *
    586  * Returns          void.
    587  *
    588  ******************************************************************************/
    589 void avct_bcb_dealloc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
    590   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    591 
    592   AVCT_TRACE_DEBUG("%s %d", __func__, p_bcb->allocated);
    593 
    594   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    595     /* if ccb allocated and */
    596     if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) {
    597       p_ccb->p_bcb = NULL;
    598       AVCT_TRACE_DEBUG("%s used by ccb: %d", __func__, idx);
    599       break;
    600     }
    601   }
    602 
    603   /* the browsing channel is down. Check if we have pending messages */
    604   osi_free_and_reset((void**)&p_bcb->p_tx_msg);
    605   memset(p_bcb, 0, sizeof(tAVCT_BCB));
    606 }
    607 
    608 /*******************************************************************************
    609  *
    610  * Function         avct_close_bcb
    611  *
    612  * Description      this function is called right before LCB disconnects.
    613  *
    614  *
    615  * Returns          Nothing.
    616  *
    617  ******************************************************************************/
    618 void avct_close_bcb(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
    619   tAVCT_BCB* p_bcb = avct_bcb_by_lcb(p_lcb);
    620   if (p_bcb->allocated) {
    621     avct_bcb_event(p_bcb, AVCT_LCB_UL_UNBIND_EVT, p_data);
    622   }
    623 }
    624 
    625 /*******************************************************************************
    626  *
    627  * Function         avct_lcb_by_bcb
    628  *
    629  * Description      This lookup function finds the lcb for a bcb.
    630  *
    631  * Returns          pointer to the lcb.
    632  *
    633  ******************************************************************************/
    634 tAVCT_LCB* avct_lcb_by_bcb(tAVCT_BCB* p_bcb) {
    635   return &avct_cb.lcb[p_bcb->allocated - 1];
    636 }
    637 
    638 /*******************************************************************************
    639  *
    640  * Function         avct_bcb_by_lcb
    641  *
    642  * Description      This lookup function finds the bcb for a lcb.
    643  *
    644  * Returns          pointer to the lcb.
    645  *
    646  ******************************************************************************/
    647 tAVCT_BCB* avct_bcb_by_lcb(tAVCT_LCB* p_lcb) {
    648   return &avct_cb.bcb[p_lcb->allocated - 1];
    649 }
    650 
    651 /*******************************************************************************
    652  *
    653  * Function         avct_bcb_get_last_ccb_index
    654  *
    655  * Description      See if given ccb is only one on the bcb.
    656  *
    657  *
    658  * Returns          0, if ccb is last,  (ccb index + 1) otherwise.
    659  *
    660  ******************************************************************************/
    661 uint8_t avct_bcb_get_last_ccb_index(tAVCT_BCB* p_bcb, tAVCT_CCB* p_ccb_last) {
    662   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
    663   uint8_t idx = 0;
    664 
    665   for (int i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
    666     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
    667       if (p_ccb != p_ccb_last) return 0;
    668       idx = (uint8_t)(i + 1);
    669     }
    670   }
    671   return idx;
    672 }
    673 
    674 /*******************************************************************************
    675  *
    676  * Function         avct_bcb_by_lcid
    677  *
    678  * Description      Find the BCB associated with the L2CAP LCID
    679  *
    680  *
    681  * Returns          pointer to the lcb, or NULL if none found.
    682  *
    683  ******************************************************************************/
    684 tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
    685   tAVCT_BCB* p_bcb = &avct_cb.bcb[0];
    686   int idx;
    687 
    688   for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
    689     if (p_bcb->allocated && (p_bcb->ch_lcid == lcid)) {
    690       return p_bcb;
    691     }
    692   }
    693 
    694   /* out of lcbs */
    695   AVCT_TRACE_WARNING("No bcb for lcid %x", lcid);
    696   return NULL;
    697 }
    698