Fork ESP-IDF's bluetooth component
i want better sbc encoding, and no cla will stop me
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,477 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID HOST API in the subsystem of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bta/bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#include "bta/utl.h"
|
||||
|
||||
#include "osi/allocator.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_hh_reg = {
|
||||
bta_hh_hdl_event,
|
||||
BTA_HhDisable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhEnable
|
||||
**
|
||||
** Description Enable the HID host. This function must be called before
|
||||
** any other functions in the HID host API are called. When the
|
||||
** enable operation is complete the callback function will be
|
||||
** called with BTA_HH_ENABLE_EVT.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
|
||||
{
|
||||
tBTA_HH_API_ENABLE *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_HH, &bta_hh_reg);
|
||||
|
||||
APPL_TRACE_API("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
|
||||
p_buf = (tBTA_HH_API_ENABLE *)osi_malloc((UINT16)sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhDisable
|
||||
**
|
||||
** Description Disable the HID host. If the server is currently
|
||||
** connected, the connection will be closed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
bta_sys_deregister(BTA_ID_HH);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HH_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhClose
|
||||
**
|
||||
** Description Disconnect a connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhClose(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhOpen
|
||||
**
|
||||
** Description Connect to a device of specified BD address in specified
|
||||
** protocol mode and security level.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
|
||||
{
|
||||
tBTA_HH_API_CONN *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_API_CONN *)osi_malloc((UINT16)sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset((void *)p_buf, 0, sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
p_buf->mode = mode;
|
||||
bdcpy(p_buf->bd_addr, dev_bda);
|
||||
|
||||
bta_sys_sendmsg((void *)p_buf);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("No resource to send HID host Connect request.");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_snd_write_dev
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
|
||||
UINT16 data, UINT8 rpt_id, BT_HDR *p_data)
|
||||
{
|
||||
tBTA_HH_CMD_DATA *p_buf;
|
||||
UINT16 len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
|
||||
|
||||
if ((p_buf = (tBTA_HH_CMD_DATA *)osi_malloc(len)) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->t_type = t_type;
|
||||
p_buf->data = data;
|
||||
p_buf->param = param;
|
||||
p_buf->p_data = p_data;
|
||||
p_buf->rpt_id = rpt_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetReport
|
||||
**
|
||||
** Description send SET_REPORT to device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** r_type: report type, could be BTA_HH_RPTT_OUTPUT or
|
||||
** BTA_HH_RPTT_FEATURE.
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetReport
|
||||
**
|
||||
** Description Send a GET_REPORT to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
|
||||
{
|
||||
UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
|
||||
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
|
||||
buf_size, rpt_id, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetProtoMode
|
||||
**
|
||||
** Description This function set the protocol mode at specified HID handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
|
||||
0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetProtoMode
|
||||
**
|
||||
** Description This function get protocol mode information.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetProtoMode(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE from HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetIdle(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendCtrl
|
||||
**
|
||||
** Description Send a control command to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendData
|
||||
**
|
||||
** Description This function send DATA transaction to HID device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** dev_bda: remote device address
|
||||
** p_data: data to be sent in the DATA transaction; or
|
||||
** the data to be write into the Output Report of a LE HID
|
||||
** device. The report is identified the report ID which is
|
||||
** the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
|
||||
** p_data->layer_specific needs to be set to the report type,
|
||||
** it can be OUTPUT report, or FEATURE report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
|
||||
{
|
||||
UNUSED(dev_bda);
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
|
||||
APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetDscpInfo
|
||||
**
|
||||
** Description Get HID device report descriptor
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetDscpInfo(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_GET_DSCP_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhAddDev
|
||||
**
|
||||
** Description Add a virtually cabled device into HID-Host device list
|
||||
** to manage and assign a device handle for future API call,
|
||||
** host applciation call this API at start-up to initialize its
|
||||
** virtually cabled devices.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
|
||||
UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
UINT16 len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)osi_malloc(len);
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_ADD_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
p_buf->attr_mask = (UINT16) attr_mask;
|
||||
p_buf->sub_class = sub_class;
|
||||
p_buf->app_id = app_id;
|
||||
bdcpy(p_buf->bda, bda);
|
||||
|
||||
memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
|
||||
if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
|
||||
p_buf->dscp_info.descriptor.dl_len = dscp_info.descriptor.dl_len;
|
||||
p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
|
||||
} else {
|
||||
p_buf->dscp_info.descriptor.dsc_list = NULL;
|
||||
p_buf->dscp_info.descriptor.dl_len = 0;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRemoveDev
|
||||
**
|
||||
** Description Remove a device from the HID host devices list.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhRemoveDev(UINT8 dev_handle )
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)osi_malloc((UINT16)sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_RMV_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhUpdateLeScanParam
|
||||
**
|
||||
** Description Update the scan paramteters if connected to a LE hid device as
|
||||
** report host.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win)
|
||||
{
|
||||
tBTA_HH_SCPP_UPDATE *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_SCPP_UPDATE *)osi_malloc((UINT16)sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_SCPP_UPDATE_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->scan_int = scan_int;
|
||||
p_buf->scan_win = scan_win;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************/
|
||||
/* Utility Function */
|
||||
/*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhParseBootRpt
|
||||
**
|
||||
** Description This utility function parse a boot mode report.
|
||||
** For keyboard report, report data will carry the keycode max
|
||||
** up to 6 key press in one report. Application need to convert
|
||||
** the keycode into keypress character according to keyboard
|
||||
** language.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
|
||||
|
||||
if (p_report) {
|
||||
/* first byte is report ID */
|
||||
switch (p_report[0]) {
|
||||
case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_DEBUG("Unknown boot report: %d", p_report[0]);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
@@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains compile-time configurable constants for the BTA Hid
|
||||
* Host.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
#include "bta/bta_hh_api.h"
|
||||
|
||||
|
||||
/* max number of device types supported by BTA */
|
||||
#define BTA_HH_MAX_DEVT_SPT 9
|
||||
|
||||
/* size of database for service discovery */
|
||||
#ifndef BTA_HH_DISC_BUF_SIZE
|
||||
#define BTA_HH_DISC_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The type of devices supported by BTA HH and corresponding application ID */
|
||||
tBTA_HH_SPT_TOD p_devt_list[BTA_HH_MAX_DEVT_SPT] = {
|
||||
{BTA_HH_DEVT_MIC, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_KBD, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_KBD | BTA_HH_DEVT_MIC, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_RMC, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_RMC | BTA_HH_DEVT_KBD, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_MIC | BTA_HH_DEVT_DGT, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_JOS, BTA_HH_APP_ID_JOY},
|
||||
{BTA_HH_DEVT_GPD, BTA_HH_APP_ID_GPAD},
|
||||
{BTA_HH_DEVT_UNKNOWN, BTA_HH_APP_ID_3DSG}
|
||||
};
|
||||
|
||||
|
||||
const tBTA_HH_CFG bta_hh_cfg = {
|
||||
BTA_HH_MAX_DEVT_SPT, /* number of supported type of devices */
|
||||
p_devt_list, /* ToD & AppID list */
|
||||
BTA_HH_DISC_BUF_SIZE /* HH SDP discovery database size */
|
||||
};
|
||||
|
||||
|
||||
tBTA_HH_CFG *p_bta_hh_cfg = (tBTA_HH_CFG *) &bta_hh_cfg;
|
||||
#endif ///defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,568 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID host main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta/bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_HH_API_DISC_ACT, /* HID host process API close action */
|
||||
BTA_HH_OPEN_ACT, /* HID host process BTA_HH_EVT_OPEN */
|
||||
BTA_HH_CLOSE_ACT, /* HID host process BTA_HH_EVT_CLOSE */
|
||||
BTA_HH_DATA_ACT, /* HID host receive data report */
|
||||
BTA_HH_CTRL_DAT_ACT,
|
||||
BTA_HH_HANDSK_ACT,
|
||||
BTA_HH_START_SDP, /* HID host inquery */
|
||||
BTA_HH_SDP_CMPL,
|
||||
BTA_HH_WRITE_DEV_ACT,
|
||||
BTA_HH_GET_DSCP_ACT,
|
||||
BTA_HH_MAINT_DEV_ACT,
|
||||
BTA_HH_OPEN_CMPL_ACT,
|
||||
BTA_HH_OPEN_FAILURE,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE,
|
||||
BTA_HH_LE_OPEN_FAIL,
|
||||
BTA_HH_GATT_OPEN,
|
||||
BTA_HH_W4_LE_READ_CHAR,
|
||||
BTA_HH_LE_READ_CHAR,
|
||||
BTA_HH_W4_LE_READ_DESCR,
|
||||
BTA_HH_LE_READ_DESCR,
|
||||
BTA_HH_W4_LE_WRITE,
|
||||
BTA_HH_LE_WRITE,
|
||||
BTA_HH_WRITE_DESCR,
|
||||
BTA_HH_START_SEC,
|
||||
BTA_HH_SEC_CMPL,
|
||||
BTA_HH_LE_UPDATE_SCPP,
|
||||
BTA_HH_GATT_ENC_CMPL,
|
||||
#endif
|
||||
BTA_HH_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_HH_IGNORE BTA_HH_NUM_ACTIONS
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
const tBTA_HH_ACTION bta_hh_action[] = {
|
||||
bta_hh_api_disc_act,
|
||||
bta_hh_open_act,
|
||||
bta_hh_close_act,
|
||||
bta_hh_data_act,
|
||||
bta_hh_ctrl_dat_act,
|
||||
bta_hh_handsk_act,
|
||||
bta_hh_start_sdp,
|
||||
bta_hh_sdp_cmpl,
|
||||
bta_hh_write_dev_act,
|
||||
bta_hh_get_dscp_act,
|
||||
bta_hh_maint_dev_act,
|
||||
bta_hh_open_cmpl_act,
|
||||
bta_hh_open_failure
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_gatt_close
|
||||
, bta_hh_le_open_fail
|
||||
, bta_hh_gatt_open
|
||||
, bta_hh_w4_le_read_char_cmpl
|
||||
, bta_hh_le_read_char_cmpl
|
||||
, bta_hh_w4_le_read_descr_cmpl
|
||||
, bta_hh_le_read_descr_cmpl
|
||||
, bta_hh_w4_le_write_cmpl
|
||||
, bta_hh_le_write_cmpl
|
||||
, bta_hh_le_write_char_descr_cmpl
|
||||
, bta_hh_start_security
|
||||
, bta_hh_security_cmpl
|
||||
, bta_hh_le_update_scpp
|
||||
, bta_hh_le_notify_enc_cmpl
|
||||
#endif
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_HH_ACTION 0 /* position of action */
|
||||
#define BTA_HH_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_HH_NUM_COLS 2 /* number of columns */
|
||||
|
||||
/* state table for idle state */
|
||||
const UINT8 bta_hh_st_idle[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_START_SDP, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_SDP_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_START_SEC, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_CHAR, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_W4_LE_WRITE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_connected[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_DATA_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_CTRL_DAT_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_HANDSK_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_GET_DSCP_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_GATT_CLOSE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_LE_READ_CHAR, BTA_HH_CONN_ST }
|
||||
/* WRITE_CHAR_CMPL_EVT*/ , {BTA_HH_LE_WRITE, BTA_HH_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST } /* do not currently read any descr when connection up */
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_CONN_ST } /* do not currently write any descr when connection up */
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_LE_UPDATE_SCPP, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
const UINT8 bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE , BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_GATT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_START_ENC_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_ENC_CMPL_EVT */ {BTA_HH_SEC_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* READ_CHAR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* READ_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* WRITE_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC }
|
||||
};
|
||||
#endif
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_HH_ST_TBL bta_hh_st_tbl[] = {
|
||||
bta_hh_st_idle,
|
||||
bta_hh_st_w4_conn,
|
||||
bta_hh_st_connected
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_st_w4_sec
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HH_CB bta_hh_cb;
|
||||
#else
|
||||
tBTA_HH_CB *bta_hh_cb_ptr;
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Static functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for HID Host
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
tBTA_HH_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
tBTA_HH cback_data;
|
||||
tBTA_HH_EVT cback_event = 0;
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
tBTA_HH_STATE in_state ;
|
||||
UINT16 debug_event = event;
|
||||
#endif
|
||||
|
||||
memset(&cback_data, 0, sizeof(tBTA_HH));
|
||||
|
||||
/* handle exception, no valid control block was found */
|
||||
if (!p_cb) {
|
||||
/* BTA HH enabled already? otherwise ignore the event although it's bad*/
|
||||
if (bta_hh_cb.p_cback != NULL) {
|
||||
switch (event) {
|
||||
/* no control block available for new connection */
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
cback_event = BTA_HH_OPEN_EVT;
|
||||
/* build cback data */
|
||||
bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
|
||||
cback_data.conn.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
|
||||
/* check if host initiate the connection*/
|
||||
cback_data.conn.is_orig = !p_cb->incoming_conn;
|
||||
break;
|
||||
/* DB full, BTA_HhAddDev */
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
cback_event = p_data->api_maintdev.sub_event;
|
||||
|
||||
if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
|
||||
cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
|
||||
} else {
|
||||
cback_data.dev_info.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_info.handle = (UINT8)p_data->api_maintdev.hdr.layer_specific;
|
||||
}
|
||||
break;
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
|
||||
BTA_HH_FST_TRANS_CB_EVT;
|
||||
if (p_data->api_sndcmd.p_data != NULL) {
|
||||
osi_free(p_data->api_sndcmd.p_data);
|
||||
}
|
||||
if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
} else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
|
||||
p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
|
||||
cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
cback_data.hs_data.status = BTA_HH_ERR_HDL;
|
||||
/* hs_data.rsp_data will be all zero, which is not valid value */
|
||||
} else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
|
||||
p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
|
||||
cback_data.status = BTA_HH_ERR_HDL;
|
||||
cback_event = BTA_HH_VC_UNPLUG_EVT;
|
||||
} else {
|
||||
cback_event = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
cback_event = BTA_HH_CLOSE_EVT;
|
||||
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid handle, call bad API event */
|
||||
APPL_TRACE_ERROR("wrong device handle: [%d], event:%d", p_data->hdr.layer_specific, event - BTA_HH_API_OPEN_EVT);
|
||||
/* Free the callback buffer now */
|
||||
if (p_data != NULL && p_data->hid_cback.p_data != NULL) {
|
||||
osi_free(p_data->hid_cback.p_data);
|
||||
p_data->hid_cback.p_data = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cback_event) {
|
||||
(* bta_hh_cb.p_cback)(cback_event, &cback_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* corresponding CB is found, go to state machine */
|
||||
else {
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
in_state = p_cb->state;
|
||||
APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
|
||||
in_state, bta_hh_state_code(in_state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
#endif
|
||||
|
||||
if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) {
|
||||
APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
|
||||
p_cb->state, event);
|
||||
return;
|
||||
}
|
||||
state_table = bta_hh_st_tbl[p_cb->state - 1];
|
||||
|
||||
event &= 0xff;
|
||||
|
||||
p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
|
||||
|
||||
if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE) {
|
||||
(*bta_hh_action[action])(p_cb, p_data);
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
if (in_state != p_cb->state) {
|
||||
APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
|
||||
bta_hh_state_code(in_state),
|
||||
bta_hh_state_code(p_cb->state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_hdl_event
|
||||
**
|
||||
** Description HID host main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
tBTA_HH_DEV_CB *p_cb = NULL;
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
bta_hh_api_disable();
|
||||
break;
|
||||
|
||||
case BTA_HH_DISC_CMPL_EVT: /* disable complete */
|
||||
bta_hh_disc_cmpl();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* all events processed in state machine need to find corresponding
|
||||
CB before proceed */
|
||||
if (p_msg->event == BTA_HH_API_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
|
||||
} else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
|
||||
/* if add device */
|
||||
if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
|
||||
} else { /* else remove device by handle */
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
// btla-specific ++
|
||||
/* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
|
||||
* then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
|
||||
* cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
|
||||
* So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
|
||||
* force the index to be IDX_INVALID
|
||||
*/
|
||||
if ((index != BTA_HH_IDX_INVALID) &&
|
||||
(bta_hh_cb.kdev[index].in_use == FALSE)) {
|
||||
index = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
// btla-specific --
|
||||
}
|
||||
} else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
|
||||
uint8_t hdl = BTA_HH_IDX_INVALID;
|
||||
if (HID_HostGetDev(((tBTA_HH_CBACK_DATA *)p_msg)->addr, &hdl) == HID_SUCCESS && hdl != BTA_HH_IDX_INVALID) {
|
||||
bta_hh_cb.cb_index[hdl] = bta_hh_cb.kdev[index].index;
|
||||
}
|
||||
} else {
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
}
|
||||
|
||||
if (index != BTA_HH_IDX_INVALID) {
|
||||
p_cb = &bta_hh_cb.kdev[index];
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
|
||||
#endif
|
||||
bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_evt_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
return "BTA_HH_API_DISABLE_EVT";
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
return "BTA_HH_API_ENABLE_EVT";
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
return "BTA_HH_API_OPEN_EVT";
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
return "BTA_HH_API_CLOSE_EVT";
|
||||
case BTA_HH_INT_OPEN_EVT:
|
||||
return "BTA_HH_INT_OPEN_EVT";
|
||||
case BTA_HH_INT_CLOSE_EVT:
|
||||
return "BTA_HH_INT_CLOSE_EVT";
|
||||
case BTA_HH_INT_HANDSK_EVT:
|
||||
return "BTA_HH_INT_HANDSK_EVT";
|
||||
case BTA_HH_INT_DATA_EVT:
|
||||
return "BTA_HH_INT_DATA_EVT";
|
||||
case BTA_HH_INT_CTRL_DATA:
|
||||
return "BTA_HH_INT_CTRL_DATA";
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
return "BTA_HH_API_WRITE_DEV_EVT";
|
||||
case BTA_HH_SDP_CMPL_EVT:
|
||||
return "BTA_HH_SDP_CMPL_EVT";
|
||||
case BTA_HH_DISC_CMPL_EVT:
|
||||
return "BTA_HH_DISC_CMPL_EVT";
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
return "BTA_HH_API_MAINT_DEV_EVT";
|
||||
case BTA_HH_API_GET_DSCP_EVT:
|
||||
return "BTA_HH_API_GET_DSCP_EVT";
|
||||
case BTA_HH_OPEN_CMPL_EVT:
|
||||
return "BTA_HH_OPEN_CMPL_EVT";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_GATT_CLOSE_EVT:
|
||||
return "BTA_HH_GATT_CLOSE_EVT";
|
||||
case BTA_HH_GATT_OPEN_EVT:
|
||||
return "BTA_HH_GATT_OPEN_EVT";
|
||||
case BTA_HH_START_ENC_EVT:
|
||||
return "BTA_HH_START_ENC_EVT";
|
||||
case BTA_HH_ENC_CMPL_EVT:
|
||||
return "BTA_HH_ENC_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host event code";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_state_code
|
||||
**
|
||||
** Description get string representation of HID host state code.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_HH_NULL_ST:
|
||||
return"BTA_HH_NULL_ST";
|
||||
case BTA_HH_IDLE_ST:
|
||||
return "BTA_HH_IDLE_ST";
|
||||
case BTA_HH_W4_CONN_ST:
|
||||
return "BTA_HH_W4_CONN_ST";
|
||||
case BTA_HH_CONN_ST:
|
||||
return "BTA_HH_CONN_ST";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_W4_SEC:
|
||||
return "BTA_HH_W4_SEC";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host state";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Debug Functions */
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
@@ -0,0 +1,531 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "bta_hh_int.h"
|
||||
|
||||
/* if SSR max latency is not defined by remote device, set the default value
|
||||
as half of the link supervision timeout */
|
||||
#define BTA_HH_GET_DEF_SSR_MAX_LAT(x) ((x)>> 1)
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
#define BTA_HH_KB_CTRL_MASK 0x11
|
||||
#define BTA_HH_KB_SHIFT_MASK 0x22
|
||||
#define BTA_HH_KB_ALT_MASK 0x44
|
||||
#define BTA_HH_KB_GUI_MASK 0x88
|
||||
|
||||
#define BTA_HH_KB_CAPS_LOCK 0x39 /* caps lock */
|
||||
#define BTA_HH_KB_NUM_LOCK 0x53 /* num lock */
|
||||
|
||||
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
static const UINT8 bta_hh_mod_key_mask[BTA_HH_MOD_MAX_KEY] = {
|
||||
BTA_HH_KB_CTRL_MASK,
|
||||
BTA_HH_KB_SHIFT_MASK,
|
||||
BTA_HH_KB_ALT_MASK,
|
||||
BTA_HH_KB_GUI_MASK
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_find_cb
|
||||
**
|
||||
** Description Find best available control block according to BD address.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_find_cb(BD_ADDR bda)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
/* See how many active devices there are. */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
/* check if any active/known devices is a match */
|
||||
if ((!bdcmp (bda, bta_hh_cb.kdev[xx].addr) &&
|
||||
bdcmp(bda, bd_addr_null) != 0) ) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found kdev_cb[%d] hid_handle = %d ", xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle)
|
||||
#endif
|
||||
return xx;
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
else {
|
||||
APPL_TRACE_DEBUG("in_use ? [%d] kdev[%d].hid_handle = %d state = [%d]",
|
||||
bta_hh_cb.kdev[xx].in_use, xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle,
|
||||
bta_hh_cb.kdev[xx].state);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* if no active device match, find a spot for it */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
if (!bta_hh_cb.kdev[xx].in_use) {
|
||||
bdcpy(bta_hh_cb.kdev[xx].addr, bda);
|
||||
bta_hh_cb.kdev[xx].in_use = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If device list full, report BTA_HH_IDX_INVALID */
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_find_cb:: index = %d while max = %d",
|
||||
xx, BTA_HH_MAX_DEVICE);
|
||||
#endif
|
||||
|
||||
if (xx == BTA_HH_MAX_DEVICE) {
|
||||
xx = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
|
||||
return xx;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_clean_up_kdev
|
||||
**
|
||||
** Description Clean up device control block when device is removed from
|
||||
** manitainace list, and update control block index map.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
if (p_cb->hid_handle != BTA_HH_INVALID_HANDLE ) {
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (p_cb->is_le_device) {
|
||||
bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = BTA_HH_IDX_INVALID;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
bta_hh_cb.cb_index[p_cb->hid_handle] = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset device control block */
|
||||
index = p_cb->index; /* Preserve index for this control block */
|
||||
|
||||
/* Free buffer for report descriptor info */
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
memset(p_cb, 0, sizeof (tBTA_HH_DEV_CB)); /* Reset control block */
|
||||
|
||||
p_cb->index = index; /* Restore index for this control block */
|
||||
p_cb->state = BTA_HH_IDLE_ST;
|
||||
p_cb->hid_handle = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_update_di_info
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("vendor_id = 0x%2x product_id = 0x%2x version = 0x%2x",
|
||||
vendor_id, product_id, version);
|
||||
#endif
|
||||
p_cb->dscp_info.vendor_id = vendor_id;
|
||||
p_cb->dscp_info.product_id = product_id;
|
||||
p_cb->dscp_info.version = version;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
p_cb->dscp_info.flag = flag;
|
||||
#else
|
||||
UNUSED(flag);
|
||||
#endif
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_add_device_to_list
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class,
|
||||
UINT16 ssr_max_latency,
|
||||
UINT16 ssr_min_tout,
|
||||
UINT8 app_id)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("subclass = 0x%2x", sub_class);
|
||||
#endif
|
||||
|
||||
p_cb->hid_handle = handle;
|
||||
p_cb->in_use = TRUE;
|
||||
p_cb->attr_mask = attr_mask;
|
||||
|
||||
p_cb->sub_class = sub_class;
|
||||
p_cb->app_id = app_id;
|
||||
|
||||
p_cb->dscp_info.ssr_max_latency = ssr_max_latency;
|
||||
p_cb->dscp_info.ssr_min_tout = ssr_min_tout;
|
||||
|
||||
/* store report descriptor info */
|
||||
if ( p_dscp_info) {
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
if (p_dscp_info->dl_len &&
|
||||
(p_cb->dscp_info.descriptor.dsc_list =
|
||||
(UINT8 *)osi_malloc(p_dscp_info->dl_len)) != NULL) {
|
||||
p_cb->dscp_info.descriptor.dl_len = p_dscp_info->dl_len;
|
||||
memcpy(p_cb->dscp_info.descriptor.dsc_list, p_dscp_info->dsc_list,
|
||||
p_dscp_info->dl_len);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_tod_spt
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class)
|
||||
{
|
||||
UINT8 xx;
|
||||
UINT8 cod = (sub_class >> 2); /* lower two bits are reserved */
|
||||
|
||||
for (xx = 0 ; xx < p_bta_hh_cfg->max_devt_spt; xx ++) {
|
||||
if (cod == (UINT8) p_bta_hh_cfg->p_devt_list[xx].tod) {
|
||||
p_cb->app_id = p_bta_hh_cfg->p_devt_list[xx].app_id;
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x supported", sub_class);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_ERROR("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_keybd_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode keyboard report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_KB_CB *p_kb = &bta_hh_cb.kb_cb;
|
||||
tBTA_HH_KEYBD_RPT *p_data = &p_kb_data->data_rpt.keybd_rpt;
|
||||
|
||||
UINT8 this_char, ctl_shift;
|
||||
UINT16 xx, yy, key_idx = 0;
|
||||
UINT8 this_report[BTA_HH_MAX_RPT_CHARS];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
||||
p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctl_shift = *p_report++;
|
||||
report_len--;
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
memset (this_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memset (p_data, 0, sizeof(tBTA_HH_KEYBD_RPT));
|
||||
memcpy (this_report, p_report, report_len);
|
||||
|
||||
/* Take care of shift, control, GUI and alt, modifier keys */
|
||||
for (xx = 0; xx < BTA_HH_MOD_MAX_KEY; xx ++ ) {
|
||||
if (ctl_shift & bta_hh_mod_key_mask[xx]) {
|
||||
APPL_TRACE_DEBUG("Mod Key[%02x] pressed", bta_hh_mod_key_mask[xx] );
|
||||
p_kb->mod_key[xx] = TRUE;
|
||||
} else if (p_kb->mod_key[xx]) {
|
||||
p_kb->mod_key[xx] = FALSE;
|
||||
}
|
||||
/* control key flag is set */
|
||||
p_data->mod_key[xx] = p_kb->mod_key[xx];
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* First step is to remove all characters we saw in the last report */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
for (yy = 0; yy < BTA_HH_MAX_RPT_CHARS; yy++) {
|
||||
if (this_report[xx] == p_kb->last_report[yy]) {
|
||||
this_report[xx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************************************************/
|
||||
/* Now, process all the characters in the report, up to 6 keycodes */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("this_char = %02x", this_report[xx]);
|
||||
#endif
|
||||
if ((this_char = this_report[xx]) == 0) {
|
||||
continue;
|
||||
}
|
||||
/* take the key code as the report data */
|
||||
if (this_report[xx] == BTA_HH_KB_CAPS_LOCK) {
|
||||
p_kb->caps_lock = p_kb->caps_lock ? FALSE : TRUE;
|
||||
} else if (this_report[xx] == BTA_HH_KB_NUM_LOCK) {
|
||||
p_kb->num_lock = p_kb->num_lock ? FALSE : TRUE;
|
||||
} else {
|
||||
p_data->this_char[key_idx ++] = this_char;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found keycode %02x ", this_report[xx]);
|
||||
#endif
|
||||
p_data->caps_lock = p_kb->caps_lock;
|
||||
p_data->num_lock = p_kb->num_lock;
|
||||
}
|
||||
|
||||
memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memcpy (p_kb->last_report, p_report, report_len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_mice_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode mouse report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_mice_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_MICE_RPT *p_data = &p_mice_data->data_rpt.mice_rpt;
|
||||
#if BTA_HH_DEBUG
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_mice_rpt: bta_keybd_rpt_rcvd(report=%p, \
|
||||
report_len=%d) called", p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
APPL_TRACE_DEBUG("this_char = %02x", p_report[xx]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* only first bytes lower 3 bits valid */
|
||||
p_data->mouse_button = (p_report[0] & 0x07);
|
||||
|
||||
/* x displacement */
|
||||
p_data->delta_x = p_report[1];
|
||||
|
||||
/* y displacement */
|
||||
p_data->delta_y = p_report[2];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("mice button: 0x%2x", p_data->mouse_button);
|
||||
APPL_TRACE_DEBUG("mice move: x = %d y = %d", p_data->delta_x,
|
||||
p_data->delta_y );
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_read_ssr_param
|
||||
**
|
||||
** Description Read the SSR Parameter for the remote device
|
||||
**
|
||||
** Returns tBTA_HH_STATUS operation status
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout)
|
||||
{
|
||||
tBTA_HH_STATUS status = BTA_HH_ERR;
|
||||
tBTA_HH_CB *p_cb = &bta_hh_cb;
|
||||
UINT8 i;
|
||||
UINT16 ssr_max_latency;
|
||||
for (i = 0; i < BTA_HH_MAX_KNOWN; i ++) {
|
||||
if (memcmp(p_cb->kdev[i].addr, bd_addr, BD_ADDR_LEN) == 0) {
|
||||
|
||||
/* if remote device does not have HIDSSRHostMaxLatency attribute in SDP,
|
||||
set SSR max latency default value here. */
|
||||
if (p_cb->kdev[i].dscp_info.ssr_max_latency == HID_SSR_PARAM_INVALID) {
|
||||
/* The default is calculated as half of link supervision timeout.*/
|
||||
|
||||
BTM_GetLinkSuperTout(p_cb->kdev[i].addr, &ssr_max_latency) ;
|
||||
ssr_max_latency = BTA_HH_GET_DEF_SSR_MAX_LAT(ssr_max_latency);
|
||||
|
||||
/* per 1.1 spec, if the newly calculated max latency is greater than
|
||||
BTA_HH_SSR_MAX_LATENCY_DEF which is 500ms, use BTA_HH_SSR_MAX_LATENCY_DEF */
|
||||
if (ssr_max_latency > BTA_HH_SSR_MAX_LATENCY_DEF) {
|
||||
ssr_max_latency = BTA_HH_SSR_MAX_LATENCY_DEF;
|
||||
}
|
||||
|
||||
* p_max_ssr_lat = ssr_max_latency;
|
||||
} else {
|
||||
* p_max_ssr_lat = p_cb->kdev[i].dscp_info.ssr_max_latency;
|
||||
}
|
||||
|
||||
if (p_cb->kdev[i].dscp_info.ssr_min_tout == HID_SSR_PARAM_INVALID) {
|
||||
* p_min_ssr_tout = BTA_HH_SSR_MIN_TOUT_DEF;
|
||||
} else {
|
||||
* p_min_ssr_tout = p_cb->kdev[i].dscp_info.ssr_min_tout;
|
||||
}
|
||||
|
||||
status = BTA_HH_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_cleanup_disable
|
||||
**
|
||||
** Description when disable finished, cleanup control block and send callback
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
||||
{
|
||||
UINT8 xx;
|
||||
/* free buffer in CB holding report descriptors */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx ++) {
|
||||
utl_freebuf((void **)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
|
||||
}
|
||||
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
|
||||
|
||||
if (bta_hh_cb.p_cback) {
|
||||
(*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH*)&status);
|
||||
/* all connections are down, no waiting for diconnect */
|
||||
memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_dev_handle_to_cb_idx
|
||||
**
|
||||
** Description convert a HID device handle to the device control block index.
|
||||
**
|
||||
**
|
||||
** Returns UINT8: index of the device control block.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
|
||||
if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
|
||||
index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)];
|
||||
}
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_hh_dev_handle_to_cb_idx dev_handle = %d index = %d", dev_handle, index);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* regular HID device checking */
|
||||
if (dev_handle < BTA_HH_MAX_KNOWN ) {
|
||||
index = bta_hh_cb.cb_index[dev_handle];
|
||||
}
|
||||
}
|
||||
return index;
|
||||
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_trace_dev_db
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_trace_dev_db(void)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_trace_dev_db:: Device DB list********************");
|
||||
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
APPL_TRACE_DEBUG("kdev[%d] in_use[%d] handle[%d] ", xx,
|
||||
bta_hh_cb.kdev[xx].in_use, bta_hh_cb.kdev[xx].hid_handle);
|
||||
|
||||
APPL_TRACE_DEBUG("\t\t\t attr_mask[%04x] state [%d] sub_class[%02x] index = %d",
|
||||
bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state,
|
||||
bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index);
|
||||
}
|
||||
APPL_TRACE_DEBUG("*********************************************************");
|
||||
}
|
||||
#endif
|
||||
#endif /* HL_INCLUDED */
|
||||
@@ -0,0 +1,403 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains BTA HID Host internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BTA_HH_INT_H
|
||||
#define BTA_HH_INT_H
|
||||
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta/utl.h"
|
||||
#include "bta/bta_hh_api.h"
|
||||
|
||||
//#if BTA_HH_LE_INCLUDED == TRUE
|
||||
#include "bta/bta_gatt_api.h"
|
||||
//#endif
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
/* can be moved to bta/bta_api.h */
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
#if (BTA_GATT_INCLUDED == FALSE || BLE_INCLUDED == FALSE)
|
||||
#undef BTA_HH_LE_INCLUDED
|
||||
#define BTA_HH_LE_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/* state machine events, these events are handled by the state machine */
|
||||
enum {
|
||||
BTA_HH_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HH),
|
||||
BTA_HH_API_CLOSE_EVT,
|
||||
BTA_HH_INT_OPEN_EVT,
|
||||
BTA_HH_INT_CLOSE_EVT,
|
||||
BTA_HH_INT_DATA_EVT,
|
||||
BTA_HH_INT_CTRL_DATA,
|
||||
BTA_HH_INT_HANDSK_EVT,
|
||||
BTA_HH_SDP_CMPL_EVT,
|
||||
BTA_HH_API_WRITE_DEV_EVT,
|
||||
BTA_HH_API_GET_DSCP_EVT,
|
||||
BTA_HH_API_MAINT_DEV_EVT,
|
||||
BTA_HH_OPEN_CMPL_EVT,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE_EVT,
|
||||
BTA_HH_GATT_OPEN_EVT,
|
||||
BTA_HH_START_ENC_EVT,
|
||||
BTA_HH_ENC_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_DESCR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
|
||||
BTA_HH_API_SCPP_UPDATE_EVT,
|
||||
BTA_HH_GATT_ENC_CMPL_EVT,
|
||||
#endif
|
||||
|
||||
/* not handled by execute state machine */
|
||||
BTA_HH_API_ENABLE_EVT,
|
||||
BTA_HH_API_DISABLE_EVT,
|
||||
BTA_HH_DISC_CMPL_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_HH_INT_EVT; /* HID host internal events */
|
||||
|
||||
#define BTA_HH_INVALID_EVT (BTA_HH_DISC_CMPL_EVT + 1)
|
||||
|
||||
/* event used to map between BTE event and BTA event */
|
||||
#define BTA_HH_FST_TRANS_CB_EVT BTA_HH_GET_RPT_EVT
|
||||
#define BTA_HH_FST_BTE_TRANS_EVT HID_TRANS_GET_REPORT
|
||||
|
||||
/* sub event code used for device maintainence API call */
|
||||
#define BTA_HH_ADD_DEV 0
|
||||
#define BTA_HH_REMOVE_DEV 1
|
||||
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_HH_NULL_ST,
|
||||
BTA_HH_IDLE_ST,
|
||||
BTA_HH_W4_CONN_ST,
|
||||
BTA_HH_CONN_ST
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, BTA_HH_W4_SEC
|
||||
#endif
|
||||
, BTA_HH_INVALID_ST /* Used to check invalid states before executing SM function */
|
||||
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATE;
|
||||
|
||||
/* data structure used to send a command/data to HID device */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 t_type;
|
||||
UINT8 param;
|
||||
UINT8 rpt_id;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 srvc_id;
|
||||
#endif
|
||||
UINT16 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CMD_DATA;
|
||||
|
||||
/* data type for BTA_HH_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 sec_mask;
|
||||
UINT8 service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
tBTA_HH_CBACK *p_cback;
|
||||
} tBTA_HH_API_ENABLE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
UINT8 sec_mask;
|
||||
tBTA_HH_PROTO_MODE mode;
|
||||
} tBTA_HH_API_CONN;
|
||||
|
||||
/* internal event data from BTE HID callback */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
UINT32 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CBACK_DATA;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bda;
|
||||
UINT16 attr_mask;
|
||||
UINT16 sub_event;
|
||||
UINT8 sub_class;
|
||||
UINT8 app_id;
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info;
|
||||
} tBTA_HH_MAINT_DEV;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 conn_id;
|
||||
tBTA_GATT_REASON reason; /* disconnect reason code, not useful when connect event is reported */
|
||||
|
||||
} tBTA_HH_LE_CLOSE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 scan_int;
|
||||
UINT16 scan_win;
|
||||
} tBTA_HH_SCPP_UPDATE;
|
||||
#endif
|
||||
/* union of all event data types */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_HH_API_ENABLE api_enable;
|
||||
tBTA_HH_API_CONN api_conn;
|
||||
tBTA_HH_CMD_DATA api_sndcmd;
|
||||
tBTA_HH_CBACK_DATA hid_cback;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_HH_MAINT_DEV api_maintdev;
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
tBTA_HH_LE_CLOSE le_close;
|
||||
tBTA_GATTC_OPEN le_open;
|
||||
tBTA_HH_SCPP_UPDATE le_scpp_update;
|
||||
tBTA_GATTC_ENC_CMPL_CB le_enc_cmpl;
|
||||
#endif
|
||||
} tBTA_HH_DATA;
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
typedef struct {
|
||||
UINT8 index;
|
||||
BOOLEAN in_use;
|
||||
UINT8 inst_id; /* share service instance ID and report instance ID, as
|
||||
hi 4 for service instance ID, low 4 as charatceristic instance ID */
|
||||
tBTA_HH_RPT_TYPE rpt_type;
|
||||
UINT16 uuid;
|
||||
UINT8 prop;
|
||||
UINT8 rpt_id;
|
||||
BOOLEAN client_cfg_exist;
|
||||
UINT16 client_cfg_value;
|
||||
} tBTA_HH_LE_RPT;
|
||||
|
||||
#ifndef BTA_HH_LE_RPT_MAX
|
||||
#define BTA_HH_LE_RPT_MAX 20
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
tBTA_HH_LE_RPT report[BTA_HH_LE_RPT_MAX];
|
||||
|
||||
#define BTA_HH_LE_PROTO_MODE_BIT 0x01
|
||||
#define BTA_HH_LE_CP_BIT 0x02
|
||||
UINT8 option_char; /* control point char exisit or not */
|
||||
|
||||
BOOLEAN expl_incl_srvc;
|
||||
UINT8 incl_srvc_inst; /* assuming only one included service : battery service */
|
||||
UINT8 cur_expl_char_idx; /* currently discovering service index */
|
||||
UINT8 *rpt_map;
|
||||
UINT16 ext_rpt_ref;
|
||||
tBTA_HH_DEV_DESCR descriptor;
|
||||
|
||||
} tBTA_HH_LE_HID_SRVC;
|
||||
|
||||
#ifndef BTA_HH_LE_HID_SRVC_MAX
|
||||
#define BTA_HH_LE_HID_SRVC_MAX 1
|
||||
#endif
|
||||
|
||||
/* convert a HID handle to the LE CB index */
|
||||
#define BTA_HH_GET_LE_CB_IDX(x) (((x) >> 4) - 1)
|
||||
/* convert a GATT connection ID to HID device handle, it is the hi 4 bits of a UINT8 */
|
||||
#define BTA_HH_GET_LE_DEV_HDL(x) (UINT8)(((x) + 1) << 4)
|
||||
/* check to see if th edevice handle is a LE device handle */
|
||||
#define BTA_HH_IS_LE_DEV_HDL(x) ((x) & 0xf0)
|
||||
#define BTA_HH_IS_LE_DEV_HDL_VALID(x) (((x)>>4) <= BTA_HH_LE_MAX_KNOWN)
|
||||
#endif
|
||||
|
||||
/* device control block */
|
||||
typedef struct {
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info; /* report descriptor and DI information */
|
||||
BD_ADDR addr; /* BD-Addr of the HID device */
|
||||
UINT16 attr_mask; /* attribute mask */
|
||||
UINT16 w4_evt; /* W4_handshake event name */
|
||||
UINT8 index; /* index number referenced to handle index */
|
||||
UINT8 sub_class; /* Cod sub class */
|
||||
UINT8 sec_mask; /* security mask */
|
||||
UINT8 app_id; /* application ID for this connection */
|
||||
UINT8 hid_handle; /* device handle : low 4 bits for regular HID: HID_HOST_MAX_DEVICES can not exceed 15;
|
||||
high 4 bits for LE HID: GATT_MAX_PHY_CHANNEL can not exceed 15 */
|
||||
BOOLEAN vp; /* virtually unplug flag */
|
||||
BOOLEAN in_use; /* control block currently in use */
|
||||
BOOLEAN incoming_conn; /* is incoming connection? */
|
||||
UINT8 incoming_hid_handle; /* temporary handle for incoming connection? */
|
||||
BOOLEAN opened; /* TRUE if device successfully opened HID connection */
|
||||
tBTA_HH_PROTO_MODE mode; /* protocol mode */
|
||||
tBTA_HH_PROTO_MODE new_mode; /* protocol mode */
|
||||
tBTA_HH_STATE state; /* CB state */
|
||||
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
#define BTA_HH_LE_DISC_NONE 0x00
|
||||
#define BTA_HH_LE_DISC_HIDS 0x01
|
||||
#define BTA_HH_LE_DISC_DIS 0x02
|
||||
#define BTA_HH_LE_DISC_SCPS 0x04
|
||||
|
||||
UINT8 disc_active;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_GATT_REASON reason;
|
||||
BOOLEAN is_le_device;
|
||||
tBTA_HH_LE_HID_SRVC hid_srvc[BTA_HH_LE_HID_SRVC_MAX];
|
||||
UINT16 conn_id;
|
||||
BOOLEAN in_bg_conn;
|
||||
UINT8 total_srvc;
|
||||
UINT8 clt_cfg_idx;
|
||||
UINT8 cur_srvc_index; /* currently discovering service index */
|
||||
BOOLEAN scps_supported;
|
||||
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_NONE 0
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_SPT 0x01
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_ENB 0x02
|
||||
UINT8 scps_notify; /* scan refresh supported/notification enabled */
|
||||
#endif
|
||||
|
||||
BOOLEAN security_pending;
|
||||
} tBTA_HH_DEV_CB;
|
||||
|
||||
/* key board parsing control block */
|
||||
typedef struct {
|
||||
BOOLEAN mod_key[4]; /* ctrl, shift(upper), Alt, GUI */
|
||||
BOOLEAN num_lock;
|
||||
BOOLEAN caps_lock;
|
||||
UINT8 last_report[BTA_HH_MAX_RPT_CHARS];
|
||||
} tBTA_HH_KB_CB;
|
||||
|
||||
/******************************************************************************
|
||||
** Main Control Block
|
||||
*******************************************************************************/
|
||||
typedef struct {
|
||||
tBTA_HH_KB_CB kb_cb; /* key board control block,
|
||||
suppose BTA will connect
|
||||
to only one keyboard at
|
||||
the same time */
|
||||
tBTA_HH_DEV_CB kdev[BTA_HH_MAX_DEVICE]; /* device control block */
|
||||
tBTA_HH_DEV_CB *p_cur; /* current device control
|
||||
block idx, used in sdp */
|
||||
UINT8 cb_index[BTA_HH_MAX_KNOWN]; /* maintain a CB index
|
||||
map to dev handle */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 le_cb_index[BTA_HH_MAX_DEVICE]; /* maintain a CB index map to LE dev handle */
|
||||
tBTA_GATTC_IF gatt_if;
|
||||
#endif
|
||||
tBTA_HH_CBACK *p_cback; /* Application callbacks */
|
||||
tSDP_DISCOVERY_DB *p_disc_db;
|
||||
UINT8 trace_level; /* tracing level */
|
||||
UINT8 cnt_num; /* connected device number */
|
||||
BOOLEAN w4_disable; /* w4 disable flag */
|
||||
}
|
||||
tBTA_HH_CB;
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_HH_CB bta_hh_cb;
|
||||
#else
|
||||
extern tBTA_HH_CB *bta_hh_cb_ptr;
|
||||
#define bta_hh_cb (*bta_hh_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* from bta_hh_cfg.c */
|
||||
extern tBTA_HH_CFG *p_bta_hh_cfg;
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg);
|
||||
extern void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event,
|
||||
tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
extern void bta_hh_api_disc_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_close_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_get_dscp_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* utility functions */
|
||||
extern UINT8 bta_hh_find_cb(BD_ADDR bda);
|
||||
extern void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class);
|
||||
extern void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb);
|
||||
|
||||
extern void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class, UINT16 max_latency, UINT16 min_tout, UINT8 app_id);
|
||||
extern void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag);
|
||||
extern void bta_hh_cleanup_disable(tBTA_HH_STATUS status);
|
||||
|
||||
extern UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle);
|
||||
|
||||
/* action functions used outside state machine */
|
||||
extern void bta_hh_api_enable(tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_api_disable(void);
|
||||
extern void bta_hh_disc_cmpl(void);
|
||||
|
||||
extern tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout);
|
||||
|
||||
/* functions for LE HID */
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
extern void bta_hh_le_enable(void);
|
||||
extern BOOLEAN bta_hh_le_is_hh_gatt_if(tBTA_GATTC_IF client_if);
|
||||
extern void bta_hh_le_deregister(void);
|
||||
extern BOOLEAN bta_hh_is_le_device(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info);
|
||||
extern void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_open_fail(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_open(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_close(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_srvc_discovery(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ci_load_rpt (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
#endif
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
extern void bta_hh_trace_dev_db(void);
|
||||
#endif
|
||||
|
||||
#endif ///defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
#endif
|
||||
Reference in New Issue
Block a user