hidh_conn.c revision 258c2538e3b62a8cdb403f2730c45d721e5292b4
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2002-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains the connection interface functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_types.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btu.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hiddefs.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hidh_api.h"
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hidh_int.h"
445cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
46bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray#include "osi/include/osi.h"
47bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic UINT8 find_conn_by_cid (UINT16 cid);
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_conn_retry (UINT8 dhandle);
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/********************************************************************************/
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/********************************************************************************/
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid,
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    UINT16 psm, UINT8 l2cap_id);
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result);
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_disconnect_cfm (UINT16 l2cap_cid, UINT16 result);
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_cong_ind (UINT16 l2cap_cid, BOOLEAN congested);
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const tL2CAP_APPL_INFO hst_reg_info =
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_connect_ind,
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_connect_cfm,
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    NULL,
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_config_ind,
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_config_cfm,
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_disconnect_ind,
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_disconnect_cfm,
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    NULL,
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_data_ind,
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_l2cif_cong_ind,
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    NULL                        /* tL2CA_TX_COMPLETE_CB */
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_reg
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initializes the SDP unit.
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttHID_STATUS hidh_conn_reg (void)
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int xx;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Initialize the L2CAP configuration. We only care about MTU and flush */
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&hh_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO));
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hh_cb.l2cap_cfg.mtu_present          = TRUE;
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hh_cb.l2cap_cfg.mtu                  = HID_HOST_MTU;
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hh_cb.l2cap_cfg.flush_to_present     = TRUE;
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hh_cb.l2cap_cfg.flush_to             = HID_HOST_FLUSH_TO;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, register with L2CAP */
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!L2CA_Register (HID_PSM_CONTROL, (tL2CAP_APPL_INFO *) &hst_reg_info))
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
103d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_ERROR ("HID-Host Control Registration failed");
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (HID_ERR_L2CAP_FAILED) ;
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!L2CA_Register (HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO *) &hst_reg_info))
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_Deregister( HID_PSM_CONTROL ) ;
109d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_ERROR ("HID-Host Interrupt Registration failed");
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (HID_ERR_L2CAP_FAILED) ;
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++)
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[xx].in_use = FALSE ;
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[xx].conn.conn_state = HID_CONN_STATE_UNUSED;
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (HID_SUCCESS);
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_conn_disconnect
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function disconnects a connection.
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if disconnect started, FALSE if already disconnected
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttHID_STATUS hidh_conn_disconnect (UINT8 dhandle)
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn;
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
135d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host disconnect");
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0))
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1411747956ba052b1538c29fe7793403dc4f13ba525Hemant Gupta        /* Set l2cap idle timeout to 0 (so ACL link is disconnected
1421747956ba052b1538c29fe7793403dc4f13ba525Hemant Gupta         * immediately after last channel is closed) */
143444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji        L2CA_SetIdleTimeoutByBdAddr(hh_cb.devices[dhandle].addr, 0, BT_TRANSPORT_BR_EDR);
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Disconnect both interrupt and control channels */
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_hcon->intr_cid)
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CA_DisconnectReq (p_hcon->intr_cid);
147bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta        else if (p_hcon->ctrl_cid)
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CA_DisconnectReq (p_hcon->ctrl_cid);
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (HID_SUCCESS);
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_sec_check_complete_term
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      HID security check complete callback function.
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Send L2CA_ConnectRsp OK if secutiry check succeed; otherwise
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  send security block L2C connection response.
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1688fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Battavoid hidh_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev= (tHID_HOST_DEV_CTB *) p_ref_data;
1715cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(bd_addr);
1728fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    UNUSED (transport);
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.disc_reason = HID_SUCCESS;  /* Authentication passed. Reset disc_reason (from HID_ERR_AUTH_FAILED) */
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR;
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Send response to the L2CAP layer. */
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_ConnectRsp (p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Send a Configuration Request. */
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_ConfigReq (p_dev->conn.ctrl_cid, &hh_cb.l2cap_cfg);
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* security check fail */
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (res != BTM_SUCCESS)
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;      /* Save reason for disconnecting */
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_ConnectRsp (p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK);
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_connect_ind
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles an inbound connection indication
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  from L2CAP. This is the case where we are acting as a
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  server.
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon;
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN      bAccept = TRUE;
2112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8        i = HID_HOST_MAX_DEVICES;
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev;
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
214d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP conn ind, PSM: 0x%04x  CID 0x%x", psm, l2cap_cid);
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    /* always add incoming connection device into HID database by default */
2172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (HID_HostAddDev(bd_addr, HID_SEC_REQUIRED, &i) != HID_SUCCESS)
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_SECURITY_BLOCK, 0);
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hcon = &hh_cb.devices[i].conn;
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev  = &hh_cb.devices[i];
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check we are in the correct state for this */
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (psm == HID_PSM_INTERRUPT)
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_hcon->ctrl_cid == 0)
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
231d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati            HIDH_TRACE_WARNING ("HID-Host Rcvd INTR L2CAP conn ind, but no CTL channel");
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bAccept = FALSE;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
236d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati            HIDH_TRACE_WARNING ("HID-Host Rcvd INTR L2CAP conn ind, wrong state: %d",
2372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                                 p_hcon->conn_state);
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bAccept = FALSE;
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* CTRL channel */
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if defined(HID_HOST_ACPT_NEW_CONN) && (HID_HOST_ACPT_NEW_CONN == TRUE)
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->ctrl_cid = p_hcon->intr_cid = 0;
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_hcon->conn_state != HID_CONN_STATE_UNUSED)
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
249d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati            HIDH_TRACE_WARNING ("HID-Host - Rcvd CTL L2CAP conn ind, wrong state: %d",
2502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                                 p_hcon->conn_state);
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bAccept = FALSE;
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!bAccept)
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_NO_RESOURCES, 0);
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (psm == HID_PSM_CONTROL)
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags = 0;
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->ctrl_cid   = l2cap_cid;
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->ctrl_id    = l2cap_id;
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;  /* In case disconnection occurs before security is completed, then set CLOSE_EVT reason code to 'connection failure' */
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_SECURITY;
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(btm_sec_mx_access_request (p_dev->addr, HID_PSM_CONTROL,
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            FALSE, BTM_SEC_PROTO_HID,
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (p_dev->attr_mask & HID_SEC_REQUIRED) ? HID_SEC_CHN : HID_NOSEC_CHN,
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            &hidh_sec_check_complete_term, p_dev) == BTM_CMD_STARTED)
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_PENDING, L2CAP_CONN_OK);
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Transition to the next appropriate state, configuration */
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hcon->conn_state = HID_CONN_STATE_CONFIG;
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hcon->intr_cid   = l2cap_cid;
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send response to the L2CAP layer. */
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send a Configuration Request. */
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_ConfigReq (l2cap_cid, &hh_cb.l2cap_cfg);
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
291d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP conn ind, sent config req, PSM: 0x%04x  CID 0x%x",
2922e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                       psm, l2cap_cid);
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_proc_repage_timeout
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles timeout (to page device).
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3049f1c9ad85759c7663e3bbc494f8e75b2f107da67Pavlin Radoslavovvoid hidh_proc_repage_timeout(timer_entry_t *p_te)
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
306bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    tHID_HOST_DEV_CTB *device;
3079f1c9ad85759c7663e3bbc494f8e75b2f107da67Pavlin Radoslavov    UINT8 dhandle = PTR_TO_UINT(p_te->param);
308bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray
309bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    hidh_conn_initiate(dhandle);
310bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray
311bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    device = &hh_cb.devices[dhandle];
312bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    device->conn_tries++;
313bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray
314bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    hh_cb.callback(dhandle, device->addr, HID_HDEV_EVT_RETRYING,
315bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray                   device->conn_tries, NULL ) ;
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_sec_check_complete_orig
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function checks to see if security procedures are being
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  carried out or not..
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Battavoid hidh_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data;
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
3325cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(bd_addr);
3338fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    UNUSED (transport);
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
335bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    // TODO(armansito): This kind of math to determine a device handle is way
336bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    // too dirty and unnecessary. Why can't |p_dev| store it's handle?
337bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    dhandle = (PTR_TO_UINT(p_dev) - PTR_TO_UINT(&(hh_cb.devices[0])))/ sizeof(tHID_HOST_DEV_CTB);
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
340d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_EVENT ("HID-Host Originator security pass.");
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.disc_reason = HID_SUCCESS;  /* Authentication passed. Reset disc_reason (from HID_ERR_AUTH_FAILED) */
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3437f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        /* Transition to the next appropriate state, configuration */
3447f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        p_dev->conn.conn_state = HID_CONN_STATE_CONFIG;
3457f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        L2CA_ConfigReq (p_dev->conn.ctrl_cid, &hh_cb.l2cap_cfg);
346d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_EVENT ("HID-Host Got Control conn cnf, sent cfg req, CID: 0x%x", p_dev->conn.ctrl_cid);
3477f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( res != BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (HID_HOST_MAX_CONN_RETRY > 0)
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if( res == BTM_DEVICE_TIMEOUT )
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if( p_dev->conn_tries <= HID_HOST_MAX_CONN_RETRY )
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                hidh_conn_retry (dhandle);
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;      /* Save reason for disconnecting */
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hidh_conn_disconnect(dhandle);
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_connect_cfm
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles the connect confirm events
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  from L2CAP. This is the case when we are acting as a
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  client and have sent a connect request.
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result)
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32  reason;
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev = NULL;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID, and verify we are in a state to accept this message */
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev = &hh_cb.devices[dhandle];
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_hcon == NULL)
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG))
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || ((l2cap_cid == p_hcon->ctrl_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL))
396742d9fa575cd1ea12c7d4413f1bec62863b07cabHemant Gupta     || ((l2cap_cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)
397742d9fa575cd1ea12c7d4413f1bec62863b07cabHemant Gupta     && (p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING)))
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
399d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd unexpected conn cnf, CID 0x%x ", l2cap_cid);
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (result != L2CAP_CONN_OK)
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (l2cap_cid == p_hcon->ctrl_cid)
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_hcon->ctrl_cid = 0;
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_hcon->intr_cid = 0;
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hidh_conn_disconnect(dhandle);
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (HID_HOST_MAX_CONN_RETRY > 0)
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if( (hh_cb.devices[dhandle].conn_tries <= HID_HOST_MAX_CONN_RETRY) &&
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (result == HCI_ERR_CONNECTION_TOUT || result == HCI_ERR_UNSPECIFIED ||
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project             result == HCI_ERR_PAGE_TIMEOUT) )
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            hidh_conn_retry(dhandle);
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            reason = HID_L2CAP_CONN_FAIL | (UINT32) result ;
4232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* receive Control Channel connect confirmation */
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cap_cid == p_hcon->ctrl_cid)
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* check security requirement */
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_SECURITY;
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;  /* In case disconnection occurs before security is completed, then set CLOSE_EVT reason code to "connection failure" */
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btm_sec_mx_access_request (p_dev->addr, HID_PSM_CONTROL,
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            TRUE, BTM_SEC_PROTO_HID,
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (p_dev->attr_mask & HID_SEC_REQUIRED) ? HID_SEC_CHN : HID_NOSEC_CHN,
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            &hidh_sec_check_complete_orig, p_dev);
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_CONFIG;
4427f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        /* Send a Configuration Request. */
4437f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        L2CA_ConfigReq (l2cap_cid, &hh_cb.l2cap_cfg);
444d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_EVENT ("HID-Host got Interrupt conn cnf, sent cfg req, CID: 0x%x", l2cap_cid);
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return;
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_config_ind
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function processes the L2CAP configuration indication
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  event.
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
4647f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta    UINT32  reason;
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
474d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
478d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid);
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Remember the remote MTU size */
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU))
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->rem_mtu_size = HID_HOST_MTU;
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->rem_mtu_size = p_cfg->mtu;
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* For now, always accept configuration from the other side */
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cfg->flush_to_present = FALSE;
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cfg->mtu_present      = FALSE;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cfg->result           = L2CAP_CFG_OK;
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_ConfigRsp (l2cap_cid, p_cfg);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cap_cid == p_hcon->ctrl_cid)
4947f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta    {
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;
4967f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
4977f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta           (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE))
4987f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        {
4997f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            /* Connect interrupt channel */
5007f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;	/* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
5017f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0)
5027f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            {
503d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati                HIDH_TRACE_WARNING ("HID-Host INTR Originate failed");
5047f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                reason = HID_L2CAP_REQ_FAIL ;
5057f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                p_hcon->conn_state = HID_CONN_STATE_UNUSED;
5067f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                hidh_conn_disconnect (dhandle);
5077f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
5087f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                return;
5097f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            }
5107f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            else
5117f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            {
5127f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                /* Transition to the next appropriate state, waiting for connection confirm on interrupt channel. */
5137f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
5147f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            }
5157f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        }
5167f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta    }
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If all configuration is complete, change state and tell management we are up */
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED)
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && (p_hcon->conn_state == HID_CONN_STATE_CONFIG))
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_CONNECTED;
5258f322bfe42a57902e7c45713a5c6215dfbe2494aHemant Gupta        /* Reset disconnect reason to success, as connection successful */
5268f322bfe42a57902e7c45713a5c6215dfbe2494aHemant Gupta        p_hcon->disc_reason = HID_SUCCESS;
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[dhandle].state = HID_DEV_CONNECTED;
5292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ;
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_config_cfm
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function processes the L2CAP configuration confirmation
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  event.
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32  reason;
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
550d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd cfg cfm, CID: 0x%x  Result: %d", l2cap_cid, p_cfg->result);
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
558d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If configuration failed, disconnect the channel(s) */
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->result != L2CAP_CFG_OK)
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hidh_conn_disconnect (dhandle);
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        reason = HID_L2CAP_CFG_FAIL | (UINT32) p_cfg->result ;
5672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cap_cid == p_hcon->ctrl_cid)
5727f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta    {
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;
5747f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
5757f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta           (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE))
5767f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        {
5777f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            /* Connect interrupt channel */
5787f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;  /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
5797f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0)
5807f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            {
581d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati                HIDH_TRACE_WARNING ("HID-Host INTR Originate failed");
5827f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                reason = HID_L2CAP_REQ_FAIL ;
5837f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                p_hcon->conn_state = HID_CONN_STATE_UNUSED;
5847f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                hidh_conn_disconnect (dhandle);
5857f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
5867f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                return;
5877f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            }
5887f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            else
5897f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            {
5907f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                /* Transition to the next appropriate state, waiting for connection confirm on interrupt channel. */
5917f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta                p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
5927f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta            }
5937f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta        }
5947f7d49370a7527052995c0f1ce355f72b073510dHemant Gupta    }
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE;
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If all configuration is complete, change state and tell management we are up */
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED)
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && (p_hcon->conn_state == HID_CONN_STATE_CONFIG))
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_CONNECTED;
6038f322bfe42a57902e7c45713a5c6215dfbe2494aHemant Gupta        /* Reset disconnect reason to success, as connection successful */
6048f322bfe42a57902e7c45713a5c6215dfbe2494aHemant Gupta        p_hcon->disc_reason = HID_SUCCESS;
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[dhandle].state = HID_DEV_CONNECTED;
6072e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ;
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_disconnect_ind
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles a disconnect event from L2CAP. If
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  requested to, we ack the disconnect before dropping the CCB
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 disc_res = HCI_SUCCESS;
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 hid_close_evt_reason;
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
635d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid);
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (ack_needed)
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_DisconnectRsp (l2cap_cid);
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
642d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cap_cid == p_hcon->ctrl_cid)
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->ctrl_cid = 0;
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->intr_cid = 0;
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0))
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[dhandle].state = HID_DEV_NO_CONN;
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if( !ack_needed )
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            disc_res = btm_get_acl_disc_reason_code();
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (HID_HOST_MAX_CONN_RETRY > 0)
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if( (disc_res == HCI_ERR_CONNECTION_TOUT || disc_res == HCI_ERR_UNSPECIFIED) &&
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (!(hh_cb.devices[dhandle].attr_mask & HID_RECONN_INIT)) &&
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (hh_cb.devices[dhandle].attr_mask & HID_NORMALLY_CONNECTABLE))
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            hh_cb.devices[dhandle].conn_tries = 0;
665bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray            hh_cb.devices[dhandle].conn.timer_entry.param = UINT_TO_PTR(dhandle);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btu_start_timer (&(hh_cb.devices[dhandle].conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN);
6670ab408fe6f6cb698ba1fcd8492d117c0d3574c7dHemant Gupta            hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, disc_res, NULL);
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Set reason code for HID_HDEV_EVT_CLOSE */
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            hid_close_evt_reason = p_hcon->disc_reason;
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If we got baseband sent HCI_DISCONNECT_COMPLETE_EVT due to security failure, then set reason to HID_ERR_AUTH_FAILED */
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((disc_res == HCI_ERR_AUTH_FAILURE)                        ||
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_KEY_MISSING)                         ||
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_HOST_REJECT_SECURITY)                ||
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_PAIRING_NOT_ALLOWED)                 ||
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_UNIT_KEY_USED)                       ||
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE)           ||
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (disc_res == HCI_ERR_REPEATED_ATTEMPTS))
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                hid_close_evt_reason = HID_ERR_AUTH_FAILED;
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6882e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, hid_close_evt_reason, NULL ) ;
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_disconnect_cfm
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles a disconnect confirm event from L2CAP.
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_disconnect_cfm (UINT16 l2cap_cid, UINT16 result)
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
7075cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(result);
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
715d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP disc cfm, unknown CID: 0x%x", l2cap_cid);
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
719d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid);
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cap_cid == p_hcon->ctrl_cid)
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->ctrl_cid = 0;
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
724bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta    {
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->intr_cid = 0;
726bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta        if (p_hcon->ctrl_cid)
727bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta        {
728d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati            HIDH_TRACE_EVENT ("HID-Host Initiating L2CAP Ctrl disconnection");
729bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta            L2CA_DisconnectReq (p_hcon->ctrl_cid);
730bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta        }
731bf51271f145204a0489597ccd9c851daa7ee0ad7Hemant Gupta    }
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0))
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        hh_cb.devices[dhandle].state = HID_DEV_NO_CONN;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
7372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, p_hcon->disc_reason, NULL ) ;
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_cong_ind
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function handles a congestion status event from L2CAP.
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_cong_ind (UINT16 l2cap_cid, BOOLEAN congested)
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
762d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP congestion status, unknown CID: 0x%x", l2cap_cid);
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
766d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP congestion status, CID: 0x%x  Cong: %d", l2cap_cid, congested);
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (congested)
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED;
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon->conn_flags &= ~HID_CONN_FLAGS_CONGESTED;
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_l2cif_data_ind
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when data is received from L2CAP.
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  if we are the originator of the connection, we are the SDP
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  client, and the received message is queued up for the client.
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If we are the destination of the connection, we are the SDP
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  server, so the message is passed to the server processing
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function.
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           *p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           ttype, param, rep_type, evt;
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 dhandle;
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN    *p_hcon = NULL;
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
800d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati    HIDH_TRACE_DEBUG ("HID-Host hidh_l2cif_data_ind [l2cap_cid=0x%04x]", l2cap_cid);
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find CCB based on CID */
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     if ((dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES)
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_hcon = &hh_cb.devices[dhandle].conn;
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon == NULL)
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
808d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid);
809258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov        osi_freebuf (p_msg);
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    ttype    = HID_GET_TRANS_FROM_HDR(*p_data);
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    param    = HID_GET_PARAM_FROM_HDR(*p_data);
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rep_type = param & HID_PAR_REP_TYPE_MASK;
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data++;
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get rid of the data type */
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_msg->len--;
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_msg->offset++;
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (ttype)
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_HANDSHAKE:
8262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback(dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_HANDSHAKE, param, NULL);
827258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov        osi_freebuf (p_msg);
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_CONTROL:
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (param)
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG:
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            hidh_conn_disconnect( dhandle ) ;
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Device is unplugging from us. Tell USB */
8362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            hh_cb.callback(dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_VC_UNPLUG, 0, NULL);
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
842258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov        osi_freebuf (p_msg);
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_DATA:
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        evt = (hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid) ?
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    HID_HDEV_EVT_INTR_DATA : HID_HDEV_EVT_CTRL_DATA;
8492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback(dhandle, hh_cb.devices[dhandle].addr, evt, rep_type, p_msg);
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_DATAC:
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        evt = (hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid) ?
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    HID_HDEV_EVT_INTR_DATC : HID_HDEV_EVT_CTRL_DATC;
8552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback(dhandle,  hh_cb.devices[dhandle].addr, evt, rep_type, p_msg);
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    default:
859258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov        osi_freebuf (p_msg);
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_conn_snd_data
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is sends out data.
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          tHID_STATUS
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                UINT16 data, UINT8 report_id, BT_HDR *buf)
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_CONN   *p_hcon = &hh_cb.devices[dhandle].conn;
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_buf;
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_out;
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      bytes_copied;
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     seg_req = FALSE;
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      data_size;
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      cid;
8842e3d006b96eafb0651fe7f78d28250faf89405dePavlin Radoslavov    UINT16      buf_size;
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       use_data = 0 ;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     blank_datc = FALSE;
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8888fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR))
8898fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
8908fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (buf)
891258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov            osi_freebuf ((void *)buf);
8928fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return( HID_ERR_NO_CONNECTION );
8938fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
8948fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED)
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (buf)
898258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov            osi_freebuf ((void *)buf);
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return( HID_ERR_CONGESTED );
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch( trans_type )
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_CONTROL:
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_GET_REPORT:
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_SET_REPORT:
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_GET_PROTOCOL:
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_SET_PROTOCOL:
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_GET_IDLE:
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_SET_IDLE:
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cid = p_hcon->ctrl_cid;
9122e3d006b96eafb0651fe7f78d28250faf89405dePavlin Radoslavov        buf_size = HID_CONTROL_BUF_SIZE;
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case HID_TRANS_DATA:
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cid = p_hcon->intr_cid;
9162e3d006b96eafb0651fe7f78d28250faf89405dePavlin Radoslavov        buf_size = HID_INTERRUPT_BUF_SIZE;
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    default:
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (HID_ERR_INVALID_PARAM) ;
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( trans_type == HID_TRANS_SET_IDLE )
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        use_data = 1;
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if( (trans_type == HID_TRANS_GET_REPORT) && (param & 0x08) )
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        use_data = 2;
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    do
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( buf == NULL || blank_datc )
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
931258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov            p_buf = (BT_HDR *)osi_getbuf(buf_size);
9322e3d006b96eafb0651fe7f78d28250faf89405dePavlin Radoslavov            if (p_buf == NULL)
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (HID_ERR_NO_RESOURCES);
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset = L2CAP_MIN_OFFSET;
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            seg_req = FALSE;
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            data_size = 0;
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bytes_copied = 0;
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            blank_datc = FALSE;
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if ( (buf->len > (p_hcon->rem_mtu_size - 1)))
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
943258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov            p_buf = (BT_HDR *)osi_getbuf(buf_size);
9442e3d006b96eafb0651fe7f78d28250faf89405dePavlin Radoslavov            if (p_buf == NULL)
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (HID_ERR_NO_RESOURCES);
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset = L2CAP_MIN_OFFSET;
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            seg_req = TRUE;
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            data_size = buf->len;
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bytes_copied = p_hcon->rem_mtu_size - 1;
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf = buf ;
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset -= 1;
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            seg_req = FALSE;
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            data_size = buf->len;
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            bytes_copied = buf->len;
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_out         = (UINT8 *)(p_buf + 1) + p_buf->offset;
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_out++      = HID_BUILD_HDR(trans_type, param);
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If report ID required for this device */
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if( (trans_type == HID_TRANS_GET_REPORT) && (report_id != 0) )
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_out = report_id;
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            data_size = bytes_copied = 1;
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (seg_req)
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_out, (((UINT8 *)(buf+1)) + buf->offset), bytes_copied);
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            buf->offset += bytes_copied;
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            buf->len -= bytes_copied;
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if( use_data == 1)
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *(p_out+bytes_copied) = data & 0xff;
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if( use_data == 2 )
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *(p_out+bytes_copied) = data & 0xff;
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *(p_out+bytes_copied+1) = (data >> 8) & 0xff ;
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len   = bytes_copied + 1 + use_data;
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        data_size    -= bytes_copied;
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Send the buffer through L2CAP */
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || (!L2CA_DataWrite (cid, p_buf)))
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (HID_ERR_CONGESTED);
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (data_size)
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            trans_type = HID_TRANS_DATAC;
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if( bytes_copied == (p_hcon->rem_mtu_size - 1) )
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            trans_type = HID_TRANS_DATAC;
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            blank_datc = TRUE;
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } while ((data_size != 0) || blank_datc ) ;
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (HID_SUCCESS);
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_conn_initiate
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called by the management to create a connection.
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttHID_STATUS hidh_conn_initiate (UINT8 dhandle)
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8   service_id = BTM_SEC_SERVICE_HIDH_NOSEC_CTRL;
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32  mx_chan_id = HID_NOSEC_CHN;
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle];
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( p_dev->conn.conn_state != HID_CONN_STATE_UNUSED )
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return( HID_ERR_CONN_IN_PROCESS );
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev->conn.ctrl_cid = 0;
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev->conn.intr_cid = 0;
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL;  /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* We are the originator of this connection */
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG;
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p_dev->attr_mask & HID_SEC_REQUIRED)
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        service_id = BTM_SEC_SERVICE_HIDH_SEC_CTRL;
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mx_chan_id = HID_SEC_CHN;
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BTM_SetOutService (p_dev->addr, service_id, mx_chan_id);
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if L2CAP started the connection process */
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq (HID_PSM_CONTROL, p_dev->addr)) == 0)
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1043d6e1b1ee17959461a80936f7308d8129615315d2Sharvil Nanavati        HIDH_TRACE_WARNING ("HID-Host Originate failed");
10442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE,
10452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                                HID_ERR_L2CAP_FAILED, NULL ) ;
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Transition to the next appropriate state, waiting for connection confirm on control channel. */
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return( HID_SUCCESS );
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         find_conn_by_cid
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function finds a connection control block based on CID
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          address of control block, or NULL if not found
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic UINT8 find_conn_by_cid (UINT16 cid)
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8      xx;
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++)
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((hh_cb.devices[xx].in_use) && (hh_cb.devices[xx].conn.conn_state != HID_CONN_STATE_UNUSED)
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            && ((hh_cb.devices[xx].conn.ctrl_cid == cid) || (hh_cb.devices[xx].conn.intr_cid == cid)))
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (xx);
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid hidh_conn_dereg( void )
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_Deregister (HID_PSM_CONTROL);
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CA_Deregister (HID_PSM_INTERRUPT);
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         hidh_conn_retry
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to retry a failed connection.
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void hidh_conn_retry(  UINT8 dhandle )
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle];
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
1100bb95452741bfd65723ea417c25dbd326c7568ab7Arman Uguray    p_dev->conn.timer_entry.param = UINT_TO_PTR(dhandle);
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (HID_HOST_REPAGE_WIN > 0)
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_start_timer (&(p_dev->conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN);
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    hidh_proc_repage_timeout( &(p_dev->conn.timer_entry) );
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1107