/******************************************************************************
 *
 *  Copyright (C) 2016 The Android Open Source Project
 *  Copyright (C) 2002-2012 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.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  this file contains the connection interface functions
 *
 ******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bt_types.h"

#include "l2c_api.h"
#include "l2cdefs.h"

#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"

#include "hiddefs.h"

#include "bt_utils.h"
#include "hidd_api.h"
#include "hidd_int.h"

#include "osi/include/osi.h"

static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid,
                                   uint16_t psm, uint8_t id);
static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result);
static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg);
static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO* p_cfg);
static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed);
static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result);
static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg);
static void hidd_l2cif_cong_ind(uint16_t cid, bool congested);

static const tL2CAP_APPL_INFO dev_reg_info = {hidd_l2cif_connect_ind,
                                              hidd_l2cif_connect_cfm,
                                              NULL,
                                              hidd_l2cif_config_ind,
                                              hidd_l2cif_config_cfm,
                                              hidd_l2cif_disconnect_ind,
                                              hidd_l2cif_disconnect_cfm,
                                              NULL,
                                              hidd_l2cif_data_ind,
                                              hidd_l2cif_cong_ind,
                                              NULL};

/*******************************************************************************
 *
 * Function         hidd_check_config_done
 *
 * Description      Checks if connection is configured and callback can be fired
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_check_config_done() {
  tHID_CONN* p_hcon;

  p_hcon = &hd_cb.device.conn;

  if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) ==
       HID_CONN_FLAGS_ALL_CONFIGURED) &&
      (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) {
    p_hcon->conn_state = HID_CONN_STATE_CONNECTED;

    hd_cb.device.state = HIDD_DEV_CONNECTED;

    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_OPEN, 0, NULL);

    // send outstanding data on intr
    if (hd_cb.pending_data) {
      L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data);
      hd_cb.pending_data = NULL;
    }
  }
}

/*******************************************************************************
 *
 * Function         hidh_sec_check_complete_term
 *
 * Description      HID security check complete callback function.
 *
 * Returns          Send L2CA_ConnectRsp OK if secutiry check succeed; otherwise
 *                  send security block L2C connection response.
 *
 ******************************************************************************/
static void hidd_sec_check_complete(UNUSED_ATTR const RawAddress* bd_addr,
                                    UNUSED_ATTR tBT_TRANSPORT transport,
                                    void* p_ref_data, uint8_t res) {
  tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data;

  if (res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) {
    p_dev->conn.disc_reason = HID_SUCCESS;
    p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR;

    L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid,
                    L2CAP_CONN_OK, L2CAP_CONN_OK);
    L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg);
  } else if (res != BTM_SUCCESS) {
    HIDD_TRACE_WARNING("%s: connection rejected by security", __func__);

    p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;
    p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
    L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid,
                    L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK);
    return;
  }
}

/*******************************************************************************
 *
 * Function         hidd_sec_check_complete_orig
 *
 * Description      HID security check complete callback function (device
*originated)
 *
 * Returns          void
 *
 ******************************************************************************/
void hidd_sec_check_complete_orig(UNUSED_ATTR const RawAddress* bd_addr,
                                  UNUSED_ATTR tBT_TRANSPORT transport,
                                  void* p_ref_data, uint8_t res) {
  tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data;

  if (p_dev->conn.conn_state != HID_CONN_STATE_SECURITY) {
    HIDD_TRACE_WARNING("%s: invalid state (%02x)", __func__,
                       p_dev->conn.conn_state);
    return;
  }

  if (res == BTM_SUCCESS) {
    HIDD_TRACE_EVENT("%s: security ok", __func__);
    p_dev->conn.disc_reason = HID_SUCCESS;

    p_dev->conn.conn_state = HID_CONN_STATE_CONFIG;
    L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg);
  } else {
    HIDD_TRACE_WARNING("%s: security check failed (%02x)", __func__, res);
    p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;
    hidd_conn_disconnect();
  }
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_connect_ind
 *
 * Description      Handles incoming L2CAP connection (we act as server)
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid,
                                   uint16_t psm, uint8_t id) {
  tHID_CONN* p_hcon;
  tHID_DEV_DEV_CTB* p_dev;
  bool accept = TRUE;  // accept by default

  HIDD_TRACE_EVENT("%s: psm=%04x cid=%04x id=%02x", __func__, psm, cid, id);

  p_dev = &hd_cb.device;

  if (!hd_cb.allow_incoming) {
    HIDD_TRACE_WARNING("%s: incoming connections not allowed, rejecting",
                       __func__);
    L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
    return;
  }

  if (p_dev->in_use && bd_addr != p_dev->addr) {
    HIDD_TRACE_WARNING(
        "%s: incoming connections from different device, rejecting", __func__);
    L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
    return;
  } else if (!p_dev->in_use) {
    p_dev->in_use = TRUE;
    p_dev->addr = bd_addr;
    p_dev->state = HIDD_DEV_NO_CONN;
  }

  p_hcon = &hd_cb.device.conn;

  switch (psm) {
    case HID_PSM_INTERRUPT:
      if (p_hcon->ctrl_cid == 0) {
        accept = FALSE;
        HIDD_TRACE_WARNING("%s: incoming INTR without CTRL, rejecting",
                           __func__);
      }

      if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) {
        accept = FALSE;
        HIDD_TRACE_WARNING("%s: incoming INTR in invalid state (%d), rejecting",
                           __func__, p_hcon->conn_state);
      }

      break;

    case HID_PSM_CONTROL:
      if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) {
        accept = FALSE;
        HIDD_TRACE_WARNING("%s: incoming CTRL in invalid state (%d), rejecting",
                           __func__, p_hcon->conn_state);
      }

      break;

    default:
      accept = FALSE;
      HIDD_TRACE_ERROR("%s: received invalid PSM, rejecting", __func__);
      break;
  }

  if (!accept) {
    L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
    return;
  }

  // for CTRL we need to go through security and we reply in callback from there
  if (psm == HID_PSM_CONTROL) {
    p_hcon->conn_flags = 0;
    p_hcon->ctrl_cid = cid;
    p_hcon->ctrl_id = id;
    p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;

    p_hcon->conn_state = HID_CONN_STATE_SECURITY;
    if (btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, FALSE,
                                  BTM_SEC_PROTO_HID, HIDD_NOSEC_CHN,
                                  &hidd_sec_check_complete,
                                  p_dev) == BTM_CMD_STARTED) {
      L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_PENDING, L2CAP_CONN_OK);
    }

    return;
  }

  // for INTR we go directly to config state
  p_hcon->conn_state = HID_CONN_STATE_CONFIG;
  p_hcon->intr_cid = cid;

  L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
  L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg);
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_connect_cfm
 *
 * Description      Handles L2CAP connection response (we act as client)
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) {
  tHID_DEV_DEV_CTB* p_dev = &hd_cb.device;
  tHID_CONN* p_hcon = &hd_cb.device.conn;

  HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result);

  if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) ||
      ((cid == p_hcon->ctrl_cid) &&
       (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL)) ||
      ((cid == p_hcon->intr_cid) &&
       (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR))) {
    HIDD_TRACE_WARNING("%s: unexpected", __func__);
    return;
  }

  if (result != L2CAP_CONN_OK) {
    HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__);

    if (cid == p_hcon->ctrl_cid)
      p_hcon->ctrl_cid = 0;
    else
      p_hcon->intr_cid = 0;

    hidd_conn_disconnect();

    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE,
                   HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL);
    return;
  }

  /* CTRL connect conf */
  if (cid == p_hcon->ctrl_cid) {
    p_hcon->conn_state = HID_CONN_STATE_SECURITY;
    p_hcon->disc_reason =
        HID_L2CAP_CONN_FAIL; /* in case disconnected before sec completed */

    btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, TRUE,
                              BTM_SEC_PROTO_HID, HIDD_SEC_CHN,
                              &hidd_sec_check_complete_orig, p_dev);
  } else {
    p_hcon->conn_state = HID_CONN_STATE_CONFIG;
    L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg);
  }

  return;
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_config_ind
 *
 * Description      Handles incoming L2CAP configuration request
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
  tHID_CONN* p_hcon;

  HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE))
    p_hcon->rem_mtu_size = HID_DEV_MTU_SIZE;
  else
    p_hcon->rem_mtu_size = p_cfg->mtu;

  // accept without changes
  p_cfg->flush_to_present = FALSE;
  p_cfg->mtu_present = FALSE;
  p_cfg->result = L2CAP_CFG_OK;

  if (cid == p_hcon->intr_cid && hd_cb.use_in_qos && !p_cfg->qos_present) {
    p_cfg->qos_present = TRUE;
    memcpy(&p_cfg->qos, &hd_cb.in_qos, sizeof(FLOW_SPEC));
  }

  L2CA_ConfigRsp(cid, p_cfg);

  // update flags
  if (cid == p_hcon->ctrl_cid) {
    p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;

    if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
        (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) {
      p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
      if ((p_hcon->intr_cid =
               L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
        hidd_conn_disconnect();
        p_hcon->conn_state = HID_CONN_STATE_UNUSED;

        HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR",
                           __func__);
        hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE,
                       HID_ERR_L2CAP_FAILED, NULL);
        return;
      } else {
        p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
      }
    }
  } else {
    p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE;
  }

  hidd_check_config_done();
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_config_cfm
 *
 * Description      Handles incoming L2CAP configuration response
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
  tHID_CONN* p_hcon;
  uint32_t reason;

  HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid,
                   p_cfg->result);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if (p_hcon->intr_cid == cid &&
      p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) {
    tL2CAP_CFG_INFO new_qos;

    // QoS parameters not accepted for intr, try again with host proposal

    memcpy(&new_qos, &hd_cb.l2cap_intr_cfg, sizeof(new_qos));
    memcpy(&new_qos.qos, &p_cfg->qos, sizeof(FLOW_SPEC));
    new_qos.qos_present = TRUE;

    HIDD_TRACE_WARNING("%s: config failed, retry", __func__);

    L2CA_ConfigReq(cid, &new_qos);
    return;
  } else if (p_hcon->intr_cid == cid &&
             p_cfg->result == L2CAP_CFG_UNKNOWN_OPTIONS) {
    // QoS not understood by remote device, try configuring without QoS

    HIDD_TRACE_WARNING("%s: config failed, retry without QoS", __func__);

    L2CA_ConfigReq(cid, &hd_cb.l2cap_cfg);
    return;
  } else if (p_cfg->result != L2CAP_CFG_OK) {
    HIDD_TRACE_WARNING("%s: config failed, disconnecting", __func__);

    hidd_conn_disconnect();
    reason = HID_L2CAP_CFG_FAIL | (uint32_t)p_cfg->result;

    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, reason, NULL);
    return;
  }

  // update flags
  if (cid == p_hcon->ctrl_cid) {
    p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;

    if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
        (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) {
      p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
      if ((p_hcon->intr_cid =
               L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
        hidd_conn_disconnect();
        p_hcon->conn_state = HID_CONN_STATE_UNUSED;

        HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR",
                           __func__);
        hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE,
                       HID_ERR_L2CAP_FAILED, NULL);
        return;
      } else {
        p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
      }
    }
  } else {
    p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE;
  }

  hidd_check_config_done();
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_disconnect_ind
 *
 * Description      Handler incoming L2CAP disconnection request
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) {
  tHID_CONN* p_hcon;

  HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->conn_state == HID_CONN_STATE_UNUSED ||
      (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if (ack_needed) L2CA_DisconnectRsp(cid);

  p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;

  if (cid == p_hcon->ctrl_cid)
    p_hcon->ctrl_cid = 0;
  else
    p_hcon->intr_cid = 0;

  if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
    HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);

    // clean any outstanding data on intr
    if (hd_cb.pending_data) {
      osi_free(hd_cb.pending_data);
      hd_cb.pending_data = NULL;
    }

    hd_cb.device.state = HIDD_DEV_NO_CONN;
    p_hcon->conn_state = HID_CONN_STATE_UNUSED;

    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, p_hcon->disc_reason,
                   NULL);
  }
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_disconnect_cfm
 *
 * Description      Handles L2CAP disconection response
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result) {
  tHID_CONN* p_hcon;

  HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->conn_state == HID_CONN_STATE_UNUSED ||
      (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if (cid == p_hcon->ctrl_cid) {
    p_hcon->ctrl_cid = 0;
  } else {
    p_hcon->intr_cid = 0;

    // now disconnect CTRL
    L2CA_DisconnectReq(p_hcon->ctrl_cid);
  }

  if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
    HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);

    hd_cb.device.state = HIDD_DEV_NO_CONN;
    p_hcon->conn_state = HID_CONN_STATE_UNUSED;

    if (hd_cb.pending_vc_unplug) {
      hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_VC_UNPLUG,
                     p_hcon->disc_reason, NULL);
      hd_cb.pending_vc_unplug = FALSE;
    } else {
      hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE,
                     p_hcon->disc_reason, NULL);
    }
  }
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_cong_ind
 *
 * Description      Handles L2CAP congestion status event
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_cong_ind(uint16_t cid, bool congested) {
  tHID_CONN* p_hcon;

  HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->conn_state == HID_CONN_STATE_UNUSED ||
      (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    return;
  }

  if (congested) {
    p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED;
  } else {
    p_hcon->conn_flags &= ~HID_CONN_FLAGS_CONGESTED;
  }
}

/*******************************************************************************
 *
 * Function         hidd_l2cif_data_ind
 *
 * Description      Handler incoming data on L2CAP channel
 *
 * Returns          void
 *
 ******************************************************************************/
static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) {
  tHID_CONN* p_hcon;
  uint8_t* p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
  uint8_t msg_type, param;
  bool err = FALSE;

  HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->conn_state == HID_CONN_STATE_UNUSED ||
      (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
    HIDD_TRACE_WARNING("%s: unknown cid", __func__);
    osi_free(p_msg);
    return;
  }

  msg_type = HID_GET_TRANS_FROM_HDR(*p_data);
  param = HID_GET_PARAM_FROM_HDR(*p_data);

  if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) {
    // skip HID header
    p_msg->offset++;
    p_msg->len--;

    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_INTR_DATA, 0, p_msg);
    return;
  }

  switch (msg_type) {
    case HID_TRANS_GET_REPORT:
      // at this stage we don't know if Report Id shall be included in request
      // so we pass complete packet in callback and let other code analyze this
      hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_GET_REPORT,
                     !!(param & HID_PAR_GET_REP_BUFSIZE_FOLLOWS), p_msg);
      break;

    case HID_TRANS_SET_REPORT:
      // as above
      hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_REPORT, 0, p_msg);
      break;

    case HID_TRANS_GET_IDLE:
      hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA,
                          HID_PAR_REP_TYPE_OTHER, hd_cb.device.idle_time, 0,
                          NULL);
      osi_free(p_msg);
      break;

    case HID_TRANS_SET_IDLE:
      if (p_msg->len != 2) {
        HIDD_TRACE_ERROR("%s: invalid len (%d) set idle request received",
                         __func__, p_msg->len);
        err = TRUE;
      } else {
        hd_cb.device.idle_time = p_data[1];
        HIDD_TRACE_DEBUG("%s: idle_time = %d", __func__,
                         hd_cb.device.idle_time);
        if (hd_cb.device.idle_time) {
          HIDD_TRACE_WARNING(
              "%s: idle_time of %d ms not supported by HID Device", __func__,
              (hd_cb.device.idle_time * 4));
          err = TRUE;
        }
      }
      if (!err) {
        hidd_conn_send_data(0, HID_TRANS_HANDSHAKE,
                            HID_PAR_HANDSHAKE_RSP_SUCCESS, 0, 0, NULL);
      } else {
        hidd_conn_send_data(0, HID_TRANS_HANDSHAKE,
                            HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM, 0, 0,
                            NULL);
      }
      osi_free(p_msg);
      break;

    case HID_TRANS_GET_PROTOCOL:
      hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA,
                          HID_PAR_REP_TYPE_OTHER, !hd_cb.device.boot_mode, 0,
                          NULL);
      osi_free(p_msg);
      break;

    case HID_TRANS_SET_PROTOCOL:
      hd_cb.device.boot_mode = !(param & HID_PAR_PROTOCOL_MASK);
      hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_PROTOCOL,
                     param & HID_PAR_PROTOCOL_MASK, NULL);
      hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_SUCCESS,
                          0, 0, NULL);
      osi_free(p_msg);
      break;

    case HID_TRANS_CONTROL:
      switch (param) {
        case HID_PAR_CONTROL_SUSPEND:
          hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SUSPEND, 0, NULL);
          break;

        case HID_PAR_CONTROL_EXIT_SUSPEND:
          hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_EXIT_SUSPEND, 0,
                         NULL);
          break;

        case HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG:
          hidd_conn_disconnect();

          // set flag so we can notify properly when disconnected
          hd_cb.pending_vc_unplug = TRUE;
          break;
      }

      osi_free(p_msg);
      break;

    case HID_TRANS_DATA:
    default:
      HIDD_TRACE_WARNING("%s: got unsupported msg (%d)", __func__, msg_type);
      hidd_conn_send_data(0, HID_TRANS_HANDSHAKE,
                          HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ, 0, 0,
                          NULL);
      osi_free(p_msg);
      break;
  }
}

/*******************************************************************************
 *
 * Function         hidd_conn_reg
 *
 * Description      Registers L2CAP channels
 *
 * Returns          void
 *
 ******************************************************************************/
tHID_STATUS hidd_conn_reg(void) {
  HIDD_TRACE_API("%s", __func__);

  memset(&hd_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO));

  hd_cb.l2cap_cfg.mtu_present = TRUE;
  hd_cb.l2cap_cfg.mtu = HID_DEV_MTU_SIZE;
  hd_cb.l2cap_cfg.flush_to_present = TRUE;
  hd_cb.l2cap_cfg.flush_to = HID_DEV_FLUSH_TO;

  memset(&hd_cb.l2cap_intr_cfg, 0, sizeof(tL2CAP_CFG_INFO));
  hd_cb.l2cap_intr_cfg.mtu_present = TRUE;
  hd_cb.l2cap_intr_cfg.mtu = HID_DEV_MTU_SIZE;
  hd_cb.l2cap_intr_cfg.flush_to_present = TRUE;
  hd_cb.l2cap_intr_cfg.flush_to = HID_DEV_FLUSH_TO;

  if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&dev_reg_info)) {
    HIDD_TRACE_ERROR("HID Control (device) registration failed");
    return (HID_ERR_L2CAP_FAILED);
  }

  if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&dev_reg_info)) {
    L2CA_Deregister(HID_PSM_CONTROL);
    HIDD_TRACE_ERROR("HID Interrupt (device) registration failed");
    return (HID_ERR_L2CAP_FAILED);
  }

  return (HID_SUCCESS);
}

/*******************************************************************************
 *
 * Function         hidd_conn_dereg
 *
 * Description      Deregisters L2CAP channels
 *
 * Returns          void
 *
 ******************************************************************************/
void hidd_conn_dereg(void) {
  HIDD_TRACE_API("%s", __func__);

  L2CA_Deregister(HID_PSM_CONTROL);
  L2CA_Deregister(HID_PSM_INTERRUPT);
}

/*******************************************************************************
 *
 * Function         hidd_conn_initiate
 *
 * Description      Initiates HID connection to plugged device
 *
 * Returns          HID_SUCCESS
 *
 ******************************************************************************/
tHID_STATUS hidd_conn_initiate(void) {
  tHID_DEV_DEV_CTB* p_dev = &hd_cb.device;

  HIDD_TRACE_API("%s", __func__);

  if (!p_dev->in_use) {
    HIDD_TRACE_WARNING("%s: no virtual cable established", __func__);
    return (HID_ERR_NOT_REGISTERED);
  }

  if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) {
    HIDD_TRACE_WARNING("%s: connection already in progress", __func__);
    return (HID_ERR_CONN_IN_PROCESS);
  }

  p_dev->conn.ctrl_cid = 0;
  p_dev->conn.intr_cid = 0;
  p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL;

  p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG;

  BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN);

  /* Check if L2CAP started the connection process */
  if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) ==
      0) {
    HIDD_TRACE_WARNING("%s: could not start L2CAP connection", __func__);
    hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED,
                   NULL);
  } else {
    p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
  }

  return (HID_SUCCESS);
}

/*******************************************************************************
 *
 * Function         hidd_conn_disconnect
 *
 * Description      Disconnects existing HID connection
 *
 * Returns          HID_SUCCESS
 *
 ******************************************************************************/
tHID_STATUS hidd_conn_disconnect(void) {
  tHID_CONN* p_hcon;

  HIDD_TRACE_API("%s", __func__);

  // clean any outstanding data on intr
  if (hd_cb.pending_data) {
    osi_free(hd_cb.pending_data);
    hd_cb.pending_data = NULL;
  }

  p_hcon = &hd_cb.device.conn;

  if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0)) {
    p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;

    /* Set l2cap idle timeout to 0 (so ACL link is disconnected
     * immediately after last channel is closed) */
    L2CA_SetIdleTimeoutByBdAddr(hd_cb.device.addr, 0, BT_TRANSPORT_BR_EDR);

    if (p_hcon->intr_cid) {
      L2CA_DisconnectReq(p_hcon->intr_cid);
    } else if (p_hcon->ctrl_cid) {
      L2CA_DisconnectReq(p_hcon->ctrl_cid);
    }
  } else {
    HIDD_TRACE_WARNING("%s: already disconnected", __func__);
    p_hcon->conn_state = HID_CONN_STATE_UNUSED;
  }

  return (HID_SUCCESS);
}

/*******************************************************************************
 *
 * Function         hidd_conn_send_data
 *
 * Description      Sends data to host
 *
 * Returns          tHID_STATUS
 *
 ******************************************************************************/
tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type,
                                uint8_t param, uint8_t data, uint16_t len,
                                uint8_t* p_data) {
  tHID_CONN* p_hcon;
  BT_HDR* p_buf;
  uint8_t* p_out;
  uint16_t cid;
  uint16_t buf_size;

  HIDD_TRACE_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__,
                     channel, msg_type, len);

  p_hcon = &hd_cb.device.conn;

  if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
    return HID_ERR_CONGESTED;
  }

  switch (msg_type) {
    case HID_TRANS_HANDSHAKE:
    case HID_TRANS_CONTROL:
      cid = p_hcon->ctrl_cid;
      buf_size = HID_CONTROL_BUF_SIZE;
      break;
    case HID_TRANS_DATA:
      if (channel == HID_CHANNEL_CTRL) {
        cid = p_hcon->ctrl_cid;
        buf_size = HID_CONTROL_BUF_SIZE;
      } else {
        cid = p_hcon->intr_cid;
        buf_size = HID_INTERRUPT_BUF_SIZE;
      }
      break;
    default:
      return (HID_ERR_INVALID_PARAM);
  }

  p_buf = (BT_HDR*)osi_malloc(buf_size);
  if (p_buf == NULL) return (HID_ERR_NO_RESOURCES);

  p_buf->offset = L2CAP_MIN_OFFSET;

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

  *p_out = HID_BUILD_HDR(msg_type, param);
  p_out++;

  p_buf->len = 1;  // start with header only

  // add report id prefix only if non-zero (which is reserved)
  if (msg_type == HID_TRANS_DATA && (data || param == HID_PAR_REP_TYPE_OTHER)) {
    *p_out = data;  // report_id
    p_out++;
    p_buf->len++;
  }

  if (len > 0 && p_data != NULL) {
    memcpy(p_out, p_data, len);
    p_buf->len += len;
  }

  // check if connected
  if (hd_cb.device.state != HIDD_DEV_CONNECTED) {
    // for DATA on intr we hold transfer and try to reconnect
    if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) {
      // drop previous data, we do not queue it for now
      if (hd_cb.pending_data) {
        osi_free(hd_cb.pending_data);
      }

      hd_cb.pending_data = p_buf;

      if (hd_cb.device.conn.conn_state == HID_CONN_STATE_UNUSED) {
        hidd_conn_initiate();
      }

      return HID_SUCCESS;
    }

    return HID_ERR_NO_CONNECTION;
  }

#ifdef REPORT_TRANSFER_TIMESTAMP
  if (report_transfer) {
    HIDD_TRACE_ERROR("%s: report sent", __func__);
  }
#endif
  HIDD_TRACE_VERBOSE("%s: report sent", __func__);

  if (!L2CA_DataWrite(cid, p_buf)) return (HID_ERR_CONGESTED);

  return (HID_SUCCESS);
}
