/******************************************************************************
 *
 *  Copyright 2003-2016 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/*****************************************************************************
 *
 *  Name:           avct_bcb_act.cc
 *
 *  Description:    This module contains action functions of the browsing
 *                  control state machine.
 *
 *****************************************************************************/

#define LOG_TAG "bluetooth"

#include <string.h>

#include "avct_api.h"
#include "avct_int.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bta/include/bta_api.h"
#include "btm_api.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/bt_hdr.h"

/* action function list */
const tAVCT_BCB_ACTION avct_bcb_action[] = {
    avct_bcb_chnl_open,   /* AVCT_LCB_CHNL_OPEN */
    avct_bcb_chnl_disc,   /* AVCT_LCB_CHNL_DISC */
    avct_bcb_send_msg,    /* AVCT_LCB_SEND_MSG */
    avct_bcb_open_ind,    /* AVCT_LCB_OPEN_IND */
    avct_bcb_open_fail,   /* AVCT_LCB_OPEN_FAIL */
    avct_bcb_close_ind,   /* AVCT_LCB_CLOSE_IND */
    avct_bcb_close_cfm,   /* AVCT_LCB_CLOSE_CFM */
    avct_bcb_msg_ind,     /* AVCT_LCB_MSG_IND */
    avct_bcb_cong_ind,    /* AVCT_LCB_CONG_IND */
    avct_bcb_bind_conn,   /* AVCT_LCB_BIND_CONN */
    avct_bcb_bind_fail,   /* AVCT_LCB_BIND_FAIL */
    avct_bcb_unbind_disc, /* AVCT_LCB_UNBIND_DISC */
    avct_bcb_chk_disc,    /* AVCT_LCB_CHK_DISC */
    avct_bcb_discard_msg, /* AVCT_LCB_DISCARD_MSG */
    avct_bcb_dealloc,     /* AVCT_LCB_DEALLOC */
    avct_bcb_free_msg_ind /* AVCT_LCB_FREE_MSG_IND */
};

/*******************************************************************************
 *
 * Function         avct_bcb_msg_asmbl
 *
 * Description      Reassemble incoming message.
 *
 *
 * Returns          Pointer to reassembled message;  NULL if no message
 *                  available.
 *
 ******************************************************************************/
static BT_HDR* avct_bcb_msg_asmbl(UNUSED_ATTR tAVCT_BCB* p_bcb, BT_HDR* p_buf) {
  uint8_t* p;
  uint8_t pkt_type;

  if (p_buf->len == 0) {
    osi_free_and_reset((void**)&p_buf);
    android_errorWriteLog(0x534e4554, "79944113");
    return nullptr;
  }

  /* parse the message header */
  p = (uint8_t*)(p_buf + 1) + p_buf->offset;
  pkt_type = AVCT_PKT_TYPE(p);

  /* must be single packet - can not fragment */
  if (pkt_type != AVCT_PKT_TYPE_SINGLE) {
    osi_free_and_reset((void**)&p_buf);
    AVCT_TRACE_WARNING("Pkt type=%d - fragmentation not allowed. drop it",
                       pkt_type);
  }
  return p_buf;
}

/*******************************************************************************
 *
 * Function         avct_bcb_chnl_open
 *
 * Description      Open L2CAP channel to peer
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
  uint16_t result = AVCT_RESULT_FAIL;
  tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
  tL2CAP_ERTM_INFO ertm_info;

  /* Set the FCR options: Browsing channel mandates ERTM */
  ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;

  /* call l2cap connect req */
  p_bcb->ch_state = AVCT_CH_CONN;
  p_bcb->ch_lcid =
      L2CA_ConnectReq2(AVCT_BR_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
  if (p_bcb->ch_lcid == 0) {
    /* if connect req failed, send ourselves close event */
    tAVCT_LCB_EVT avct_lcb_evt;
    avct_lcb_evt.result = result;
    avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_unbind_disc
 *
 * Description      call callback with disconnect event.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_unbind_disc(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  p_data->p_ccb->p_bcb = NULL;
  (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
                                    AVCT_BROWSE_DISCONN_CFM_EVT, 0, NULL);
}

/*******************************************************************************
 *
 * Function         avct_bcb_open_ind
 *
 * Description      Handle an LL_OPEN event.
 *                  For the allocated ccb already bound to the bcb, send a
 *                  connect event. For the unbound ccb with a new PID, bind that
 *                  ccb to the bcb with the same bd_addr and send a connect
 *                  event.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  tAVCT_CCB* p_ccb_bind = NULL;
  bool bind = false;
  tAVCT_UL_MSG ul_msg;

  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    /* if ccb allocated and */
    if (p_ccb->allocated) {
      /* if bound to this bcb send connect confirm event */
      if (p_ccb->p_bcb == p_bcb) {
        bind = true;
        p_ccb_bind = p_ccb;
        p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT,
                               0, &p_ccb->p_lcb->peer_addr);
      }
      /* if unbound acceptor and lcb allocated and bd_addr are the same for bcb
         and lcb */
      else if ((p_ccb->p_bcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
               (p_ccb->p_lcb != NULL) &&
               p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
        /* bind bcb to ccb and send connect ind event */
        bind = true;
        p_ccb_bind = p_ccb;
        p_ccb->p_bcb = p_bcb;
        p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT,
                               0, &p_ccb->p_lcb->peer_addr);
      }
    }
  }

  /* if no ccbs bound to this lcb, disconnect */
  if (!bind) {
    avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
    return;
  }

  if (!p_bcb->p_tx_msg || !p_ccb_bind) {
    return;
  }

  ul_msg.p_buf = p_bcb->p_tx_msg;
  ul_msg.p_ccb = p_ccb_bind;
  ul_msg.label = (uint8_t)(p_bcb->p_tx_msg->layer_specific & 0xFF);
  ul_msg.cr = (uint8_t)((p_bcb->p_tx_msg->layer_specific & 0xFF00) >> 8);
  p_bcb->p_tx_msg->layer_specific = AVCT_DATA_BROWSE;
  p_bcb->p_tx_msg = NULL;

  /* send msg event to bcb */
  tAVCT_LCB_EVT avct_lcb_evt;
  avct_lcb_evt.ul_msg = ul_msg;
  avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
}

/*******************************************************************************
 *
 * Function         avct_bcb_open_fail
 *
 * Description      L2CAP channel open attempt failed.  Mark the ccbs
 *                  as NULL bcb.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_open_fail(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];

  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
      p_ccb->p_bcb = NULL;
    }
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_close_ind
 *
 * Description      L2CAP channel closed by peer.  Deallocate any initiator
 *                  ccbs on this lcb and send disconnect ind event.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_close_ind(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);

  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
      if (p_ccb->cc.role == AVCT_INT) {
        (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
                                  AVCT_BROWSE_DISCONN_CFM_EVT, 0,
                                  &p_lcb->peer_addr);
      } else {
        (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
                                  AVCT_BROWSE_DISCONN_IND_EVT, 0, NULL);
      }
      p_ccb->p_bcb = NULL;
    }
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_close_cfm
 *
 * Description      L2CAP channel closed by us.  Deallocate any initiator
 *                  ccbs on this lcb and send disconnect ind or cfm event.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  uint8_t event = 0;
  /* Whether BCB initiated channel close */
  bool ch_close = p_bcb->ch_close;
  tAVCT_CTRL_CBACK* p_cback;

  p_bcb->ch_close = false;
  p_bcb->allocated = 0;
  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
      /* if this ccb initiated close send disconnect cfm otherwise ind */
      if (ch_close) {
        event = AVCT_BROWSE_DISCONN_CFM_EVT;
      } else {
        event = AVCT_BROWSE_DISCONN_IND_EVT;
      }

      p_cback = p_ccb->cc.p_ctrl_cback;
      p_ccb->p_bcb = NULL;
      if (p_ccb->p_lcb == NULL) avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
      (*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
                 &p_bcb->peer_addr);
    }
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_bind_conn
 *
 * Description      Bind ccb to lcb and send connect cfm event.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
  p_data->p_ccb->p_bcb = p_bcb;
  (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
                                    AVCT_BROWSE_CONN_CFM_EVT, 0,
                                    &p_lcb->peer_addr);
}

/*******************************************************************************
 *
 * Function         avct_bcb_chk_disc
 *
 * Description      A ccb wants to close; if it is the last ccb on this lcb,
 *                  close channel.  Otherwise just deallocate and call
 *                  callback.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  p_bcb->ch_close = avct_bcb_get_last_ccb_index(p_bcb, p_data->p_ccb);
  if (p_bcb->ch_close) {
    avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
    return;
  }

  avct_bcb_unbind_disc(p_bcb, p_data);
}

/*******************************************************************************
 *
 * Function         avct_bcb_chnl_disc
 *
 * Description      Disconnect L2CAP channel.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
  avct_l2c_br_disconnect(p_bcb->ch_lcid, 0);
}

/*******************************************************************************
 *
 * Function         avct_bcb_bind_fail
 *
 * Description      Deallocate ccb and call callback with connect event
 *                  with failure result.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_bind_fail(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  p_data->p_ccb->p_bcb = NULL;
  (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
                                    AVCT_BROWSE_CONN_CFM_EVT, AVCT_RESULT_FAIL,
                                    NULL);
}

/*******************************************************************************
 *
 * Function         avct_bcb_cong_ind
 *
 * Description      Handle congestion indication from L2CAP.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  uint8_t event;
  tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);

  /* set event */
  event =
      (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;

  /* send event to all ccbs on this lcb */
  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
      (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
                                &p_lcb->peer_addr);
    }
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_discard_msg
 *
 * Description      Discard a message sent in from the API.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  osi_free_and_reset((void**)&p_bcb->p_tx_msg);

  /* if control channel is up, save the message and open the browsing channel */
  if (p_data->ul_msg.p_ccb->p_lcb == NULL) {
    osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
    return;
  }
  p_bcb->p_tx_msg = p_data->ul_msg.p_buf;

  if (p_bcb->p_tx_msg) {
    p_bcb->p_tx_msg->layer_specific =
        (p_data->ul_msg.cr << 8) + p_data->ul_msg.label;

    /* the channel is closed, opening or closing - open it again */
    AVCT_TRACE_DEBUG("ch_state: %d, allocated:%d->%d", p_bcb->ch_state,
                     p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated);
    p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated;
    avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT,
                   (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb);
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_send_msg
 *
 * Description      Build and send an AVCTP message.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  uint16_t curr_msg_len;
  uint8_t pkt_type = AVCT_PKT_TYPE_SINGLE;
  uint8_t hdr_len;
  BT_HDR* p_buf;
  uint8_t* p;

  /* store msg len */
  curr_msg_len = p_data->ul_msg.p_buf->len;

  /* initialize packet type and other stuff */
  if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
    AVCT_TRACE_ERROR("%s msg len (%d) exceeds peer mtu(%d-%d)!!", __func__,
                     curr_msg_len, p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE);
    osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
    return;
  }

  /* set header len */
  hdr_len = avct_lcb_pkt_type_len[pkt_type];
  p_buf = p_data->ul_msg.p_buf;

  /* set up to build header */
  p_buf->len += hdr_len;
  p_buf->offset -= hdr_len;
  p = (uint8_t*)(p_buf + 1) + p_buf->offset;

  /* build header */
  AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
  UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);

  p_buf->layer_specific = AVCT_DATA_BROWSE;

  /* send message to L2CAP */
  L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
}

/*******************************************************************************
 *
 * Function         avct_bcb_free_msg_ind
 *
 * Description      Discard an incoming AVCTP message.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_free_msg_ind(UNUSED_ATTR tAVCT_BCB* p_bcb,
                           tAVCT_LCB_EVT* p_data) {
  if (p_data) osi_free_and_reset((void**)&p_data->p_buf);
}

/*******************************************************************************
 *
 * Function         avct_bcb_msg_ind
 *
 * Description      Handle an incoming AVCTP message.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
  uint8_t* p;
  uint8_t label, type, cr_ipid;
  uint16_t pid;
  tAVCT_CCB* p_ccb;
  tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);

  if ((p_data == NULL) || (p_data->p_buf == NULL)) {
    AVCT_TRACE_WARNING("%s p_data is NULL, returning!", __func__);
    return;
  }

  /* this p_buf is to be reported through p_msg_cback. The layer_specific
   * needs to be set properly to indicate that it is received through
   * browsing channel */
  p_data->p_buf->layer_specific = AVCT_DATA_BROWSE;

  /* reassemble message; if no message available (we received a fragment) return
   */
  p_data->p_buf = avct_bcb_msg_asmbl(p_bcb, p_data->p_buf);
  if (p_data->p_buf == NULL) {
    return;
  }

  if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
    AVCT_TRACE_WARNING("Invalid AVCTP packet length %d: must be at least %d",
                       p_data->p_buf->len, AVCT_HDR_LEN_SINGLE);
    osi_free_and_reset((void**)&p_data->p_buf);
    android_errorWriteLog(0x534e4554, "79944113");
    return;
  }

  p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;

  /* parse header byte */
  AVCT_PARSE_HDR(p, label, type, cr_ipid);

  /* check for invalid cr_ipid */
  if (cr_ipid == AVCT_CR_IPID_INVALID) {
    AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
    osi_free_and_reset((void**)&p_data->p_buf);
    return;
  }

  /* parse and lookup PID */
  BE_STREAM_TO_UINT16(pid, p);
  p_ccb = avct_lcb_has_pid(p_lcb, pid);
  if (p_ccb) {
    /* PID found; send msg up, adjust bt hdr and call msg callback */
    p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
    p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
    (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid,
                             p_data->p_buf);
    return;
  }

  /* PID not found; drop message */
  AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
  osi_free_and_reset((void**)&p_data->p_buf);

  /* if command send reject */
  if (cr_ipid == AVCT_CMD) {
    BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVRC_CMD_BUF_SIZE);
    p_buf->len = AVCT_HDR_LEN_SINGLE;
    p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
    p = (uint8_t*)(p_buf + 1) + p_buf->offset;
    AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
    UINT16_TO_BE_STREAM(p, pid);
    p_buf->layer_specific = AVCT_DATA_BROWSE;
    L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
  }
}

/*******************************************************************************
 *
 * Function         avct_bcb_dealloc
 *
 * Description      Deallocate a browse control block.
 *
 *
 * Returns          void.
 *
 ******************************************************************************/
void avct_bcb_dealloc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];

  AVCT_TRACE_DEBUG("%s %d", __func__, p_bcb->allocated);

  for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
    /* if ccb allocated and */
    if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) {
      p_ccb->p_bcb = NULL;
      AVCT_TRACE_DEBUG("%s used by ccb: %d", __func__, idx);
      break;
    }
  }

  /* the browsing channel is down. Check if we have pending messages */
  osi_free_and_reset((void**)&p_bcb->p_tx_msg);
  memset(p_bcb, 0, sizeof(tAVCT_BCB));
}

/*******************************************************************************
 *
 * Function         avct_close_bcb
 *
 * Description      this function is called right before LCB disconnects.
 *
 *
 * Returns          Nothing.
 *
 ******************************************************************************/
void avct_close_bcb(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
  tAVCT_BCB* p_bcb = avct_bcb_by_lcb(p_lcb);
  if (p_bcb->allocated) {
    avct_bcb_event(p_bcb, AVCT_LCB_UL_UNBIND_EVT, p_data);
  }
}

/*******************************************************************************
 *
 * Function         avct_lcb_by_bcb
 *
 * Description      This lookup function finds the lcb for a bcb.
 *
 * Returns          pointer to the lcb.
 *
 ******************************************************************************/
tAVCT_LCB* avct_lcb_by_bcb(tAVCT_BCB* p_bcb) {
  return &avct_cb.lcb[p_bcb->allocated - 1];
}

/*******************************************************************************
 *
 * Function         avct_bcb_by_lcb
 *
 * Description      This lookup function finds the bcb for a lcb.
 *
 * Returns          pointer to the lcb.
 *
 ******************************************************************************/
tAVCT_BCB* avct_bcb_by_lcb(tAVCT_LCB* p_lcb) {
  return &avct_cb.bcb[p_lcb->allocated - 1];
}

/*******************************************************************************
 *
 * Function         avct_bcb_get_last_ccb_index
 *
 * Description      See if given ccb is only one on the bcb.
 *
 *
 * Returns          0, if ccb is last,  (ccb index + 1) otherwise.
 *
 ******************************************************************************/
uint8_t avct_bcb_get_last_ccb_index(tAVCT_BCB* p_bcb, tAVCT_CCB* p_ccb_last) {
  tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
  uint8_t idx = 0;

  for (int i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
    if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
      if (p_ccb != p_ccb_last) return 0;
      idx = (uint8_t)(i + 1);
    }
  }
  return idx;
}

/*******************************************************************************
 *
 * Function         avct_bcb_by_lcid
 *
 * Description      Find the BCB associated with the L2CAP LCID
 *
 *
 * Returns          pointer to the lcb, or NULL if none found.
 *
 ******************************************************************************/
tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
  tAVCT_BCB* p_bcb = &avct_cb.bcb[0];
  int idx;

  for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
    if (p_bcb->allocated && (p_bcb->ch_lcid == lcid)) {
      return p_bcb;
    }
  }

  /* out of lcbs */
  AVCT_TRACE_WARNING("No bcb for lcid %x", lcid);
  return NULL;
}
