/******************************************************************************
 *
 *  Copyright 2016 The Android Open Source Project
 *  Copyright 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,
    NULL /* tL2CA_CREDITS_RECEIVED_CB */};

/*******************************************************************************
 *
 * 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;
  }

  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) {
    // We are ready to accept connection from this device, since we aren't
    // connected to anything and are in the correct state.
    p_dev->in_use = TRUE;
    p_dev->addr = bd_addr;
    p_dev->state = HIDD_DEV_NO_CONN;

    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);

  if (p_msg->len < 1) {
    HIDD_TRACE_ERROR("Invalid data length, ignore");
    osi_free(p_msg);
    return;
  }

  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,
                     false /* enable_snoop */, nullptr)) {
    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,
                     false /* enable_snoop */, nullptr)) {
    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);
}
