18843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/****************************************************************************** 28843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 38843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Copyright (C) 2016 The Android Open Source Project 48843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Copyright (C) 2002-2012 Broadcom Corporation 58843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 68843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 78843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * you may not use this file except in compliance with the License. 88843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * You may obtain a copy of the License at: 98843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Unless required by applicable law or agreed to in writing, software 138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * See the License for the specific language governing permissions and 168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * limitations under the License. 178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/****************************************************************************** 218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * this file contains the connection interface functions 238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include <stdio.h> 278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include <stdlib.h> 288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include <string.h> 298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "bt_types.h" 318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "l2c_api.h" 338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "l2cdefs.h" 348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "btm_api.h" 368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "btm_int.h" 378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "btu.h" 388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "hiddefs.h" 408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "bt_utils.h" 428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "hidd_api.h" 438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "hidd_int.h" 448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#include "osi/include/osi.h" 468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm, 488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t id); 498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result); 508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg); 518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO* p_cfg); 528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed); 538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result); 548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg); 558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_cong_ind(uint16_t cid, bool congested); 568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic const tL2CAP_APPL_INFO dev_reg_info = {hidd_l2cif_connect_ind, 588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_connect_cfm, 598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL, 608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_config_ind, 618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_config_cfm, 628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_disconnect_ind, 638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_disconnect_cfm, 648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL, 658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_data_ind, 668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_l2cif_cong_ind, 678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL}; 688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_check_config_done 728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Checks if connection is configured and callback can be fired 748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_check_config_done() { 798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == 848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_CONN_FLAGS_ALL_CONFIGURED) && 858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) { 868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_CONNECTED; 878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.state = HIDD_DEV_CONNECTED; 898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_OPEN, 0, NULL); 918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // send outstanding data on intr 938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.pending_data) { 948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data); 958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_data = NULL; 968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 1018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidh_sec_check_complete_term 1038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description HID security check complete callback function. 1058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns Send L2CA_ConnectRsp OK if secutiry check succeed; otherwise 1078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * send security block L2C connection response. 1088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 1108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr, 1118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta UNUSED_ATTR tBT_TRANSPORT transport, 1128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta void* p_ref_data, uint8_t res) { 1138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data; 1148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) { 1168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.disc_reason = HID_SUCCESS; 1178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR; 1188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, 1208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CAP_CONN_OK, L2CAP_CONN_OK); 1218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg); 1228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else if (res != BTM_SUCCESS) { 1238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: connection rejected by security", __func__); 1248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; 1268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_state = HID_CONN_STATE_UNUSED; 1278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, 1288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK); 1298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 1308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 1318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 1328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 1348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_sec_check_complete_orig 1368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description HID security check complete callback function (device 1388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta*originated) 1398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 1418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 1438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptavoid hidd_sec_check_complete_orig(UNUSED_ATTR BD_ADDR bd_addr, 1448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta UNUSED_ATTR tBT_TRANSPORT transport, 1458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta void* p_ref_data, uint8_t res) { 1468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data; 1478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_dev->conn.conn_state != HID_CONN_STATE_SECURITY) { 1498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: invalid state (%02x)", __func__, 1508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_state); 1518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 1528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 1538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (res == BTM_SUCCESS) { 1558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: security ok", __func__); 1568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.disc_reason = HID_SUCCESS; 1578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_state = HID_CONN_STATE_CONFIG; 1598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg); 1608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 1618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: security check failed (%02x)", __func__, res); 1628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; 1638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 1648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 1658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 1668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 1688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_connect_ind 1708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles incoming L2CAP connection (we act as server) 1728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 1748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 1758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 1768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm, 1778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t id) { 1788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 1798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_DEV_DEV_CTB* p_dev; 1808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta bool accept = TRUE; // accept by default 1818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: psm=%04x cid=%04x id=%02x", __func__, psm, cid, id); 1838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev = &hd_cb.device; 1858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!hd_cb.allow_incoming) { 1878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: incoming connections not allowed, rejecting", 1888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__); 1898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0); 1908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 1918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 1928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 1938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_dev->in_use && memcmp(bd_addr, p_dev->addr, sizeof(BD_ADDR))) { 1948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING( 1958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta "%s: incoming connections from different device, rejecting", __func__); 1968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0); 1978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 1988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else if (!p_dev->in_use) { 1998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->in_use = TRUE; 2008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memcpy(p_dev->addr, bd_addr, sizeof(BD_ADDR)); 2018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->state = HIDD_DEV_NO_CONN; 2028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 2058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta switch (psm) { 2078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_PSM_INTERRUPT: 2088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->ctrl_cid == 0) { 2098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta accept = FALSE; 2108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: incoming INTR without CTRL, rejecting", 2118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__); 2128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) { 2158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta accept = FALSE; 2168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: incoming INTR in invalid state (%d), rejecting", 2178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__, p_hcon->conn_state); 2188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 2218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_PSM_CONTROL: 2238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) { 2248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta accept = FALSE; 2258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: incoming CTRL in invalid state (%d), rejecting", 2268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__, p_hcon->conn_state); 2278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 2308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta default: 2328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta accept = FALSE; 2338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_ERROR("%s: received invalid PSM, rejecting", __func__); 2348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 2358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!accept) { 2388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0); 2398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 2408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // for CTRL we need to go through security and we reply in callback from there 2438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (psm == HID_PSM_CONTROL) { 2448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags = 0; 2458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->ctrl_cid = cid; 2468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->ctrl_id = id; 2478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; 2488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_SECURITY; 2508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, FALSE, 2518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta BTM_SEC_PROTO_HID, HIDD_NOSEC_CHN, 2528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta &hidd_sec_check_complete, 2538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev) == BTM_CMD_STARTED) { 2548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_PENDING, L2CAP_CONN_OK); 2558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 2588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // for INTR we go directly to config state 2618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_CONFIG; 2628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->intr_cid = cid; 2638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_OK, L2CAP_CONN_OK); 2658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg); 2668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 2678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 2698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 2708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_connect_cfm 2718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 2728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles L2CAP connection response (we act as client) 2738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 2748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 2758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 2768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 2778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) { 2788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_DEV_DEV_CTB* p_dev = &hd_cb.device; 2798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon = &hd_cb.device.conn; 2808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result); 2828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { 2848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 2858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 2868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) || 2898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ((cid == p_hcon->ctrl_cid) && 2908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL)) || 2918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ((cid == p_hcon->intr_cid) && 2928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR))) { 2938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unexpected", __func__); 2948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 2958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 2968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 2978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (result != L2CAP_CONN_OK) { 2988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__); 2998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) 3018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->ctrl_cid = 0; 3028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta else 3038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->intr_cid = 0; 3048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 3068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, 3088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL); 3098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 3108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta /* CTRL connect conf */ 3138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) { 3148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_SECURITY; 3158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason = 3168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_L2CAP_CONN_FAIL; /* in case disconnected before sec completed */ 3178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, TRUE, 3198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta BTM_SEC_PROTO_HID, HIDD_SEC_CHN, 3208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta &hidd_sec_check_complete_orig, p_dev); 3218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 3228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_CONFIG; 3238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg); 3248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 3278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 3288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 3308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_config_ind 3328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles incoming L2CAP configuration request 3348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 3368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 3388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { 3398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 3408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); 3428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 3448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { 3468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 3478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 3488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE)) 3518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->rem_mtu_size = HID_DEV_MTU_SIZE; 3528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta else 3538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->rem_mtu_size = p_cfg->mtu; 3548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // accept without changes 3568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->flush_to_present = FALSE; 3578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->mtu_present = FALSE; 3588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->result = L2CAP_CFG_OK; 3598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->intr_cid && hd_cb.use_in_qos && !p_cfg->qos_present) { 3618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->qos_present = TRUE; 3628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memcpy(&p_cfg->qos, &hd_cb.in_qos, sizeof(FLOW_SPEC)); 3638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigRsp(cid, p_cfg); 3668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // update flags 3688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) { 3698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; 3708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && 3728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { 3738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; 3748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->intr_cid = 3758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { 3768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 377367373ba8bcfb1d9db41b1904de372483991fc10Ivan Podogov p_hcon->conn_state = HID_CONN_STATE_UNUSED; 3788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR", 3808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__); 3818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, 3828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_ERR_L2CAP_FAILED, NULL); 3838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 3848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 3858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR; 3868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 3898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE; 3908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 3918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_check_config_done(); 3938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 3948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 3958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 3968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_config_cfm 3988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 3998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles incoming L2CAP configuration response 4008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 4028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 4048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { 4058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 4068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint32_t reason; 4078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid, 4098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->result); 4108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 4128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { 4148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 4158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->intr_cid == cid && 4198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) { 4208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tL2CAP_CFG_INFO new_qos; 4218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // QoS parameters not accepted for intr, try again with host proposal 4238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memcpy(&new_qos, &hd_cb.l2cap_intr_cfg, sizeof(new_qos)); 4258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memcpy(&new_qos.qos, &p_cfg->qos, sizeof(FLOW_SPEC)); 4268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta new_qos.qos_present = TRUE; 4278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: config failed, retry", __func__); 4298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(cid, &new_qos); 4318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else if (p_hcon->intr_cid == cid && 4338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_cfg->result == L2CAP_CFG_UNKNOWN_OPTIONS) { 4348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // QoS not understood by remote device, try configuring without QoS 4358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: config failed, retry without QoS", __func__); 4378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConfigReq(cid, &hd_cb.l2cap_cfg); 4398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else if (p_cfg->result != L2CAP_CFG_OK) { 4418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: config failed, disconnecting", __func__); 4428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 4448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta reason = HID_L2CAP_CFG_FAIL | (uint32_t)p_cfg->result; 4458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, reason, NULL); 4478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // update flags 4518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) { 4528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; 4538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && 4558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) { 4568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; 4578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->intr_cid = 4588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { 4598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 460367373ba8bcfb1d9db41b1904de372483991fc10Ivan Podogov p_hcon->conn_state = HID_CONN_STATE_UNUSED; 4618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR", 4638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__); 4648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, 4658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_ERR_L2CAP_FAILED, NULL); 4668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 4688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR; 4698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 4728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE; 4738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_check_config_done(); 4768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 4778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 4798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_disconnect_ind 4818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handler incoming L2CAP disconnection request 4838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 4858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 4868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 4878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) { 4888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 4898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed); 4918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 4938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 4948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || 4958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { 4968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 4978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 4988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 4998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (ack_needed) L2CA_DisconnectRsp(cid); 5018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; 5038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) 5058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->ctrl_cid = 0; 5068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta else 5078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->intr_cid = 0; 5088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) { 5108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__); 5118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // clean any outstanding data on intr 5138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.pending_data) { 5148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(hd_cb.pending_data); 5158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_data = NULL; 5168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.state = HIDD_DEV_NO_CONN; 5198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_UNUSED; 5208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, p_hcon->disc_reason, 5228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 5238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 5258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 5278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_disconnect_cfm 5298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles L2CAP disconection response 5318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 5338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 5358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result) { 5368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 5378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result); 5398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 5418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || 5438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { 5448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 5458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 5468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (cid == p_hcon->ctrl_cid) { 5498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->ctrl_cid = 0; 5508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 5518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->intr_cid = 0; 5528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // now disconnect CTRL 5548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_DisconnectReq(p_hcon->ctrl_cid); 5558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) { 5588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__); 5598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.state = HIDD_DEV_NO_CONN; 5618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_UNUSED; 5628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.pending_vc_unplug) { 5648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_VC_UNPLUG, 5658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason, NULL); 5668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_vc_unplug = FALSE; 5678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 5688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, 5698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->disc_reason, NULL); 5708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 5738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 5758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_cong_ind 5778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handles L2CAP congestion status event 5798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 5818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 5828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 5838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_cong_ind(uint16_t cid, bool congested) { 5848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 5858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested); 5878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 5898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || 5918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { 5928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 5938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 5948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 5958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 5968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (congested) { 5978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED; 5988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 5998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_flags &= ~HID_CONN_FLAGS_CONGESTED; 6008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 6028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 6048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 6058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_l2cif_data_ind 6068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 6078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Handler incoming data on L2CAP channel 6088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 6098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 6108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 6118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 6128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptastatic void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { 6138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 6148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t* p_data = (uint8_t*)(p_msg + 1) + p_msg->offset; 6158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t msg_type, param; 6168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta bool err = FALSE; 6178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); 6198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 6218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || 6238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { 6248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: unknown cid", __func__); 6258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 6268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 6278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta msg_type = HID_GET_TRANS_FROM_HDR(*p_data); 6308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta param = HID_GET_PARAM_FROM_HDR(*p_data); 6318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) { 6338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // skip HID header 6348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_msg->offset++; 6358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_msg->len--; 6368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_INTR_DATA, 0, p_msg); 6388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return; 6398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta switch (msg_type) { 6428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_GET_REPORT: 6438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // at this stage we don't know if Report Id shall be included in request 6448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // so we pass complete packet in callback and let other code analyze this 6458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_GET_REPORT, 6468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta !!(param & HID_PAR_GET_REP_BUFSIZE_FOLLOWS), p_msg); 6478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 6488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_SET_REPORT: 6508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // as above 6518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_REPORT, 0, p_msg); 6528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 6538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_GET_IDLE: 6558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, 6568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_PAR_REP_TYPE_OTHER, hd_cb.device.idle_time, 0, 6578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 6588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 6598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 6608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_SET_IDLE: 6628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_msg->len != 2) { 6638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_ERROR("%s: invalid len (%d) set idle request received", 6648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta __func__, p_msg->len); 6658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta err = TRUE; 6668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 6678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.idle_time = p_data[1]; 6688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_DEBUG("%s: idle_time = %d", __func__, 6698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.idle_time); 6708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.device.idle_time) { 6718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING( 6728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta "%s: idle_time of %d ms not supported by HID Device", __func__, 6738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta (hd_cb.device.idle_time * 4)); 6748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta err = TRUE; 6758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!err) { 6788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, 6798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_PAR_HANDSHAKE_RSP_SUCCESS, 0, 0, NULL); 6808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 6818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, 6828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM, 0, 0, 6838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 6848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 6858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 6868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 6878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_GET_PROTOCOL: 6898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, 6908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_PAR_REP_TYPE_OTHER, !hd_cb.device.boot_mode, 0, 6918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 6928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 6938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 6948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 6958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_SET_PROTOCOL: 6968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.device.boot_mode = !(param & HID_PAR_PROTOCOL_MASK); 6978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_PROTOCOL, 6988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta param & HID_PAR_PROTOCOL_MASK, NULL); 6998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_SUCCESS, 7008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 0, 0, NULL); 7018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 7028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_CONTROL: 7058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta switch (param) { 7068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_PAR_CONTROL_SUSPEND: 7078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SUSPEND, 0, NULL); 7088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_PAR_CONTROL_EXIT_SUSPEND: 7118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_EXIT_SUSPEND, 0, 7128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 7138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG: 7168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_disconnect(); 7178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // set flag so we can notify properly when disconnected 7198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_vc_unplug = TRUE; 7208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 7228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 7248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_DATA: 7278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta default: 7288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: got unsupported msg (%d)", __func__, msg_type); 7298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, 7308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ, 0, 0, 7318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 7328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(p_msg); 7338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 7348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 7358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 7368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 7388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_conn_reg 7408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Registers L2CAP channels 7428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 7448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 7468843cc830b522cfe6f1e361297fc28fd331a1378Hemant GuptatHID_STATUS hidd_conn_reg(void) { 7478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_API("%s", __func__); 7488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memset(&hd_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO)); 7508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_cfg.mtu_present = TRUE; 7528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_cfg.mtu = HID_DEV_MTU_SIZE; 7538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_cfg.flush_to_present = TRUE; 7548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_cfg.flush_to = HID_DEV_FLUSH_TO; 7558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memset(&hd_cb.l2cap_intr_cfg, 0, sizeof(tL2CAP_CFG_INFO)); 7578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_intr_cfg.mtu_present = TRUE; 7588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_intr_cfg.mtu = HID_DEV_MTU_SIZE; 7598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_intr_cfg.flush_to_present = TRUE; 7608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.l2cap_intr_cfg.flush_to = HID_DEV_FLUSH_TO; 7618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&dev_reg_info)) { 7638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_ERROR("HID Control (device) registration failed"); 7648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_ERR_L2CAP_FAILED); 7658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 7668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&dev_reg_info)) { 7688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_Deregister(HID_PSM_CONTROL); 7698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_ERROR("HID Interrupt (device) registration failed"); 7708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_ERR_L2CAP_FAILED); 7718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 7728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_SUCCESS); 7748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 7758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 7778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_conn_dereg 7798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Deregisters L2CAP channels 7818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns void 7838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 7858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Guptavoid hidd_conn_dereg(void) { 7868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_API("%s", __func__); 7878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7888843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_Deregister(HID_PSM_CONTROL); 7898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_Deregister(HID_PSM_INTERRUPT); 7908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 7918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 7928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 7938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_conn_initiate 7958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Initiates HID connection to plugged device 7978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 7988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns HID_SUCCESS 7998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 8018843cc830b522cfe6f1e361297fc28fd331a1378Hemant GuptatHID_STATUS hidd_conn_initiate(void) { 8028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_DEV_DEV_CTB* p_dev = &hd_cb.device; 8038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_API("%s", __func__); 8058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!p_dev->in_use) { 8078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: no virtual cable established", __func__); 8088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_ERR_NOT_REGISTERED); 8098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) { 8128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: connection already in progress", __func__); 8138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_ERR_CONN_IN_PROCESS); 8148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.ctrl_cid = 0; 8178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.intr_cid = 0; 8188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; 8198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; 8218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN); 8238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta /* Check if L2CAP started the connection process */ 8258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 8268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 0) { 8278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: could not start L2CAP connection", __func__); 8288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, 8298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta NULL); 8308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 8318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL; 8328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_SUCCESS); 8358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 8368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 8388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_conn_disconnect 8408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Disconnects existing HID connection 8428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns HID_SUCCESS 8448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 8468843cc830b522cfe6f1e361297fc28fd331a1378Hemant GuptatHID_STATUS hidd_conn_disconnect(void) { 8478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 8488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_API("%s", __func__); 8508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // clean any outstanding data on intr 8528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.pending_data) { 8538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(hd_cb.pending_data); 8548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_data = NULL; 8558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 8588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0)) { 8608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; 8618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta /* Set l2cap idle timeout to 0 (so ACL link is disconnected 8638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * immediately after last channel is closed) */ 8648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_SetIdleTimeoutByBdAddr(hd_cb.device.addr, 0, BT_TRANSPORT_BR_EDR); 8658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->intr_cid) { 8678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_DisconnectReq(p_hcon->intr_cid); 8688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else if (p_hcon->ctrl_cid) { 8698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta L2CA_DisconnectReq(p_hcon->ctrl_cid); 8708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 8728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_WARNING("%s: already disconnected", __func__); 8738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon->conn_state = HID_CONN_STATE_UNUSED; 8748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 8758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_SUCCESS); 8778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 8788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta/******************************************************************************* 8808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8818843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Function hidd_conn_send_data 8828843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8838843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Description Sends data to host 8848843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8858843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * Returns tHID_STATUS 8868843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta * 8878843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta ******************************************************************************/ 8888843cc830b522cfe6f1e361297fc28fd331a1378Hemant GuptatHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, 8898843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t param, uint8_t data, uint16_t len, 8908843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t* p_data) { 8918843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta tHID_CONN* p_hcon; 8928843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta BT_HDR* p_buf; 8938843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint8_t* p_out; 8948843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint16_t cid; 8958843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta uint16_t buf_size; 8968843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 8978843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__, 8988843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta channel, msg_type, len); 8998843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9008843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_hcon = &hd_cb.device.conn; 9018843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9028843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) { 9038843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return HID_ERR_CONGESTED; 9048843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9058843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9068843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta switch (msg_type) { 9078843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_HANDSHAKE: 9088843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_CONTROL: 9098843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta cid = p_hcon->ctrl_cid; 9108843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta buf_size = HID_CONTROL_BUF_SIZE; 9118843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 9128843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta case HID_TRANS_DATA: 9138843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (channel == HID_CHANNEL_CTRL) { 9148843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta cid = p_hcon->ctrl_cid; 9158843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta buf_size = HID_CONTROL_BUF_SIZE; 9168843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } else { 9178843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta cid = p_hcon->intr_cid; 9188843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta buf_size = HID_INTERRUPT_BUF_SIZE; 9198843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9208843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta break; 9218843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta default: 9228843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_ERR_INVALID_PARAM); 9238843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9248843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9258843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_buf = (BT_HDR*)osi_malloc(buf_size); 9268843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (p_buf == NULL) return (HID_ERR_NO_RESOURCES); 9278843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9288843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_buf->offset = L2CAP_MIN_OFFSET; 9298843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9308843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_out = (uint8_t*)(p_buf + 1) + p_buf->offset; 9318843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9328843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta *p_out = HID_BUILD_HDR(msg_type, param); 9338843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_out++; 9348843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9358843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_buf->len = 1; // start with header only 9368843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9378843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // add report id prefix only if non-zero (which is reserved) 9388843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (msg_type == HID_TRANS_DATA && (data || param == HID_PAR_REP_TYPE_OTHER)) { 9398843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta *p_out = data; // report_id 9408843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_out++; 9418843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_buf->len++; 9428843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9438843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9448843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (len > 0 && p_data != NULL) { 9458843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta memcpy(p_out, p_data, len); 9468843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta p_buf->len += len; 9478843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9488843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9498843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // check if connected 9508843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.device.state != HIDD_DEV_CONNECTED) { 9518843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // for DATA on intr we hold transfer and try to reconnect 9528843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) { 9538843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta // drop previous data, we do not queue it for now 9548843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.pending_data) { 9558843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta osi_free(hd_cb.pending_data); 9568843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9578843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9588843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hd_cb.pending_data = p_buf; 9598843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9608843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (hd_cb.device.conn.conn_state == HID_CONN_STATE_UNUSED) { 9618843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta hidd_conn_initiate(); 9628843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9638843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9648843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return HID_SUCCESS; 9658843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9668843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9678843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return HID_ERR_NO_CONNECTION; 9688843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9698843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9708843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#ifdef REPORT_TRANSFER_TIMESTAMP 9718843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (report_transfer) { 9728843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_ERROR("%s: report sent", __func__); 9738843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta } 9748843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta#endif 9758843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta HIDD_TRACE_VERBOSE("%s: report sent", __func__); 9768843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9778843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta if (!L2CA_DataWrite(cid, p_buf)) return (HID_ERR_CONGESTED); 9788843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta 9798843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta return (HID_SUCCESS); 9808843cc830b522cfe6f1e361297fc28fd331a1378Hemant Gupta} 981