mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
1. transparent HID device
2. add esp API for HID 3. add PM config for HID 4. add HID device demo Closes https://github.com/espressif/esp-idf/issues/5311 Closes https://github.com/espressif/esp-idf/issues/5635 Merges https://github.com/espressif/esp-idf/pull/3425
This commit is contained in:
parent
9049974d6b
commit
1c15c9207c
@ -55,6 +55,7 @@ if(CONFIG_BT_ENABLED)
|
||||
host/bluedroid/bta/gatt/include
|
||||
host/bluedroid/bta/hf_ag/include
|
||||
host/bluedroid/bta/hf_client/include
|
||||
host/bluedroid/bta/hd/include
|
||||
host/bluedroid/bta/hh/include
|
||||
host/bluedroid/bta/jv/include
|
||||
host/bluedroid/bta/sdp/include
|
||||
@ -66,12 +67,12 @@ if(CONFIG_BT_ENABLED)
|
||||
host/bluedroid/external/sbc/plc/include
|
||||
host/bluedroid/btc/profile/esp/include
|
||||
host/bluedroid/btc/profile/std/a2dp/include
|
||||
host/bluedroid/btc/profile/std/hid/include
|
||||
host/bluedroid/btc/profile/std/include
|
||||
host/bluedroid/btc/include
|
||||
host/bluedroid/stack/btm/include
|
||||
host/bluedroid/stack/gap/include
|
||||
host/bluedroid/stack/gatt/include
|
||||
host/bluedroid/stack/hid/include
|
||||
host/bluedroid/stack/l2cap/include
|
||||
host/bluedroid/stack/sdp/include
|
||||
host/bluedroid/stack/smp/include
|
||||
@ -94,6 +95,8 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/api/esp_gatt_common_api.c"
|
||||
"host/bluedroid/api/esp_gattc_api.c"
|
||||
"host/bluedroid/api/esp_gatts_api.c"
|
||||
"host/bluedroid/api/esp_hidd_api.c"
|
||||
"host/bluedroid/api/esp_hidh_api.c"
|
||||
"host/bluedroid/api/esp_hf_ag_api.c"
|
||||
"host/bluedroid/api/esp_hf_client_api.c"
|
||||
"host/bluedroid/api/esp_spp_api.c"
|
||||
@ -128,6 +131,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/bta/gatt/bta_gatts_co.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_main.c"
|
||||
"host/bluedroid/bta/gatt/bta_gatts_utils.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_api.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_act.c"
|
||||
"host/bluedroid/bta/hd/bta_hd_main.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_act.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_api.c"
|
||||
"host/bluedroid/bta/hh/bta_hh_cfg.c"
|
||||
@ -184,8 +190,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||
"host/bluedroid/btc/profile/std/hid/hidh_api.c"
|
||||
"host/bluedroid/btc/profile/std/hid/hidh_conn.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hd.c"
|
||||
"host/bluedroid/btc/profile/std/hid/btc_hh.c"
|
||||
"host/bluedroid/btc/profile/std/hid/bta_hh_co.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"host/bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c"
|
||||
@ -251,6 +258,10 @@ if(CONFIG_BT_ENABLED)
|
||||
"host/bluedroid/stack/avrc/avrc_pars_tg.c"
|
||||
"host/bluedroid/stack/avrc/avrc_sdp.c"
|
||||
"host/bluedroid/stack/avrc/avrc_utils.c"
|
||||
"host/bluedroid/stack/hid/hidd_api.c"
|
||||
"host/bluedroid/stack/hid/hidd_conn.c"
|
||||
"host/bluedroid/stack/hid/hidh_api.c"
|
||||
"host/bluedroid/stack/hid/hidh_conn.c"
|
||||
"host/bluedroid/stack/btm/btm_acl.c"
|
||||
"host/bluedroid/stack/btm/btm_ble.c"
|
||||
"host/bluedroid/stack/btm/btm_ble_addr.c"
|
||||
|
@ -53,6 +53,12 @@
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
#include "btc_hf_client.h"
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED == TRUE
|
||||
#include "btc_hd.h"
|
||||
#endif /* BTC_HD_INCLUDED */
|
||||
#if BTC_HH_INCLUDED == TRUE
|
||||
#include "btc_hh.h"
|
||||
#endif /* BTC_HH_INCLUDED */
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
|
||||
@ -120,6 +126,12 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#if BTC_HD_INCLUDED
|
||||
[BTC_PID_HD] = {btc_hd_call_handler, btc_hd_cb_handler },
|
||||
#endif
|
||||
#if BTC_HH_INCLUDED
|
||||
[BTC_PID_HH] = {btc_hh_call_handler, btc_hh_cb_handler },
|
||||
#endif
|
||||
#endif /* #if CLASSIC_BT_INCLUDED */
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH
|
||||
|
@ -65,6 +65,8 @@ typedef enum {
|
||||
BTC_PID_AVRC_CT,
|
||||
BTC_PID_AVRC_TG,
|
||||
BTC_PID_SPP,
|
||||
BTC_PID_HD,
|
||||
BTC_PID_HH,
|
||||
#if (BTC_HF_INCLUDED == TRUE)
|
||||
BTC_PID_HF,
|
||||
#endif /* BTC_HF_INCLUDED */
|
||||
@ -99,6 +101,10 @@ typedef struct {
|
||||
|
||||
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* transfer an message to another module in the different task.
|
||||
* @param msg message
|
||||
@ -124,4 +130,8 @@ void btc_deinit(void);
|
||||
bool btc_check_queue_is_congest(void);
|
||||
int get_btc_work_queue_size(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BTC_TASK_H__ */
|
||||
|
@ -46,6 +46,7 @@ COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||
host/bluedroid/bta/hf_client/include \
|
||||
host/bluedroid/bta/dm/include \
|
||||
host/bluedroid/bta/gatt/include \
|
||||
host/bluedroid/bta/hd/include \
|
||||
host/bluedroid/bta/hh/include \
|
||||
host/bluedroid/bta/jv/include \
|
||||
host/bluedroid/bta/sdp/include \
|
||||
@ -70,6 +71,7 @@ COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||
host/bluedroid/stack/gap/include \
|
||||
host/bluedroid/stack/gatt/include \
|
||||
host/bluedroid/stack/hcic/include \
|
||||
host/bluedroid/stack/hid/include \
|
||||
host/bluedroid/stack/l2cap/include \
|
||||
host/bluedroid/stack/sdp/include \
|
||||
host/bluedroid/stack/smp/include \
|
||||
@ -86,6 +88,7 @@ COMPONENT_ADD_INCLUDEDIRS += host/bluedroid/api/include/api \
|
||||
|
||||
COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||
host/bluedroid/bta/gatt \
|
||||
host/bluedroid/bta/hd \
|
||||
host/bluedroid/bta/hh \
|
||||
host/bluedroid/bta/sdp \
|
||||
host/bluedroid/bta/av \
|
||||
@ -118,6 +121,7 @@ COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||
host/bluedroid/stack/gap \
|
||||
host/bluedroid/stack/gatt \
|
||||
host/bluedroid/stack/hcic \
|
||||
host/bluedroid/stack/hid \
|
||||
host/bluedroid/stack/include \
|
||||
host/bluedroid/stack/l2cap \
|
||||
host/bluedroid/stack/sdp \
|
||||
|
@ -99,13 +99,27 @@ config BT_HFP_WBS_ENABLE
|
||||
This enables Wide Band Speech. Should disable it when SCO data path is PCM.
|
||||
Otherwise there will be no data transmited via GPIOs.
|
||||
|
||||
config BT_HID_HOST_ENABLED
|
||||
bool "Classic BT HID Host"
|
||||
config BT_HID_ENABLED
|
||||
bool "Classic BT HID"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
default n
|
||||
help
|
||||
This enables the BT HID Host
|
||||
|
||||
choice BT_HID_ROLE
|
||||
prompt "Profile Role configuration"
|
||||
depends on BT_HID_ENABLED
|
||||
config BT_HID_HOST_ENABLED
|
||||
bool "Classic BT HID Host"
|
||||
help
|
||||
This enables the BT HID Host
|
||||
|
||||
config BT_HID_DEVICE_ENABLED
|
||||
bool "Classic BT HID Device"
|
||||
help
|
||||
This enables the BT HID Device
|
||||
endchoice
|
||||
|
||||
config BT_SSP_ENABLED
|
||||
bool "Secure Simple Pairing"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
|
176
components/bt/host/bluedroid/api/esp_hidd_api.c
Normal file
176
components/bt/host/bluedroid/api/esp_hidd_api.c
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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 "esp_err.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_hd.h"
|
||||
#include "esp_hidd_api.h"
|
||||
|
||||
#if (defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t *callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_HD, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_init(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_deinit(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_DEINIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t* app_param, esp_hidd_qos_param_t* in_qos, esp_hidd_qos_param_t* out_qos)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.register_app.app_param = app_param;
|
||||
args.register_app.in_qos = in_qos;
|
||||
args.register_app.out_qos = out_qos;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_REGISTER_APP_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_unregister_app(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_UNREGISTER_APP_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
memcpy(args.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_CONNECT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_disconnect(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_DISCONNECT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t* data)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_SEND_REPORT_EVT;
|
||||
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.send_report.type = type;
|
||||
args.send_report.id = id;
|
||||
args.send_report.len = len;
|
||||
args.send_report.data = data;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), btc_hd_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_REPORT_ERROR_EVT;
|
||||
|
||||
btc_hidd_args_t args;
|
||||
memset(&args, 0, sizeof(btc_hidd_args_t));
|
||||
args.error = error;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_device_virtual_cable_unplug(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = BTC_HD_UNPLUG_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE */
|
254
components/bt/host/bluedroid/api/esp_hidh_api.c
Normal file
254
components/bt/host/bluedroid/api/esp_hidh_api.c
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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 "btc/btc_manage.h"
|
||||
#include "btc_hh.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_hidh_api.h"
|
||||
#include <string.h>
|
||||
|
||||
#if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t *callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_HH, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_init(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_INIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_deinit(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_DEINIT_EVT;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_CONNECT_EVT;
|
||||
|
||||
memcpy(arg.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_DISCONNECT_EVT;
|
||||
|
||||
memcpy(arg.disconnect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_UNPLUG_EVT;
|
||||
|
||||
memcpy(arg.unplug.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_INFO_EVT;
|
||||
|
||||
memcpy(arg.set_info.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_info.hid_info = hid_info;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_PROTO_EVT;
|
||||
|
||||
memcpy(arg.get_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_PROTO_EVT;
|
||||
|
||||
memcpy(arg.set_protocol.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_protocol.protocol_mode = protocol_mode;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_IDLE_EVT;
|
||||
|
||||
memcpy(arg.get_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_IDLE_EVT;
|
||||
|
||||
memcpy(arg.set_idle.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_idle.idle_time = idle_time;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id,
|
||||
int buffer_size)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_GET_REPORT_EVT;
|
||||
|
||||
memcpy(arg.get_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.get_report.report_type = report_type;
|
||||
arg.get_report.report_id = report_id;
|
||||
arg.get_report.buffer_size = buffer_size;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report,
|
||||
size_t len)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SET_REPORT_EVT;
|
||||
|
||||
memcpy(arg.set_report.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.set_report.report_type = report_type;
|
||||
arg.set_report.len = len;
|
||||
arg.set_report.report = report;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
btc_msg_t msg;
|
||||
btc_hidh_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTC_HH_SEND_DATA_EVT;
|
||||
|
||||
memcpy(arg.send_data.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
|
||||
arg.send_data.len = len;
|
||||
arg.send_data.data = data;
|
||||
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), btc_hh_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE */
|
379
components/bt/host/bluedroid/api/include/api/esp_hidd_api.h
Normal file
379
components/bt/host/bluedroid/api/include/api/esp_hidd_api.h
Normal file
@ -0,0 +1,379 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef __ESP_HIDD_API_H__
|
||||
#define __ESP_HIDD_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* sub_class of hid device */
|
||||
#define ESP_HID_CLASS_UNKNOWN (0x00<<2)
|
||||
#define ESP_HID_CLASS_JOS (0x01<<2) /* joy stick */
|
||||
#define ESP_HID_CLASS_GPD (0x02<<2) /* game pad */
|
||||
#define ESP_HID_CLASS_RMC (0x03<<2) /* remote control */
|
||||
#define ESP_HID_CLASS_SED (0x04<<2) /* sensing device */
|
||||
#define ESP_HID_CLASS_DGT (0x05<<2) /* Digitizer tablet */
|
||||
#define ESP_HID_CLASS_CDR (0x06<<2) /* card reader */
|
||||
#define ESP_HID_CLASS_KBD (0x10<<2) /* keyboard */
|
||||
#define ESP_HID_CLASS_MIC (0x20<<2) /* pointing device */
|
||||
#define ESP_HID_CLASS_COM (0x30<<2) /* Combo keyboard/pointing */
|
||||
|
||||
/**
|
||||
* @brief HIDD handshake error
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_SUCCESS = 0,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_NOT_READY = 1,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID = 2,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ = 3,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM = 4,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN = 14,
|
||||
ESP_HID_PAR_HANDSHAKE_RSP_ERR_FATAL = 15
|
||||
} esp_hidd_handshake_error_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD report types
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_REPORT_TYPE_OTHER = 0,
|
||||
ESP_HIDD_REPORT_TYPE_INPUT,
|
||||
ESP_HIDD_REPORT_TYPE_OUTPUT,
|
||||
ESP_HIDD_REPORT_TYPE_FEATURE,
|
||||
// special value for reports to be sent on INTR(INPUT is assumed)
|
||||
ESP_HIDD_REPORT_TYPE_INTRDATA
|
||||
} esp_hidd_report_type_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD connection state
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_CONN_STATE_CONNECTED,
|
||||
ESP_HIDD_CONN_STATE_CONNECTING,
|
||||
ESP_HIDD_CONN_STATE_DISCONNECTED,
|
||||
ESP_HIDD_CONN_STATE_DISCONNECTING,
|
||||
ESP_HIDD_CONN_STATE_UNKNOWN
|
||||
} esp_hidd_connection_state_t;
|
||||
|
||||
/**
|
||||
* @brief HID device protocol modes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_REPORT_MODE = 0x00,
|
||||
ESP_HIDD_BOOT_MODE = 0x01,
|
||||
ESP_HIDD_UNSUPPORTED_MODE = 0xff
|
||||
} esp_hidd_protocol_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief HIDD characteristics for SDP report
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *description;
|
||||
const char *provider;
|
||||
uint8_t subclass;
|
||||
uint8_t *desc_list;
|
||||
int desc_list_len;
|
||||
} esp_hidd_app_param_t;
|
||||
|
||||
/**
|
||||
* @brief HIDD Quality of Service parameters
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t service_type;
|
||||
uint32_t token_rate;
|
||||
uint32_t token_bucket_size;
|
||||
uint32_t peak_bandwidth;
|
||||
uint32_t access_latency;
|
||||
uint32_t delay_variation;
|
||||
} esp_hidd_qos_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback function events
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDD_INIT_EVT = 0, /*!< When HID device is inited, the event comes */
|
||||
ESP_HIDD_DEINIT_EVT, /*!< When HID device is deinited, the event comes */
|
||||
ESP_HIDD_REGISTER_APP_EVT, /*!< When HID device application registered, the event comes */
|
||||
ESP_HIDD_UNREGISTER_APP_EVT, /*!< When HID device application unregistered, the event comes */
|
||||
ESP_HIDD_OPEN_EVT, /*!< When HID device connection to host opened, the event comes */
|
||||
ESP_HIDD_CLOSE_EVT, /*!< When HID device connection to host closed, the event comes */
|
||||
ESP_HIDD_SEND_REPORT_EVT, /*!< When HID device send report to lower layer, the event comes */
|
||||
ESP_HIDD_REPORT_ERR_EVT, /*!< When HID device report handshanke error to lower layer, the event comes */
|
||||
ESP_HIDD_GET_REPORT_EVT, /*!< When HID device receives GET_REPORT request from host, the event comes */
|
||||
ESP_HIDD_SET_REPORT_EVT, /*!< When HID device receives SET_REPORT request from host, the event comes */
|
||||
ESP_HIDD_SET_PROTOCOL_EVT, /*!< When HID device receives SET_PROTOCOL request from host, the event comes */
|
||||
ESP_HIDD_INTR_DATA_EVT, /*!< When HID device receives DATA from host on intr, the event comes */
|
||||
ESP_HIDD_VC_UNPLUG_EVT, /*!< When HID device initiates Virtual Cable Unplug, the event comes */
|
||||
ESP_HIDD_API_ERR_EVT /*!< When HID device has API error, the event comes */
|
||||
} esp_hidd_cb_event_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_HIDD_SUCCESS,
|
||||
ESP_HIDD_ERROR, /*!< general ESP HD error */
|
||||
ESP_HIDD_NO_RES, /*!< out of system resources */
|
||||
ESP_HIDD_BUSY, /*!< Temporarily can not handle this request. */
|
||||
ESP_HIDD_NO_DATA, /*!< No data. */
|
||||
ESP_HIDD_NEED_INIT, /*!< HIDD module shall init first */
|
||||
ESP_HIDD_NEED_DEINIT, /*!< HIDD module shall deinit first */
|
||||
ESP_HIDD_NEED_REG, /*!< HIDD module shall register first */
|
||||
ESP_HIDD_NEED_DEREG, /*!< HIDD module shall deregister first */
|
||||
ESP_HIDD_NO_CONNECTION, /*!< connection may have been closed */
|
||||
} esp_hidd_status_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_HIDD_INIT_EVT
|
||||
*/
|
||||
struct hidd_init_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} init; /*!< HIDD callback param of ESP_HIDD_INIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_DEINIT_EVT
|
||||
*/
|
||||
struct hidd_deinit_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} deinit; /*!< HIDD callback param of ESP_HIDD_DEINIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_REGISTER_APP_EVT
|
||||
*/
|
||||
struct hidd_register_app_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
bool in_use; /*!< indicate whether use virtual cable plug host address */
|
||||
esp_bd_addr_t bd_addr; /*!< host address */
|
||||
} register_app; /*!< HIDD callback param of ESP_HIDD_REGISTER_APP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_UNREGISTER_APP_EVT
|
||||
*/
|
||||
struct hidd_unregister_app_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
} unregister_app; /*!< HIDD callback param of ESP_HIDD_UNREGISTER_APP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_OPEN_EVT
|
||||
*/
|
||||
struct hidd_open_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
esp_bd_addr_t bd_addr; /*!< host address */
|
||||
} open; /*!< HIDD callback param of ESP_HIDD_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_CLOSE_EVT
|
||||
*/
|
||||
struct hidd_close_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
} close; /*!< HIDD callback param of ESP_HIDD_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SEND_REPORT_EVT
|
||||
*/
|
||||
struct hidd_send_report_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
} send_report; /*!< HIDD callback param of ESP_HIDD_SEND_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_REPORT_ERR_EVT
|
||||
*/
|
||||
struct hidd_report_err_evt_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
} report_err; /*!< HIDD callback param of ESP_HIDD_REPORT_ERR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_GET_REPORT_EVT
|
||||
*/
|
||||
struct hidd_get_report_evt_param {
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
uint16_t buffer_size; /*!< buffer size */
|
||||
} get_report; /*!< HIDD callback param of ESP_HIDD_GET_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SET_REPORT_EVT
|
||||
*/
|
||||
struct hidd_set_report_evt_param {
|
||||
esp_hidd_report_type_t report_type; /*!< report type */
|
||||
uint8_t report_id; /*!< report id */
|
||||
uint16_t len; /*!< set_report data length */
|
||||
uint8_t *data; /*!< set_report data pointer */
|
||||
} set_report; /*!< HIDD callback param of ESP_HIDD_SET_REPORT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_SET_PROTOCOL_EVT
|
||||
*/
|
||||
struct hidd_set_protocol_evt_param {
|
||||
esp_hidd_protocol_mode_t protocol_mode; /*!< protocol mode */
|
||||
} set_protocol; /*!< HIDD callback param of ESP_HIDD_SET_PROTOCOL_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_INTR_DATA_EVT
|
||||
*/
|
||||
struct hidd_intr_data_evt_param {
|
||||
uint8_t report_id; /*!< interrupt channel report id */
|
||||
uint16_t len; /*!< interrupt channel report data length */
|
||||
uint8_t *data; /*!< interrupt channel report data pointer */
|
||||
} intr_data; /*!< HIDD callback param of ESP_HIDD_INTR_DATA_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDD_VC_UNPLUG_EVT
|
||||
*/
|
||||
struct hidd_vc_unplug_param {
|
||||
esp_hidd_status_t status; /*!< operation status */
|
||||
esp_hidd_connection_state_t conn_status; /*!< connection status */
|
||||
} vc_unplug; /*!< HIDD callback param of ESP_HIDD_VC_UNPLUG_EVT */
|
||||
} esp_hidd_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID device callback function type.
|
||||
* @param event: Event type
|
||||
* @param param: Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (esp_hd_cb_t)(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to init callbacks with HID device module.
|
||||
*
|
||||
* @param[in] callback: pointer to the init callback function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_register_callback(esp_hd_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief This function initializes HIDD. This function should be called after esp_bluedroid_enable and
|
||||
* esp_blueroid_init success, and should be called after esp_bt_hid_device_register_callback.
|
||||
* When the operation is complete the callback function will be called with ESP_HIDD_INIT_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_init(void);
|
||||
|
||||
/**
|
||||
* @brief This function de-initializes HIDD interface. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_device_init(). When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_DEINIT_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Registers HIDD parameters with SDP and sets l2cap Quality of Service. This function should be called after
|
||||
* esp_bluedroid_enable and esp_blueroid_init success, and must be done after esp_bt_hid_device_init. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_REGISTER_APP_EVT.
|
||||
*
|
||||
* @param[in] app_param: HIDD parameters
|
||||
* @param[in] in_qos: incoming QoS parameters
|
||||
* @param[in] out_qos: outgoing QoS parameters
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t *app_param, esp_hidd_qos_param_t *in_qos,
|
||||
esp_hidd_qos_param_t *out_qos);
|
||||
|
||||
/**
|
||||
* @brief Removes HIDD parameters from SDP and resets l2cap Quality of Service. This function should be called after esp_bluedroid_enable and
|
||||
* esp_blueroid_init success, and should be called after esp_bt_hid_device_init. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_UNREGISTER_APP_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_unregister_app(void);
|
||||
|
||||
/**
|
||||
* @brief This function connects HIDD interface to connected bluetooth device, if not done already. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_OPEN_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote host bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief This function disconnects HIDD interface. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_CLOSE_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_disconnect(void);
|
||||
|
||||
/**
|
||||
* @brief Send HIDD report. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_SEND_REPORT_EVT.
|
||||
*
|
||||
* @param[in] type: type of report
|
||||
* @param[in] id: report id as defined by descriptor
|
||||
* @param[in] len: length of report
|
||||
* @param[in] data: report data
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Sends HIDD handshake with error info for invalid set_report. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_REPORT_ERR_EVT.
|
||||
*
|
||||
* @param[in] error: type of error
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error);
|
||||
|
||||
/**
|
||||
* @brief Unplug virtual cable of HIDD. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDD_VC_UNPLUG_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_device_virtual_cable_unplug(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
465
components/bt/host/bluedroid/api/include/api/esp_hidh_api.h
Normal file
465
components/bt/host/bluedroid/api/include/api/esp_hidh_api.h
Normal file
@ -0,0 +1,465 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019 Blake Felt
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef __ESP_HIDH_API_H__
|
||||
#define __ESP_HIDH_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BTHH_MAX_DSC_LEN 884
|
||||
|
||||
/**
|
||||
* @brief HID host connection state
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_CONN_STATE_CONNECTED = 0, /*!< connected state */
|
||||
ESP_HIDH_CONN_STATE_CONNECTING, /*!< connecting state */
|
||||
ESP_HIDH_CONN_STATE_DISCONNECTED, /*!< disconnected state */
|
||||
ESP_HIDH_CONN_STATE_DISCONNECTING, /*!< disconnecting state */
|
||||
ESP_HIDH_CONN_STATE_UNKNOWN /*!< unknown state(initial state) */
|
||||
} esp_hidh_connection_state_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_HIDH_OK,
|
||||
ESP_HIDH_HS_HID_NOT_READY, /*!< handshake error : device not ready */
|
||||
ESP_HIDH_HS_INVALID_RPT_ID, /*!< handshake error : invalid report ID */
|
||||
ESP_HIDH_HS_TRANS_NOT_SPT, /*!< handshake error : transaction not spt */
|
||||
ESP_HIDH_HS_INVALID_PARAM, /*!< handshake error : invalid paremter */
|
||||
ESP_HIDH_HS_ERROR, /*!< handshake error : unspecified HS error */
|
||||
ESP_HIDH_ERR, /*!< general ESP HH error */
|
||||
ESP_HIDH_ERR_SDP, /*!< SDP error */
|
||||
ESP_HIDH_ERR_PROTO, /*!< SET_Protocol error,
|
||||
only used in ESP_HIDH_OPEN_EVT callback */
|
||||
|
||||
ESP_HIDH_ERR_DB_FULL, /*!< device database full error, used in
|
||||
ESP_HIDH_OPEN_EVT/ESP_HIDH_ADD_DEV_EVT */
|
||||
ESP_HIDH_ERR_TOD_UNSPT, /*!< type of device not supported */
|
||||
ESP_HIDH_ERR_NO_RES, /*!< out of system resources */
|
||||
ESP_HIDH_ERR_AUTH_FAILED, /*!< authentication fail */
|
||||
ESP_HIDH_ERR_HDL, /*!< connection handle error */
|
||||
ESP_HIDH_ERR_SEC, /*!< encryption error */
|
||||
// self_defined
|
||||
ESP_HIDH_BUSY, /*!< Temporarily can not handle this request. */
|
||||
ESP_HIDH_NO_DATA, /*!< No data. */
|
||||
ESP_HIDH_NEED_INIT, /*!< HIDH module shall init first */
|
||||
ESP_HIDH_NEED_DEINIT, /*!< HIDH module shall deinit first */
|
||||
ESP_HIDH_NO_CONNECTION, /*!< connection may have been closed */
|
||||
} esp_hidh_status_t;
|
||||
|
||||
/**
|
||||
* @brief HID host protocol modes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_BOOT_MODE = 0x00, /*!< boot protocol mode */
|
||||
ESP_HIDH_REPORT_MODE = 0x01, /*!< report protocol mode */
|
||||
ESP_HIDH_UNSUPPORTED_MODE = 0xff /*!< unsupported protocol mode */
|
||||
} esp_hidh_protocol_mode_t;
|
||||
|
||||
/**
|
||||
* @brief HID host report types
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_REPORT_TYPE_OTHER = 0, /*!< unsupported report type */
|
||||
ESP_HIDH_REPORT_TYPE_INPUT, /*!< input report type */
|
||||
ESP_HIDH_REPORT_TYPE_OUTPUT, /*!< output report type */
|
||||
ESP_HIDH_REPORT_TYPE_FEATURE, /*!< feature report type */
|
||||
} esp_hidh_report_type_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback function events
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_HIDH_INIT_EVT = 0, /*!< When HID host is inited, the event comes */
|
||||
ESP_HIDH_DEINIT_EVT, /*!< When HID host is deinited, the event comes */
|
||||
ESP_HIDH_OPEN_EVT, /*!< When HID host connection opened, the event comes */
|
||||
ESP_HIDH_CLOSE_EVT, /*!< When HID host connection closed, the event comes */
|
||||
ESP_HIDH_GET_RPT_EVT, /*!< When Get_Report command is called, the event comes */
|
||||
ESP_HIDH_SET_RPT_EVT, /*!< When Set_Report command is called, the event comes */
|
||||
ESP_HIDH_GET_PROTO_EVT, /*!< When Get_Protocol command is called, the event comes */
|
||||
ESP_HIDH_SET_PROTO_EVT, /*!< When Set_Protocol command is called, the event comes */
|
||||
ESP_HIDH_GET_IDLE_EVT, /*!< When Get_Idle command is called, the event comes */
|
||||
ESP_HIDH_SET_IDLE_EVT, /*!< When Set_Idle command is called, the event comes */
|
||||
ESP_HIDH_GET_DSCP_EVT, /*!< When HIDH is inited, the event comes */
|
||||
ESP_HIDH_ADD_DEV_EVT, /*!< When a device is added, the event comes */
|
||||
ESP_HIDH_RMV_DEV_EVT, /*!< When a device is removed, the event comes */
|
||||
ESP_HIDH_VC_UNPLUG_EVT, /*!< When virtually unplugged, the event comes */
|
||||
ESP_HIDH_DATA_EVT, /*!< When send data on interrupt channel, the event comes */
|
||||
ESP_HIDH_DATA_IND_EVT, /*!< When receive data on interrupt channel, the event comes */
|
||||
ESP_HIDH_SET_INFO_EVT /*!< When set the HID device descriptor, the event comes */
|
||||
} esp_hidh_cb_event_t;
|
||||
|
||||
typedef struct {
|
||||
int attr_mask;
|
||||
uint8_t sub_class;
|
||||
uint8_t app_id;
|
||||
int vendor_id;
|
||||
int product_id;
|
||||
int version;
|
||||
uint8_t ctry_code;
|
||||
int dl_len;
|
||||
uint8_t dsc_list[BTHH_MAX_DSC_LEN];
|
||||
} esp_hidh_hid_info_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_HIDH_INIT_EVT
|
||||
*/
|
||||
struct hidh_init_evt_param {
|
||||
esp_hidh_status_t status; /*!< status */
|
||||
} init; /*!< HIDH callback param of ESP_HIDH_INIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DEINIT_EVT
|
||||
*/
|
||||
struct hidh_uninit_evt_param {
|
||||
esp_hidh_status_t status; /*!< status */
|
||||
} deinit; /*!< HIDH callback param of ESP_HIDH_DEINIT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_OPEN_EVT
|
||||
*/
|
||||
struct hidh_open_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
bool is_orig; /*!< indicate if host intiate the connection */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} open; /*!< HIDH callback param of ESP_HIDH_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_CLOSE_EVT
|
||||
*/
|
||||
struct hidh_close_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} close; /*!< HIDH callback param of ESP_HIDH_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_VC_UNPLUG_EVT
|
||||
*/
|
||||
struct hidh_unplug_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
esp_hidh_connection_state_t conn_status; /*!< connection status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} unplug; /*!< HIDH callback param of ESP_HIDH_VC_UNPLUG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_PROTO_EVT
|
||||
*/
|
||||
struct hidh_get_proto_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */
|
||||
} get_proto; /*!< HIDH callback param of ESP_HIDH_GET_PROTO_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_PROTO_EVT
|
||||
*/
|
||||
struct hidh_set_proto_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_proto; /*!< HIDH callback param of ESP_HIDH_SET_PROTO_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_RPT_EVT
|
||||
*/
|
||||
struct hidh_get_rpt_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint16_t len; /*!< data length */
|
||||
uint8_t *data; /*!< data pointer */
|
||||
} get_rpt; /*!< HIDH callback param of ESP_HIDH_GET_RPT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_RPT_EVT
|
||||
*/
|
||||
struct hidh_set_rpt_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_rpt; /*!< HIDH callback param of ESP_HIDH_SET_RPT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DATA_EVT
|
||||
*/
|
||||
struct hidh_send_data_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint8_t reason; /*!< lower layer failed reason(ref hiddefs.h) */
|
||||
} send_data; /*!< HIDH callback param of ESP_HIDH_DATA_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_IDLE_EVT
|
||||
*/
|
||||
struct hidh_get_idle_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
uint8_t idle_rate; /*!< idle rate */
|
||||
} get_idle; /*!< HIDH callback param of ESP_HIDH_GET_IDLE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_IDLE_EVT
|
||||
*/
|
||||
struct hidh_set_idle_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
} set_idle; /*!< HIDH callback param of ESP_HIDH_SET_IDLE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_DATA_IND_EVT
|
||||
*/
|
||||
struct hidh_data_ind_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_hidh_protocol_mode_t proto_mode; /*!< protocol mode */
|
||||
uint16_t len; /*!< data length */
|
||||
uint8_t *data; /*!< data pointer */
|
||||
} data_ind; /*!< HIDH callback param of ESP_HIDH_DATA_IND_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_ADD_DEV_EVT
|
||||
*/
|
||||
struct hidh_add_dev_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} add_dev; /*!< HIDH callback param of ESP_HIDH_ADD_DEV_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_RMV_DEV_EVT
|
||||
*/
|
||||
struct hidh_rmv_dev_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} rmv_dev; /*!< HIDH callback param of ESP_HIDH_RMV_DEV_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_GET_DSCP_EVT
|
||||
*/
|
||||
struct hidh_get_dscp_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
bool added; /*!< Indicate if added */
|
||||
uint16_t vendor_id; /*!< Vendor ID */
|
||||
uint16_t product_id; /*!< Product ID */
|
||||
uint16_t version; /*!< Version */
|
||||
uint16_t ssr_max_latency; /*!< SSR max latency */
|
||||
uint16_t ssr_min_tout; /*!< SSR min timeout */
|
||||
uint8_t ctry_code; /*!< Country Code */
|
||||
uint16_t dl_len; /*!< Device descriptor length */
|
||||
uint8_t *dsc_list; /*!< Device descriptor pointer */
|
||||
} dscp; /*!< HIDH callback param of ESP_HIDH_GET_DSCP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HIDH_SET_INFO_EVT
|
||||
*/
|
||||
struct hidh_set_info_evt_param {
|
||||
esp_hidh_status_t status; /*!< operation status */
|
||||
uint8_t handle; /*!< device handle */
|
||||
esp_bd_addr_t bd_addr; /*!< device address */
|
||||
} set_info; /*!< HIDH callback param of ESP_HIDH_SET_INFO_EVT */
|
||||
} esp_hidh_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief HID host callback function type
|
||||
* @param event: Event type
|
||||
* @param param: Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (esp_hh_cb_t)(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to init callbacks with HID host module.
|
||||
*
|
||||
* @param[in] callback: pointer to the init callback function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief This function initializes HID host. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_host_register_callback().
|
||||
* When the operation is complete the callback function will be called with ESP_HIDH_INIT_EVT.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_init(void);
|
||||
|
||||
/**
|
||||
* @brief Closes the interface. This function should be called after esp_bluedroid_enable() and
|
||||
* esp_blueroid_init() success, and should be called after esp_bt_hid_host_init().
|
||||
* When the operation is complete the callback function will be called with ESP_HIDH_DEINIT_EVT.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Connect to hid device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_OPEN_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from hid device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_CLOSE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Virtual UnPlug (VUP) the specified HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_VC_UNPLUG_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID device descriptor for the specified HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_INFO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] hid_info: HID device descriptor structure.
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info);
|
||||
|
||||
/**
|
||||
* @brief Get the HID proto mode. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_PROTO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID proto mode. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_PROTO_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] protocol_mode: Protocol mode type.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode);
|
||||
|
||||
/**
|
||||
* @brief Get the HID Idle Time. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_IDLE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Set the HID Idle Time. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_IDLE_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] idle_time: Idle time rate
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time);
|
||||
|
||||
/**
|
||||
* @brief Send a GET_REPORT to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_GET_RPT_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] report_type: Report type
|
||||
* @param[in] report_id: Report id
|
||||
* @param[in] buffer_size: Buffer size
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t report_id,
|
||||
int buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Send a SET_REPORT to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_SET_RPT_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] report_type: Report type
|
||||
* @param[in] report: Report data pointer
|
||||
* @param[in] len: Report data length
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type_t report_type, uint8_t *report,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Send data to HID device. When the operation is complete the callback
|
||||
* function will be called with ESP_HIDH_DATA_EVT.
|
||||
*
|
||||
* @param[in] bd_addr: Remote device bluetooth device address.
|
||||
* @param[in] data: Data pointer
|
||||
* @param[in] len: Data length
|
||||
*
|
||||
* @return - ESP_OK: success
|
||||
* - other: failed
|
||||
*/
|
||||
esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -4498,6 +4498,22 @@ void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
#if (BTA_HD_INCLUDED == TRUE)
|
||||
BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count);
|
||||
for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) {
|
||||
// Check if profiles other than hid are connected
|
||||
if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) &&
|
||||
!bdcmp(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr)) {
|
||||
APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__, bta_dm_conn_srvcs.conn_srvc[j].id);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED == TRUE */
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -117,11 +117,11 @@ tBTA_DM_CFG *const p_bta_dm_cfg = (tBTA_DM_CFG *) &bta_dm_cfg;
|
||||
tBTA_DM_RM *const p_bta_dm_rm_cfg = (tBTA_DM_RM *) &bta_dm_rm_cfg;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
# define BTA_DM_NUM_PM_ENTRY 10 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 10 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 8 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 8 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 6 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 6 /* number of entries in bta_dm_pm_spec */
|
||||
#endif
|
||||
|
||||
#if (BTA_DM_PM_INCLUDED == TRUE)
|
||||
@ -133,10 +133,12 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1]
|
||||
{BTA_ID_JV, BTA_APP_ID_1, 2}, /* app BTA_JV_PM_ID_1, reuse ftc spec table */
|
||||
{BTA_ID_JV, BTA_ALL_APP_ID, 3}, /* reuse fts spec table */
|
||||
{BTA_ID_HS, BTA_ALL_APP_ID, 4}, /* HS spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 5} /* avk spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 5}, /* avk spec table */
|
||||
{BTA_ID_HD, BTA_ALL_APP_ID, 6}, /* hd spec table */
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, 7} /* hh spec table */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 6} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 7} /* gatts spec table */
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 8} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 9} /* gatts spec table */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -254,10 +256,48 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HD : 6 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR3), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HH : 7 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR1), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
|
||||
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* GATTC : 6 */
|
||||
/* GATTC : 8 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
@ -278,7 +318,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
{{BTA_DM_PM_RETRY, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
/* GATTS : 7 */
|
||||
/* GATTS : 9 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
@ -372,7 +412,7 @@ tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
|
||||
seting default max latency and min remote timeout as 0,
|
||||
and always read individual device preference from HH module */
|
||||
{1200, 2, 2}, /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
|
||||
{360, 160, 2} /* BTA_DM_PM_SSR3 - HD */
|
||||
{360, 160, 1600} /* BTA_DM_PM_SSR3 - HD */
|
||||
};
|
||||
|
||||
tBTA_DM_SSR_SPEC *const p_bta_dm_ssr_spec = (tBTA_DM_SSR_SPEC *) &bta_dm_ssr_spec;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#endif
|
||||
@ -1596,6 +1597,11 @@ extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
|
||||
|
||||
#if (BTA_HD_INCLUDED == TRUE)
|
||||
extern BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr);
|
||||
#endif /* BTA_HD_INCLUDED */
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_oob_reply(tBTA_DM_MSG *p_data);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "gatt_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/mutex.h"
|
||||
#include "bta_hh_int.h"
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#include "bta_hh_int.h"
|
||||
@ -304,7 +305,10 @@ void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
|
||||
bta_gattc_deregister_cmpl(p_clreg);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
|
||||
APPL_TRACE_ERROR("Deregister Failed unknown client cif");
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
bta_hh_cleanup_disable(BTA_HH_OK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
|
774
components/bt/host/bluedroid/bta/hd/bta_hd_act.c
Normal file
774
components/bt/host/bluedroid/bta/hd/bta_hd_act.c
Normal file
@ -0,0 +1,774 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* 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 device action functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/osi.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include <string.h>
|
||||
|
||||
static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR *pdata);
|
||||
|
||||
static bool check_descriptor(uint8_t *data, uint16_t length, bool *has_report_id)
|
||||
{
|
||||
uint8_t *ptr = data;
|
||||
*has_report_id = FALSE;
|
||||
while (ptr < data + length) {
|
||||
uint8_t item = *ptr++;
|
||||
switch (item) {
|
||||
case 0xfe: // long item indicator
|
||||
if (ptr < data + length) {
|
||||
ptr += ((*ptr) + 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 0x85: // Report ID
|
||||
*has_report_id = TRUE;
|
||||
default:
|
||||
ptr += (item & 0x03);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ptr == data + length);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_api_enable
|
||||
*
|
||||
* Description Enables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_api_enable(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_ERROR;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevInit();
|
||||
|
||||
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
|
||||
|
||||
HID_DevSetSecurityLevel(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
|
||||
/* store parameters */
|
||||
bta_hd_cb.p_cback = p_data->api_enable.p_cback;
|
||||
|
||||
ret = HID_DevRegister(bta_hd_cback);
|
||||
if (ret == HID_SUCCESS) {
|
||||
status = BTA_HD_OK;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
|
||||
}
|
||||
|
||||
/* signal BTA call back event */
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_ENABLE_EVT, (tBTA_HD *)&status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_api_disable
|
||||
*
|
||||
* Description Disables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_api_disable(void)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_ERROR;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
/* service is not enabled */
|
||||
if (bta_hd_cb.p_cback == NULL)
|
||||
return;
|
||||
|
||||
/* Remove service record */
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
}
|
||||
|
||||
/* Deregister with lower layer */
|
||||
ret = HID_DevDeregister();
|
||||
if (ret == HID_SUCCESS) {
|
||||
status = BTA_HD_OK;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s: Failed to deregister HID device (%d)", __func__, ret);
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_DISABLE_EVT, (tBTA_HD *)&status);
|
||||
|
||||
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_register_act
|
||||
*
|
||||
* Description Registers SDP record
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_register_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD ret;
|
||||
tBTA_HD_REGISTER_APP *p_app_data = (tBTA_HD_REGISTER_APP *)p_data;
|
||||
bool use_report_id = FALSE;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret.reg_status.in_use = FALSE;
|
||||
|
||||
/* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
|
||||
* itself is well-formed. Also check if descriptor has Report Id item so we
|
||||
* know if report will have prefix or not. */
|
||||
if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
|
||||
!check_descriptor(p_app_data->d_data, p_app_data->d_len, &use_report_id)) {
|
||||
APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
|
||||
ret.reg_status.status = BTA_HD_ERROR;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret.reg_status.status = BTA_HD_OK;
|
||||
|
||||
/* Remove old record if for some reason it's already registered */
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
}
|
||||
|
||||
bta_hd_cb.use_report_id = use_report_id;
|
||||
bta_hd_cb.sdp_handle = SDP_CreateRecord();
|
||||
HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name, p_app_data->description, p_app_data->provider,
|
||||
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
|
||||
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
|
||||
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
|
||||
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
|
||||
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
|
||||
|
||||
HID_DevSetOutgoingQos(p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
|
||||
p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
|
||||
p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
|
||||
|
||||
// application is registered so we can accept incoming connections
|
||||
HID_DevSetIncomingPolicy(TRUE);
|
||||
|
||||
if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
|
||||
ret.reg_status.in_use = TRUE;
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_unregister_act
|
||||
*
|
||||
* Description Unregisters SDP record
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_unregister_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_STATUS status = BTA_HD_OK;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
// application is no longer registered so we do not want incoming connections
|
||||
HID_DevSetIncomingPolicy(FALSE);
|
||||
|
||||
if (bta_hd_cb.sdp_handle != 0) {
|
||||
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
|
||||
}
|
||||
|
||||
bta_hd_cb.sdp_handle = 0;
|
||||
bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_UNREGISTER_APP_EVT, (tBTA_HD *)&status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_unregister2_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_unregister2_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
// close first
|
||||
bta_hd_close_act(p_data);
|
||||
|
||||
// then unregister
|
||||
bta_hd_unregister_act(p_data);
|
||||
|
||||
if (bta_hd_cb.disable_w4_close) {
|
||||
bta_hd_api_disable();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_connect_act
|
||||
*
|
||||
* Description Connect to device (must be virtually plugged)
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_connect_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
do {
|
||||
ret = HID_DevPlugDevice(p_ctrl->addr);
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevPlugDevice returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = HID_DevConnect();
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevConnect returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_ctrl->addr);
|
||||
cback_data.conn.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTING;
|
||||
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_disconnect_act
|
||||
*
|
||||
* Description Disconnect from device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_disconnect_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret = HID_DevDisconnect();
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevDisconnect returned %d", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HID_DevGetDevice(&cback_data.conn.bda) == HID_SUCCESS) {
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTING;
|
||||
bta_hd_cb.p_cback(BTA_HD_CLOSE_EVT, &cback_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_add_device_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_add_device_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevPlugDevice(p_ctrl->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_remove_device_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_remove_device_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevUnplugDevice(p_ctrl->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_send_report_act
|
||||
*
|
||||
* Description Sends report
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_send_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_SEND_REPORT *p_report = (tBTA_HD_SEND_REPORT *)p_data;
|
||||
uint8_t channel;
|
||||
uint8_t report_id;
|
||||
tBTA_HD cback_data;
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_VERBOSE("%s", __func__);
|
||||
|
||||
channel = p_report->use_intr ? HID_CHANNEL_INTR : HID_CHANNEL_CTRL;
|
||||
report_id = (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) ? p_report->id : 0x00;
|
||||
|
||||
ret = HID_DevSendReport(channel, p_report->type, report_id, p_report->len, p_report->data);
|
||||
|
||||
/* trigger PM */
|
||||
bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
|
||||
cback_data.send_report.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.send_report.reason = ret;
|
||||
cback_data.send_report.report_id = report_id;
|
||||
cback_data.send_report.report_type = p_report->type;
|
||||
bta_hd_cb.p_cback(BTA_HD_SEND_REPORT_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_report_error_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_report_error_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_REPORT_ERR *p_report = (tBTA_HD_REPORT_ERR *)p_data;
|
||||
tHID_STATUS ret;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s: error = %d", __func__, p_report->error);
|
||||
|
||||
ret = HID_DevReportError(p_report->error);
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevReportError returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
cback_data.report_err.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
|
||||
cback_data.report_err.reason = ret;
|
||||
bta_hd_cb.p_cback(BTA_HD_REPORT_ERR_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_vc_unplug_act
|
||||
*
|
||||
* Description Sends Virtual Cable Unplug
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_vc_unplug_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_hd_cb.vc_unplug = TRUE;
|
||||
ret = HID_DevVirtualCableUnplug();
|
||||
|
||||
if (ret != HID_SUCCESS) {
|
||||
APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
/* trigger PM */
|
||||
bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_open_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_open_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
HID_DevPlugDevice(p_cback->addr);
|
||||
bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTED;
|
||||
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_close_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_close_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
if (bta_hd_cb.vc_unplug) {
|
||||
bta_hd_cb.vc_unplug = FALSE;
|
||||
HID_DevUnplugDevice(p_cback->addr);
|
||||
cback_event = BTA_HD_VC_UNPLUG_EVT;
|
||||
}
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
memset(bta_hd_cb.bd_addr, 0, sizeof(BD_ADDR));
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
|
||||
bta_hd_cb.p_cback(cback_event, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_intr_data_act
|
||||
*
|
||||
* Description Handles incoming DATA request on intr
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint16_t len = p_msg->len;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_INTR_DATA ret;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
|
||||
ret.report_id = *p_buf;
|
||||
len--;
|
||||
p_buf++;
|
||||
} else {
|
||||
ret.report_id = 0;
|
||||
}
|
||||
|
||||
ret.len = len;
|
||||
ret.p_data = p_buf;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_INTR_DATA_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_get_report_act
|
||||
*
|
||||
* Description Handles incoming GET_REPORT request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_get_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
bool rep_size_follows = p_cback->data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_GET_REPORT ret = {0, 0, 0};
|
||||
uint16_t remaining_len = p_msg->len;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if (remaining_len < 1) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
|
||||
ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
|
||||
p_buf++;
|
||||
remaining_len--;
|
||||
|
||||
if (bta_hd_cb.use_report_id) {
|
||||
if (remaining_len < 1) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
ret.report_id = *p_buf;
|
||||
p_buf++;
|
||||
remaining_len--;
|
||||
}
|
||||
|
||||
if (rep_size_follows) {
|
||||
if (remaining_len < 2) {
|
||||
APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
|
||||
return;
|
||||
}
|
||||
ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
|
||||
}
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_GET_REPORT_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_set_report_act
|
||||
*
|
||||
* Description Handles incoming SET_REPORT request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
BT_HDR *p_msg = p_cback->p_data;
|
||||
uint16_t len = p_msg->len;
|
||||
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
|
||||
p_buf++;
|
||||
len--;
|
||||
|
||||
if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
|
||||
ret.report_id = *p_buf;
|
||||
len--;
|
||||
p_buf++;
|
||||
} else {
|
||||
ret.report_id = 0;
|
||||
}
|
||||
|
||||
ret.len = len;
|
||||
ret.p_data = p_buf;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, (tBTA_HD *)&ret);
|
||||
if (p_msg) {
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_set_protocol_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE);
|
||||
cback_data.set_protocol = p_cback->data;
|
||||
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_SET_PROTOCOL_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_vc_unplug_done_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
|
||||
|
||||
HID_DevUnplugDevice(p_cback->addr);
|
||||
|
||||
bdcpy(cback_data.conn.bda, p_cback->addr);
|
||||
bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
|
||||
cback_data.conn.status = BTA_HD_OK;
|
||||
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
|
||||
(*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_suspend_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_exit_suspend_act
|
||||
*
|
||||
* Description
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
|
||||
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
bta_sys_busy(BTA_ID_HD, 1, p_cback->addr);
|
||||
bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_cback
|
||||
*
|
||||
* Description BTA HD callback function
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR *pdata)
|
||||
{
|
||||
tBTA_HD_CBACK_DATA *p_buf = NULL;
|
||||
uint16_t sm_event = BTA_HD_INVALID_EVT;
|
||||
|
||||
APPL_TRACE_API("%s: event=%d", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case HID_DHOST_EVT_OPEN:
|
||||
sm_event = BTA_HD_INT_OPEN_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_CLOSE:
|
||||
sm_event = BTA_HD_INT_CLOSE_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_GET_REPORT:
|
||||
sm_event = BTA_HD_INT_GET_REPORT_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SET_REPORT:
|
||||
sm_event = BTA_HD_INT_SET_REPORT_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SET_PROTOCOL:
|
||||
sm_event = BTA_HD_INT_SET_PROTOCOL_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_INTR_DATA:
|
||||
sm_event = BTA_HD_INT_INTR_DATA_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_VC_UNPLUG:
|
||||
sm_event = BTA_HD_INT_VC_UNPLUG_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_SUSPEND:
|
||||
sm_event = BTA_HD_INT_SUSPEND_EVT;
|
||||
break;
|
||||
|
||||
case HID_DHOST_EVT_EXIT_SUSPEND:
|
||||
sm_event = BTA_HD_INT_EXIT_SUSPEND_EVT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sm_event != BTA_HD_INVALID_EVT &&
|
||||
(p_buf = (tBTA_HD_CBACK_DATA *)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) + sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->hdr.event = sm_event;
|
||||
bdcpy(p_buf->addr, bd_addr);
|
||||
p_buf->data = data;
|
||||
p_buf->p_data = pdata;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
287
components/bt/host/bluedroid/bta/hd/bta_hd_api.c
Normal file
287
components/bt/host/bluedroid/bta/hd/bta_hd_api.c
Normal file
@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* 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 DEVICE API in the subsystem of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants
|
||||
****************************************************************************/
|
||||
static const tBTA_SYS_REG bta_hd_reg = {bta_hd_hdl_event, BTA_HdDisable};
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdEnable
|
||||
*
|
||||
* Description Enables HID device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void BTA_HdEnable(tBTA_HD_CBACK *p_cback)
|
||||
{
|
||||
tBTA_HD_API_ENABLE *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
bta_sys_register(BTA_ID_HD, &bta_hd_reg);
|
||||
p_buf = (tBTA_HD_API_ENABLE *)osi_malloc((uint16_t)sizeof(tBTA_HD_API_ENABLE));
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HD_API_ENABLE));
|
||||
p_buf->hdr.event = BTA_HD_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdDisable
|
||||
*
|
||||
* Description Disables HID device.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void BTA_HdDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
bta_sys_deregister(BTA_ID_HD);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRegisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
*registered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_in_qos, tBTA_HD_QOS_INFO *p_out_qos)
|
||||
{
|
||||
tBTA_HD_REGISTER_APP *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_REGISTER_APP *)osi_malloc(sizeof(tBTA_HD_REGISTER_APP))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REGISTER_APP_EVT;
|
||||
if (p_app_info->p_name) {
|
||||
strncpy(p_buf->name, p_app_info->p_name, BTA_HD_APP_NAME_LEN);
|
||||
p_buf->name[BTA_HD_APP_NAME_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->name[0] = '\0';
|
||||
}
|
||||
if (p_app_info->p_description) {
|
||||
strncpy(p_buf->description, p_app_info->p_description, BTA_HD_APP_DESCRIPTION_LEN);
|
||||
p_buf->description[BTA_HD_APP_DESCRIPTION_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->description[0] = '\0';
|
||||
}
|
||||
if (p_app_info->p_provider) {
|
||||
strncpy(p_buf->provider, p_app_info->p_provider, BTA_HD_APP_PROVIDER_LEN);
|
||||
p_buf->provider[BTA_HD_APP_PROVIDER_LEN] = '\0';
|
||||
} else {
|
||||
p_buf->provider[0] = '\0';
|
||||
}
|
||||
p_buf->subclass = p_app_info->subclass;
|
||||
p_buf->d_len = p_app_info->descriptor.dl_len;
|
||||
memcpy(p_buf->d_data, p_app_info->descriptor.dsc_list, p_app_info->descriptor.dl_len);
|
||||
// copy qos data as-is
|
||||
memcpy(&p_buf->in_qos, p_in_qos, sizeof(tBTA_HD_QOS_INFO));
|
||||
memcpy(&p_buf->out_qos, p_out_qos, sizeof(tBTA_HD_QOS_INFO));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdUnregisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
*unregistered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdUnregisterApp(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_UNREGISTER_APP_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdSendReport
|
||||
*
|
||||
* Description This function is called when report is to be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdSendReport(tBTA_HD_REPORT *p_report)
|
||||
{
|
||||
tBTA_HD_SEND_REPORT *p_buf;
|
||||
APPL_TRACE_VERBOSE("%s", __func__);
|
||||
if (p_report->len > BTA_HD_REPORT_LEN) {
|
||||
APPL_TRACE_WARNING("%s, report len (%d) > MTU len (%d), can't send report."
|
||||
" Increase value of HID_DEV_MTU_SIZE to send larger reports",
|
||||
__func__, p_report->len, BTA_HD_REPORT_LEN);
|
||||
return;
|
||||
}
|
||||
if ((p_buf = (tBTA_HD_SEND_REPORT *)osi_malloc(sizeof(tBTA_HD_SEND_REPORT))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_SEND_REPORT_EVT;
|
||||
p_buf->use_intr = p_report->use_intr;
|
||||
p_buf->type = p_report->type;
|
||||
p_buf->id = p_report->id;
|
||||
p_buf->len = p_report->len;
|
||||
memcpy(p_buf->data, p_report->p_data, p_report->len);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdVirtualCableUnplug
|
||||
*
|
||||
* Description This function is called when VCU shall be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdVirtualCableUnplug(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_VC_UNPLUG_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdConnect
|
||||
*
|
||||
* Description This function is called when connection to host shall be
|
||||
* made
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdConnect(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_CONNECT_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdDisconnect
|
||||
*
|
||||
* Description This function is called when host shall be disconnected
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdDisconnect(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HD_API_DISCONNECT_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdAddDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually cabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdAddDevice(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_ADD_DEVICE_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRemoveDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually uncabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRemoveDevice(BD_ADDR addr)
|
||||
{
|
||||
tBTA_HD_DEVICE_CTRL *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_DEVICE_CTRL *)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REMOVE_DEVICE_EVT;
|
||||
memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdReportError
|
||||
*
|
||||
* Description This function is called when reporting error for set report
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdReportError(uint8_t error)
|
||||
{
|
||||
tBTA_HD_REPORT_ERR *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_REPORT_ERR *)osi_malloc(sizeof(tBTA_HD_REPORT_ERR))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_REPORT_ERROR_EVT;
|
||||
p_buf->error = error;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
320
components/bt/host/bluedroid/bta/hd/bta_hd_main.c
Normal file
320
components/bt/host/bluedroid/bta/hd/bta_hd_main.c
Normal file
@ -0,0 +1,320 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* 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_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta_hd_int.h"
|
||||
#include <string.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants and types
|
||||
****************************************************************************/
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_HD_INIT_ST,
|
||||
BTA_HD_IDLE_ST, /* not connected, waiting for connection */
|
||||
BTA_HD_CONN_ST, /* host connected */
|
||||
BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT */
|
||||
};
|
||||
typedef uint8_t tBTA_HD_STATE;
|
||||
|
||||
/* state machine actions */
|
||||
enum {
|
||||
BTA_HD_REGISTER_ACT,
|
||||
BTA_HD_UNREGISTER_ACT,
|
||||
BTA_HD_UNREGISTER2_ACT,
|
||||
BTA_HD_CONNECT_ACT,
|
||||
BTA_HD_DISCONNECT_ACT,
|
||||
BTA_HD_ADD_DEVICE_ACT,
|
||||
BTA_HD_REMOVE_DEVICE_ACT,
|
||||
BTA_HD_SEND_REPORT_ACT,
|
||||
BTA_HD_REPORT_ERROR_ACT,
|
||||
BTA_HD_VC_UNPLUG_ACT,
|
||||
BTA_HD_OPEN_ACT,
|
||||
BTA_HD_CLOSE_ACT,
|
||||
BTA_HD_INTR_DATA_ACT,
|
||||
BTA_HD_GET_REPORT_ACT,
|
||||
BTA_HD_SET_REPORT_ACT,
|
||||
BTA_HD_SET_PROTOCOL_ACT,
|
||||
BTA_HD_VC_UNPLUG_DONE_ACT,
|
||||
BTA_HD_SUSPEND_ACT,
|
||||
BTA_HD_EXIT_SUSPEND_ACT,
|
||||
BTA_HD_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_HD_IGNORE BTA_HD_NUM_ACTIONS
|
||||
|
||||
typedef void (*tBTA_HD_ACTION)(tBTA_HD_DATA *p_data);
|
||||
/* action functions */
|
||||
const tBTA_HD_ACTION bta_hd_action[] = {
|
||||
bta_hd_register_act, bta_hd_unregister_act, bta_hd_unregister2_act, bta_hd_connect_act,
|
||||
bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act,
|
||||
bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act,
|
||||
bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act,
|
||||
bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act,
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_HD_ACTION 0 /* position of action */
|
||||
#define BTA_HD_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_HD_NUM_COLS 2 /* number of columns */
|
||||
|
||||
const uint8_t bta_hd_st_init[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state
|
||||
*/
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_REGISTER_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state
|
||||
*/
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_UNREGISTER_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_CONNECT_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_conn[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_REPORT_ERROR_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_CLOSE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_INTR_DATA_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_GET_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_SET_REPORT_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_SET_PROTOCOL_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_DONE_ACT, BTA_HD_IDLE_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_SUSPEND_ACT, BTA_HD_CONN_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_EXIT_SUSPEND_ACT, BTA_HD_CONN_ST},
|
||||
};
|
||||
|
||||
const uint8_t bta_hd_st_transient_to_init[][BTA_HD_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
|
||||
/* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
/* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const uint8_t (*tBTA_HD_ST_TBL)[BTA_HD_NUM_COLS];
|
||||
/* state table */
|
||||
const tBTA_HD_ST_TBL bta_hd_st_tbl[] = {bta_hd_st_init, bta_hd_st_idle, bta_hd_st_conn, bta_hd_st_transient_to_init};
|
||||
|
||||
/*****************************************************************************
|
||||
* Global data
|
||||
****************************************************************************/
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HD_CB bta_hd_cb;
|
||||
#else
|
||||
tBTA_HD_CB *bta_hd_cb_ptr;
|
||||
#endif
|
||||
|
||||
static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code);
|
||||
static const char *bta_hd_state_code(tBTA_HD_STATE state_code);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_sm_execute
|
||||
*
|
||||
* Description State machine event handling function for HID Device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void bta_hd_sm_execute(uint16_t event, tBTA_HD_DATA *p_data)
|
||||
{
|
||||
tBTA_HD_ST_TBL state_table;
|
||||
tBTA_HD_STATE prev_state;
|
||||
uint8_t action;
|
||||
tBTA_HD cback_data;
|
||||
|
||||
APPL_TRACE_EVENT("%s: state=%s (%d) event=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state,
|
||||
bta_hd_evt_code(event), event);
|
||||
|
||||
prev_state = bta_hd_cb.state;
|
||||
memset(&cback_data, 0, sizeof(tBTA_HD));
|
||||
state_table = bta_hd_st_tbl[bta_hd_cb.state];
|
||||
event &= 0xff;
|
||||
|
||||
if ((action = state_table[event][BTA_HD_ACTION]) < BTA_HD_IGNORE) {
|
||||
(*bta_hd_action[action])(p_data);
|
||||
}
|
||||
|
||||
bta_hd_cb.state = state_table[event][BTA_HD_NEXT_STATE];
|
||||
|
||||
if (bta_hd_cb.state != prev_state) {
|
||||
APPL_TRACE_EVENT("%s: [new] state=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hd_hdl_event
|
||||
*
|
||||
* Description HID device main event handling function.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
bool bta_hd_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event);
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_HD_API_ENABLE_EVT:
|
||||
bta_hd_api_enable((tBTA_HD_DATA *)p_msg);
|
||||
break;
|
||||
case BTA_HD_API_DISABLE_EVT:
|
||||
if (bta_hd_cb.state == BTA_HD_CONN_ST) {
|
||||
APPL_TRACE_WARNING("%s: host connected, disconnect before disabling", __func__);
|
||||
// unregister (and disconnect)
|
||||
bta_hd_cb.disable_w4_close = TRUE;
|
||||
bta_hd_sm_execute(BTA_HD_API_UNREGISTER_APP_EVT, (tBTA_HD_DATA *)p_msg);
|
||||
} else {
|
||||
bta_hd_api_disable();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bta_hd_sm_execute(p_msg->event, (tBTA_HD_DATA *)p_msg);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_HD_API_REGISTER_APP_EVT:
|
||||
return "BTA_HD_API_REGISTER_APP_EVT";
|
||||
case BTA_HD_API_UNREGISTER_APP_EVT:
|
||||
return "BTA_HD_API_UNREGISTER_APP_EVT";
|
||||
case BTA_HD_API_CONNECT_EVT:
|
||||
return "BTA_HD_API_CONNECT_EVT";
|
||||
case BTA_HD_API_DISCONNECT_EVT:
|
||||
return "BTA_HD_API_DISCONNECT_EVT";
|
||||
case BTA_HD_API_ADD_DEVICE_EVT:
|
||||
return "BTA_HD_API_ADD_DEVICE_EVT";
|
||||
case BTA_HD_API_REMOVE_DEVICE_EVT:
|
||||
return "BTA_HD_API_REMOVE_DEVICE_EVT";
|
||||
case BTA_HD_API_SEND_REPORT_EVT:
|
||||
return "BTA_HD_API_SEND_REPORT_EVT";
|
||||
case BTA_HD_API_REPORT_ERROR_EVT:
|
||||
return "BTA_HD_API_REPORT_ERROR_EVT";
|
||||
case BTA_HD_API_VC_UNPLUG_EVT:
|
||||
return "BTA_HD_API_VC_UNPLUG_EVT";
|
||||
case BTA_HD_INT_OPEN_EVT:
|
||||
return "BTA_HD_INT_OPEN_EVT";
|
||||
case BTA_HD_INT_CLOSE_EVT:
|
||||
return "BTA_HD_INT_CLOSE_EVT";
|
||||
case BTA_HD_INT_INTR_DATA_EVT:
|
||||
return "BTA_HD_INT_INTR_DATA_EVT";
|
||||
case BTA_HD_INT_GET_REPORT_EVT:
|
||||
return "BTA_HD_INT_GET_REPORT_EVT";
|
||||
case BTA_HD_INT_SET_REPORT_EVT:
|
||||
return "BTA_HD_INT_SET_REPORT_EVT";
|
||||
case BTA_HD_INT_SET_PROTOCOL_EVT:
|
||||
return "BTA_HD_INT_SET_PROTOCOL_EVT";
|
||||
case BTA_HD_INT_VC_UNPLUG_EVT:
|
||||
return "BTA_HD_INT_VC_UNPLUG_EVT";
|
||||
case BTA_HD_INT_SUSPEND_EVT:
|
||||
return "BTA_HD_INT_SUSPEND_EVT";
|
||||
case BTA_HD_INT_EXIT_SUSPEND_EVT:
|
||||
return "BTA_HD_INT_EXIT_SUSPEND_EVT";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *bta_hd_state_code(tBTA_HD_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_HD_INIT_ST:
|
||||
return "BTA_HD_INIT_ST";
|
||||
case BTA_HD_IDLE_ST:
|
||||
return "BTA_HD_IDLE_ST";
|
||||
case BTA_HD_CONN_ST:
|
||||
return "BTA_HD_CONN_ST";
|
||||
case BTA_HD_TRANSIENT_TO_INIT_ST:
|
||||
return "BTA_HD_TRANSIENT_TO_INIT_ST";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
#endif /* BTA_HD_INCLUDED */
|
168
components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h
Normal file
168
components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h
Normal file
@ -0,0 +1,168 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* 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 Device internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HD_INT_H
|
||||
#define BTA_HD_INT_H
|
||||
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "stack/hiddefs.h"
|
||||
|
||||
enum {
|
||||
BTA_HD_API_REGISTER_APP_EVT = BTA_SYS_EVT_START(BTA_ID_HD),
|
||||
BTA_HD_API_UNREGISTER_APP_EVT,
|
||||
BTA_HD_API_CONNECT_EVT,
|
||||
BTA_HD_API_DISCONNECT_EVT,
|
||||
BTA_HD_API_ADD_DEVICE_EVT,
|
||||
BTA_HD_API_REMOVE_DEVICE_EVT,
|
||||
BTA_HD_API_SEND_REPORT_EVT,
|
||||
BTA_HD_API_REPORT_ERROR_EVT,
|
||||
BTA_HD_API_VC_UNPLUG_EVT,
|
||||
BTA_HD_INT_OPEN_EVT,
|
||||
BTA_HD_INT_CLOSE_EVT,
|
||||
BTA_HD_INT_INTR_DATA_EVT,
|
||||
BTA_HD_INT_GET_REPORT_EVT,
|
||||
BTA_HD_INT_SET_REPORT_EVT,
|
||||
BTA_HD_INT_SET_PROTOCOL_EVT,
|
||||
BTA_HD_INT_VC_UNPLUG_EVT,
|
||||
BTA_HD_INT_SUSPEND_EVT,
|
||||
BTA_HD_INT_EXIT_SUSPEND_EVT,
|
||||
/* handled outside state machine */
|
||||
BTA_HD_API_ENABLE_EVT,
|
||||
BTA_HD_API_DISABLE_EVT
|
||||
};
|
||||
typedef uint16_t tBTA_HD_INT_EVT;
|
||||
#define BTA_HD_INVALID_EVT (BTA_HD_API_DISABLE_EVT + 1)
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_HD_CBACK *p_cback;
|
||||
} tBTA_HD_API_ENABLE;
|
||||
#define BTA_HD_APP_NAME_LEN 50
|
||||
#define BTA_HD_APP_DESCRIPTION_LEN 50
|
||||
#define BTA_HD_APP_PROVIDER_LEN 50
|
||||
#define BTA_HD_APP_DESCRIPTOR_LEN 2048
|
||||
#define BTA_HD_STATE_DISABLED 0x00
|
||||
#define BTA_HD_STATE_ENABLED 0x01
|
||||
#define BTA_HD_STATE_IDLE 0x02
|
||||
#define BTA_HD_STATE_CONNECTED 0x03
|
||||
#define BTA_HD_STATE_DISABLING 0x04
|
||||
#define BTA_HD_STATE_REMOVING 0x05
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
char name[BTA_HD_APP_NAME_LEN + 1];
|
||||
char description[BTA_HD_APP_DESCRIPTION_LEN + 1];
|
||||
char provider[BTA_HD_APP_PROVIDER_LEN + 1];
|
||||
uint8_t subclass;
|
||||
uint16_t d_len;
|
||||
uint8_t d_data[BTA_HD_APP_DESCRIPTOR_LEN];
|
||||
tBTA_HD_QOS_INFO in_qos;
|
||||
tBTA_HD_QOS_INFO out_qos;
|
||||
} tBTA_HD_REGISTER_APP;
|
||||
|
||||
#define BTA_HD_REPORT_LEN HID_DEV_MTU_SIZE
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
bool use_intr;
|
||||
uint8_t type;
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t data[BTA_HD_REPORT_LEN];
|
||||
} tBTA_HD_SEND_REPORT;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
} tBTA_HD_DEVICE_CTRL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
uint8_t error;
|
||||
} tBTA_HD_REPORT_ERR;
|
||||
|
||||
/* union of all event data types */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_HD_API_ENABLE api_enable;
|
||||
tBTA_HD_REGISTER_APP register_app;
|
||||
tBTA_HD_SEND_REPORT send_report;
|
||||
tBTA_HD_DEVICE_CTRL device_ctrl;
|
||||
tBTA_HD_REPORT_ERR report_err;
|
||||
} tBTA_HD_DATA;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
uint32_t data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HD_CBACK_DATA;
|
||||
|
||||
/******************************************************************************
|
||||
* Main Control Block
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
tBTA_HD_CBACK *p_cback;
|
||||
uint32_t sdp_handle;
|
||||
uint8_t trace_level;
|
||||
uint8_t state;
|
||||
BD_ADDR bd_addr;
|
||||
bool use_report_id;
|
||||
bool boot_mode;
|
||||
bool vc_unplug;
|
||||
bool disable_w4_close;
|
||||
} tBTA_HD_CB;
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_HD_CB bta_hd_cb;
|
||||
#else
|
||||
extern tBTA_HD_CB *bta_hd_cb_ptr;
|
||||
#define bta_hd_cb (*bta_hd_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************/
|
||||
extern bool bta_hd_hdl_event(BT_HDR *p_msg);
|
||||
extern void bta_hd_api_enable(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_api_disable(void);
|
||||
extern void bta_hd_register_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_unregister_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_unregister2_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_connect_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_disconnect_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_add_device_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_remove_device_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_send_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_report_error_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_vc_unplug_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_open_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_close_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_get_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data);
|
||||
extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data);
|
||||
|
||||
#endif
|
@ -323,6 +323,7 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
|
||||
p_cb->sec_mask = p_data->api_conn.sec_mask;
|
||||
p_cb->mode = p_data->api_conn.mode;
|
||||
p_cb->new_mode = p_data->api_conn.mode;
|
||||
bta_hh_cb.p_cur = p_cb;
|
||||
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
@ -451,6 +452,8 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
HID_HostRemoveDev( p_cb->incoming_hid_handle);
|
||||
}
|
||||
conn_dat.status = status;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat);
|
||||
|
||||
/* move state machine W4_CONN ->IDLE */
|
||||
@ -521,6 +524,8 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
|
||||
memset((void *)&conn, 0, sizeof (tBTA_HH_CONN));
|
||||
conn.handle = dev_handle;
|
||||
/* check if host initiate the connection*/
|
||||
conn.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn.bda, p_cb->addr);
|
||||
|
||||
/* increase connection number */
|
||||
@ -587,6 +592,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
APPL_TRACE_EVENT ("bta_hh_open_act: Device[%d] connected", dev_handle);
|
||||
#endif
|
||||
|
||||
p_cb->incoming_conn = TRUE;
|
||||
/* SDP has been done */
|
||||
if (p_cb->app_id != 0) {
|
||||
bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
|
||||
@ -594,7 +600,6 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
/* app_id == 0 indicates an incoming conenction request arrives without SDP
|
||||
performed, do it first */
|
||||
{
|
||||
p_cb->incoming_conn = TRUE;
|
||||
/* store the handle here in case sdp fails - need to disconnect */
|
||||
p_cb->incoming_hid_handle = dev_handle;
|
||||
|
||||
@ -676,6 +681,11 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
case BTA_HH_SET_IDLE_EVT :
|
||||
cback_data.handle = p_cb->hid_handle;
|
||||
cback_data.status = bta_hh_get_trans_status(p_data->hid_cback.data);
|
||||
if (cback_data.status == BTA_HH_OK) {
|
||||
p_cb->mode = p_cb->new_mode;
|
||||
} else {
|
||||
p_cb->new_mode = p_cb->mode;
|
||||
}
|
||||
(* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&cback_data);
|
||||
p_cb->w4_evt = 0;
|
||||
break;
|
||||
@ -684,6 +694,8 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
case BTA_HH_OPEN_EVT:
|
||||
conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK;
|
||||
conn.handle = p_cb->hid_handle;
|
||||
/* check if host initiate the connection*/
|
||||
conn.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn.bda, p_cb->addr);
|
||||
(* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&conn);
|
||||
#if BTA_HH_DEBUG
|
||||
@ -787,6 +799,8 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
conn_dat.handle = p_cb->hid_handle;
|
||||
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ?
|
||||
BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn_dat.bda, p_cb->addr);
|
||||
HID_HostCloseDev(p_cb->hid_handle);
|
||||
|
||||
@ -836,6 +850,8 @@ void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
/* Failure in opening connection */
|
||||
conn_dat.handle = p_cb->hid_handle;
|
||||
conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
|
||||
/* check if host initiate the connection*/
|
||||
conn_dat.is_orig = !p_cb->incoming_conn;
|
||||
bdcpy(conn_dat.bda, p_cb->addr);
|
||||
HID_HostCloseDev(p_cb->hid_handle);
|
||||
|
||||
@ -1019,7 +1035,9 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
tHID_STATUS status;
|
||||
tBTA_HH_CBDATA cbdata = {BTA_HH_OK, 0};
|
||||
tBTA_HH_API_SENDDATA send_data = {BTA_HH_OK, 0, 0};
|
||||
UINT16 event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
|
||||
BTA_HH_FST_TRANS_CB_EVT;
|
||||
|
||||
@ -1031,25 +1049,33 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
|
||||
cbdata.handle = p_cb->hid_handle;
|
||||
send_data.handle = p_cb->hid_handle;
|
||||
|
||||
/* match up BTE/BTA report/boot mode def */
|
||||
if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL) {
|
||||
p_cb->new_mode = p_data->api_sndcmd.param;
|
||||
p_data->api_sndcmd.param = ( p_data->api_sndcmd.param == BTA_HH_PROTO_RPT_MODE) ? \
|
||||
HID_PAR_PROTOCOL_REPORT : HID_PAR_PROTOCOL_BOOT_MODE;
|
||||
}
|
||||
|
||||
if (HID_HostWriteDev (p_cb->hid_handle,
|
||||
p_data->api_sndcmd.t_type,
|
||||
p_data->api_sndcmd.param,
|
||||
p_data->api_sndcmd.data,
|
||||
p_data->api_sndcmd.rpt_id,
|
||||
p_data->api_sndcmd.p_data) != HID_SUCCESS) {
|
||||
APPL_TRACE_ERROR("HID_HostWriteDev Error ");
|
||||
status = HID_HostWriteDev(p_cb->hid_handle, p_data->api_sndcmd.t_type, p_data->api_sndcmd.param,
|
||||
p_data->api_sndcmd.data, p_data->api_sndcmd.rpt_id, p_data->api_sndcmd.p_data);
|
||||
if (status != HID_SUCCESS) {
|
||||
APPL_TRACE_ERROR("HID_HostWriteDev status:%d", status);
|
||||
cbdata.status = BTA_HH_ERR;
|
||||
send_data.status = BTA_HH_ERR;
|
||||
|
||||
if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL &&
|
||||
p_data->api_sndcmd.t_type != HID_TRANS_DATA) {
|
||||
(* bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
|
||||
if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
|
||||
switch (p_data->api_sndcmd.t_type) {
|
||||
case HID_TRANS_DATA:
|
||||
event = BTA_HH_DATA_EVT;
|
||||
send_data.reason = status;
|
||||
(*bta_hh_cb.p_cback)(event, (tBTA_HH *)&send_data);
|
||||
break;
|
||||
default:
|
||||
(*bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
|
||||
break;
|
||||
}
|
||||
} else if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, (tBTA_HH *)&cbdata);
|
||||
}
|
||||
@ -1070,6 +1096,7 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
p_cb->w4_evt = event;
|
||||
break;
|
||||
case HID_TRANS_DATA: /* output report */
|
||||
(*bta_hh_cb.p_cback)(BTA_HH_DATA_EVT, (tBTA_HH *)&send_data);
|
||||
/* fall through */
|
||||
case HID_TRANS_CONTROL:
|
||||
/* no handshake event will be generated */
|
||||
@ -1098,7 +1125,6 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -24,9 +24,9 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_hh_api.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
#include "bta/bta_hh_api.h"
|
||||
|
||||
|
||||
/* max number of device types supported by BTA */
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "bta/utl.h"
|
||||
|
||||
#define LOG_TAG "bt_bta_hh"
|
||||
#include "osi/include/log.h"
|
||||
// #include "osi/include/log.h"
|
||||
|
||||
#ifndef BTA_HH_LE_RECONN
|
||||
#define BTA_HH_LE_RECONN TRUE
|
||||
|
@ -292,6 +292,8 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_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:
|
||||
@ -340,7 +342,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data)
|
||||
|
||||
default:
|
||||
/* invalid handle, call bad API event */
|
||||
APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
|
||||
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);
|
||||
@ -443,6 +445,10 @@ BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class)
|
||||
}
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class);
|
||||
APPL_TRACE_ERROR("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
@ -460,9 +460,11 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
||||
}
|
||||
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
|
||||
|
||||
(* 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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -243,6 +243,7 @@ typedef struct {
|
||||
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)
|
||||
@ -364,6 +365,7 @@ 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);
|
||||
@ -391,6 +393,7 @@ 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);
|
||||
|
@ -78,7 +78,7 @@ typedef UINT8 tBTA_STATUS;
|
||||
#define BTA_SAP_SERVICE_ID 17 /* SIM Access profile */
|
||||
#define BTA_A2DP_SINK_SERVICE_ID 18 /* A2DP Sink */
|
||||
#define BTA_AVRCP_SERVICE_ID 19 /* A/V remote control */
|
||||
#define BTA_HID_SERVICE_ID 20 /* HID */
|
||||
#define BTA_HID_SERVICE_ID 20 /* HID Host*/
|
||||
#define BTA_VDP_SERVICE_ID 21 /* Video distribution */
|
||||
#define BTA_PBAP_SERVICE_ID 22 /* PhoneBook Access Server*/
|
||||
#define BTA_HSP_HS_SERVICE_ID 23 /* HFP HS role */
|
||||
@ -1331,8 +1331,8 @@ typedef UINT8 tBTA_DM_PM_ACTION;
|
||||
#endif
|
||||
|
||||
#ifndef BTA_DM_PM_SNIFF2_MAX
|
||||
#define BTA_DM_PM_SNIFF2_MAX 180
|
||||
#define BTA_DM_PM_SNIFF2_MIN 150
|
||||
#define BTA_DM_PM_SNIFF2_MAX 54 //180
|
||||
#define BTA_DM_PM_SNIFF2_MIN 30 //150
|
||||
#define BTA_DM_PM_SNIFF2_ATTEMPT 4
|
||||
#define BTA_DM_PM_SNIFF2_TIMEOUT 1
|
||||
#endif
|
||||
@ -1345,8 +1345,8 @@ typedef UINT8 tBTA_DM_PM_ACTION;
|
||||
#endif
|
||||
|
||||
#ifndef BTA_DM_PM_SNIFF4_MAX
|
||||
#define BTA_DM_PM_SNIFF4_MAX 54
|
||||
#define BTA_DM_PM_SNIFF4_MIN 30
|
||||
#define BTA_DM_PM_SNIFF4_MAX 18 //54
|
||||
#define BTA_DM_PM_SNIFF4_MIN 10 //30
|
||||
#define BTA_DM_PM_SNIFF4_ATTEMPT 4
|
||||
#define BTA_DM_PM_SNIFF4_TIMEOUT 1
|
||||
#endif
|
||||
|
295
components/bt/host/bluedroid/bta/include/bta/bta_hd_api.h
Normal file
295
components/bt/host/bluedroid/bta/include/bta/bta_hd_api.h
Normal file
@ -0,0 +1,295 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HD_API_H
|
||||
#define BTA_HD_API_H
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "stack/hidd_api.h"
|
||||
|
||||
#if BTA_HD_INCLUDED == TRUE
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants and Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BTA_HD_DEBUG
|
||||
#define BTA_HD_DEBUG TRUE
|
||||
#endif
|
||||
|
||||
/* BTA HID Device callback events */
|
||||
#define BTA_HD_ENABLE_EVT 0 /* BT-HD enabled */
|
||||
#define BTA_HD_DISABLE_EVT 1 /* BT-HD disabled */
|
||||
#define BTA_HD_REGISTER_APP_EVT 2 /* application registered */
|
||||
#define BTA_HD_UNREGISTER_APP_EVT 3 /* application unregistered */
|
||||
#define BTA_HD_OPEN_EVT 4 /* connection to host opened */
|
||||
#define BTA_HD_CLOSE_EVT 5 /* connection to host closed */
|
||||
#define BTA_HD_GET_REPORT_EVT 6 /* GET_REPORT request from host */
|
||||
#define BTA_HD_SET_REPORT_EVT 7 /* SET_REPORT request from host */
|
||||
#define BTA_HD_SET_PROTOCOL_EVT 8 /* SET_PROTOCOL request from host */
|
||||
#define BTA_HD_INTR_DATA_EVT 9 /* DATA received from host on intr */
|
||||
#define BTA_HD_VC_UNPLUG_EVT 10 /* Virtual Cable Unplug */
|
||||
// #define BTA_HD_CONN_STATE_EVT 11 /* Report connection state change */
|
||||
#define BTA_HD_SEND_REPORT_EVT 12 /* Send report finish */
|
||||
#define BTA_HD_REPORT_ERR_EVT 13 /* Report Handshake finish */
|
||||
#define BTA_HD_API_ERR_EVT 99 /* BT-HD API error */
|
||||
|
||||
typedef uint16_t tBTA_HD_EVT;
|
||||
|
||||
enum { BTA_HD_OK, BTA_HD_ERROR };
|
||||
|
||||
typedef enum {
|
||||
BTA_HD_CONN_STATE_CONNECTED,
|
||||
BTA_HD_CONN_STATE_CONNECTING,
|
||||
BTA_HD_CONN_STATE_DISCONNECTED,
|
||||
BTA_HD_CONN_STATE_DISCONNECTING,
|
||||
BTA_HD_CONN_STATE_UNKNOWN
|
||||
} tBTA_HD_CONN_STAT;
|
||||
|
||||
typedef uint8_t tBTA_HD_STATUS;
|
||||
typedef tHID_DEV_DSCP_INFO tBTA_HD_DEV_DESCR;
|
||||
|
||||
typedef struct {
|
||||
char *p_name;
|
||||
char *p_description;
|
||||
char *p_provider;
|
||||
uint8_t subclass;
|
||||
tBTA_HD_DEV_DESCR descriptor;
|
||||
} tBTA_HD_APP_INFO;
|
||||
|
||||
typedef struct {
|
||||
uint8_t service_type;
|
||||
uint32_t token_rate;
|
||||
uint32_t token_bucket_size;
|
||||
uint32_t peak_bandwidth;
|
||||
uint32_t access_latency;
|
||||
uint32_t delay_variation;
|
||||
} tBTA_HD_QOS_INFO;
|
||||
|
||||
typedef struct {
|
||||
bool use_intr;
|
||||
uint8_t type;
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t *p_data;
|
||||
} tBTA_HD_REPORT;
|
||||
|
||||
typedef struct {
|
||||
tBTA_HD_STATUS status;
|
||||
bool in_use;
|
||||
BD_ADDR bda;
|
||||
} tBTA_HD_REG_STATUS;
|
||||
|
||||
typedef struct {
|
||||
BD_ADDR bda;
|
||||
tBTA_HD_STATUS status;
|
||||
tBTA_HD_CONN_STAT conn_status;
|
||||
} tBTA_HD_CONN;
|
||||
|
||||
typedef struct {
|
||||
uint8_t report_type;
|
||||
uint8_t report_id;
|
||||
uint16_t buffer_size;
|
||||
} tBTA_HD_GET_REPORT;
|
||||
|
||||
typedef struct {
|
||||
uint8_t report_type;
|
||||
uint8_t report_id;
|
||||
uint16_t len;
|
||||
uint8_t *p_data;
|
||||
} tBTA_HD_SET_REPORT;
|
||||
|
||||
typedef uint8_t tBTA_HD_SET_PROTOCOL;
|
||||
|
||||
typedef struct {
|
||||
uint8_t report_id;
|
||||
uint16_t len;
|
||||
uint8_t *p_data;
|
||||
} tBTA_HD_INTR_DATA;
|
||||
|
||||
typedef struct {
|
||||
tBTA_HD_STATUS status;
|
||||
uint8_t reason;
|
||||
uint8_t report_type;
|
||||
uint8_t report_id;
|
||||
} tBTA_HD_API_SEND_REPORT;
|
||||
|
||||
typedef struct {
|
||||
tBTA_HD_STATUS status;
|
||||
uint8_t reason;
|
||||
} tBTA_HD_API_REPORT_ERR;
|
||||
|
||||
/* union of data associated with HD callback */
|
||||
typedef union {
|
||||
tBTA_HD_STATUS status; /* BTA_HD_ENABLE_EVT
|
||||
BTA_HD_DISABLE_EVT
|
||||
BTA_HD_UNREGISTER_APP_EVT */
|
||||
tBTA_HD_REG_STATUS reg_status; /* BTA_HD_REGISTER_APP_EVT */
|
||||
tBTA_HD_CONN conn; /* BTA_HD_OPEN_EVT
|
||||
BTA_HD_CLOSE_EVT
|
||||
BTA_HD_VC_UNPLUG_EVT
|
||||
BTA_HD_OWN_VC_UNPLUG_EVT */
|
||||
tBTA_HD_GET_REPORT get_report; /* BTA_HD_GET_REPORT */
|
||||
tBTA_HD_SET_REPORT set_report; /* BTA_HD_SET_REPORT */
|
||||
tBTA_HD_SET_PROTOCOL set_protocol; /* BTA_HD_SETPROTOCOL */
|
||||
tBTA_HD_INTR_DATA intr_data; /* BTA_HD_INTR_DATA_EVT */
|
||||
tBTA_HD_API_SEND_REPORT send_report; /* BTA_HD_API_SEND_REPORT_EVT */
|
||||
tBTA_HD_API_REPORT_ERR report_err; /* BTA_HD_API_REPORT_ERR_EVT */
|
||||
} tBTA_HD;
|
||||
|
||||
/* BTA HD callback function */
|
||||
typedef void (tBTA_HD_CBACK)(tBTA_HD_EVT event, tBTA_HD *p_data);
|
||||
|
||||
/*****************************************************************************
|
||||
* External Function Declarations
|
||||
****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HhRegister
|
||||
*
|
||||
* Description This function enable HID host and registers HID-Host with
|
||||
* lower layers.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdEnable(tBTA_HD_CBACK *p_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HhDeregister
|
||||
*
|
||||
* Description This function is called when the host is about power down.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdDisable(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRegisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
* registered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_in_qos, tBTA_HD_QOS_INFO *p_out_qos);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdUnregisterApp
|
||||
*
|
||||
* Description This function is called when application should be
|
||||
* unregistered
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdUnregisterApp(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdSendReport
|
||||
*
|
||||
* Description This function is called when report is to be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdSendReport(tBTA_HD_REPORT *p_report);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdVirtualCableUnplug
|
||||
*
|
||||
* Description This function is called when VCU shall be sent
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdVirtualCableUnplug(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdConnect
|
||||
*
|
||||
* Description This function is called when connection to host shall be
|
||||
* made.
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdConnect(BD_ADDR addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdDisconnect
|
||||
*
|
||||
* Description This function is called when host shall be disconnected
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdDisconnect(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdAddDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually cabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdAddDevice(BD_ADDR addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdRemoveDevice
|
||||
*
|
||||
* Description This function is called when a device is virtually uncabled
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRemoveDevice(BD_ADDR addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function BTA_HdReportError
|
||||
*
|
||||
* Description This function is called when reporting error for set report
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void BTA_HdReportError(uint8_t error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_HD_INCLUDED */
|
||||
#endif /* BTA_HD_API_H */
|
@ -58,7 +58,8 @@
|
||||
#define BTA_HH_VC_UNPLUG_EVT 13 /* virtually unplugged */
|
||||
#define BTA_HH_DATA_EVT 15
|
||||
#define BTA_HH_API_ERR_EVT 16 /* API error is caught */
|
||||
#define BTA_HH_UPDATE_SCPP_EVT 17 /* update scan paramter complete */
|
||||
#define BTA_HH_UPDATE_SCPP_EVT 17 /* update scan paramter complete */
|
||||
#define BTA_HH_DATA_IND_EVT 18 /* Data on interrupt channel */
|
||||
|
||||
typedef UINT16 tBTA_HH_EVT;
|
||||
|
||||
@ -131,8 +132,8 @@ enum {
|
||||
BTA_HH_ERR_TOD_UNSPT, /* type of device not supported */
|
||||
BTA_HH_ERR_NO_RES, /* out of system resources */
|
||||
BTA_HH_ERR_AUTH_FAILED, /* authentication fail */
|
||||
BTA_HH_ERR_HDL,
|
||||
BTA_HH_ERR_SEC
|
||||
BTA_HH_ERR_HDL, /* connection handle error */
|
||||
BTA_HH_ERR_SEC, /* encryption error */
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATUS;
|
||||
|
||||
@ -210,6 +211,7 @@ typedef struct {
|
||||
BD_ADDR bda; /* HID device bd address */
|
||||
tBTA_HH_STATUS status; /* operation status */
|
||||
UINT8 handle; /* device handle */
|
||||
BOOLEAN is_orig; /* indicate if host initiate connection */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BOOLEAN le_hid; /* is LE devices? */
|
||||
BOOLEAN scps_supported; /* scan parameter service supported */
|
||||
@ -257,9 +259,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
tBTA_HH_BOOT_RPT_ID dev_type; /* type of device report */
|
||||
union {
|
||||
tBTA_HH_KEYBD_RPT keybd_rpt; /* keyboard report */
|
||||
tBTA_HH_MICE_RPT mice_rpt; /* mouse report */
|
||||
} data_rpt;
|
||||
tBTA_HH_KEYBD_RPT keybd_rpt; /* keyboard report */
|
||||
tBTA_HH_MICE_RPT mice_rpt; /* mouse report */
|
||||
} data_rpt;
|
||||
} tBTA_HH_BOOT_RPT;
|
||||
|
||||
/* handshake data */
|
||||
@ -267,13 +269,29 @@ typedef struct {
|
||||
tBTA_HH_STATUS status; /* handshake status */
|
||||
UINT8 handle; /* device handle */
|
||||
union {
|
||||
tBTA_HH_PROTO_MODE proto_mode; /* GET_PROTO_EVT :protocol mode */
|
||||
BT_HDR *p_rpt_data; /* GET_RPT_EVT : report data */
|
||||
UINT8 idle_rate; /* GET_IDLE_EVT : idle rate */
|
||||
} rsp_data;
|
||||
tBTA_HH_PROTO_MODE proto_mode; /* GET_PROTO_EVT :protocol mode */
|
||||
BT_HDR *p_rpt_data; /* GET_RPT_EVT : report data */
|
||||
UINT8 idle_rate; /* GET_IDLE_EVT : idle rate */
|
||||
} rsp_data;
|
||||
|
||||
} tBTA_HH_HSDATA;
|
||||
|
||||
|
||||
/* upper layer send data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* handshake status */
|
||||
UINT8 handle; /* device handle */
|
||||
UINT8 reason; /* send data failed reason */
|
||||
} tBTA_HH_API_SENDDATA;
|
||||
|
||||
/* interrupt channel data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* handshake status */
|
||||
UINT8 handle; /* device handle */
|
||||
tBTA_HH_PROTO_MODE proto_mode; /* protocol mode */
|
||||
BT_HDR *p_data; /* DATA_EVT : feature report data */
|
||||
} tBTA_HH_INTDATA;
|
||||
|
||||
/* union of data associated with HD callback */
|
||||
typedef union {
|
||||
tBTA_HH_DEV_INFO dev_info; /* BTA_HH_ADD_DEV_EVT, BTA_HH_RMV_DEV_EVT */
|
||||
@ -290,10 +308,12 @@ typedef union {
|
||||
BTA_HH_GET_RPT_EVT
|
||||
BTA_HH_GET_PROTO_EVT
|
||||
BTA_HH_GET_IDLE_EVT */
|
||||
tBTA_HH_API_SENDDATA send_data; /* BTA_HH_DATA_EVT */
|
||||
tBTA_HH_INTDATA int_data; /* BTA_HH_DATA_IND_EVT */
|
||||
} tBTA_HH;
|
||||
|
||||
/* BTA HH callback function */
|
||||
typedef void (tBTA_HH_CBACK) (tBTA_HH_EVT event, tBTA_HH *p_data);
|
||||
typedef void (tBTA_HH_CBACK)(tBTA_HH_EVT event, tBTA_HH *p_data);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -16,11 +16,13 @@
|
||||
#include "btc/btc_storage.h"
|
||||
#include "btc/btc_util.h"
|
||||
#include "osi/osi.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "esp_system.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "device/bdaddr.h"
|
||||
#include "btc/btc_config.h"
|
||||
#include "btc_hh.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -247,3 +249,252 @@ bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *d
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_add_hid_device_info
|
||||
*
|
||||
* Description BTC storage API - Adds the hid information of bonded hid
|
||||
* devices-to NVRAM
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if the store was successful,
|
||||
* BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bt_status_t btc_storage_add_hid_device_info(bt_bdaddr_t *remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
|
||||
uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version,
|
||||
uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
|
||||
uint16_t dl_len, uint8_t *dsc_list)
|
||||
{
|
||||
BTC_TRACE_DEBUG("btc_storage_add_hid_device_info:");
|
||||
bdstr_t bdstr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
btc_config_lock();
|
||||
int ret = btc_config_set_int(bdstr, "HidAttrMask", attr_mask);
|
||||
ret &= btc_config_set_int(bdstr, "HidSubClass", sub_class);
|
||||
ret &= btc_config_set_int(bdstr, "HidAppId", app_id);
|
||||
ret &= btc_config_set_int(bdstr, "HidVendorId", vendor_id);
|
||||
ret &= btc_config_set_int(bdstr, "HidProductId", product_id);
|
||||
ret &= btc_config_set_int(bdstr, "HidVersion", version);
|
||||
ret &= btc_config_set_int(bdstr, "HidCountryCode", ctry_code);
|
||||
ret &= btc_config_set_int(bdstr, "HidSSRMaxLatency", ssr_max_latency);
|
||||
ret &= btc_config_set_int(bdstr, "HidSSRMinTimeout", ssr_min_tout);
|
||||
if (dl_len > 0)
|
||||
btc_config_set_bin(bdstr, "HidDescriptor", dsc_list, dl_len);
|
||||
btc_config_flush();
|
||||
btc_config_unlock();
|
||||
|
||||
BTC_TRACE_DEBUG("Storage add hid device info %d\n", ret);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_load_bonded_hid_info
|
||||
*
|
||||
* Description BTIF storage API - Loads hid info for all the bonded devices
|
||||
* from NVRAM and adds those devices to the BTA_HH.
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_load_bonded_hid_info(void)
|
||||
{
|
||||
int value;
|
||||
btc_config_lock();
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (string_is_bdaddr(name) && btc_config_exist(name, BTC_STORAGE_LINK_KEY_TYPE_STR) &&
|
||||
btc_config_exist(name, BTC_STORAGE_PIN_LENGTH_STR) && btc_config_exist(name, BTC_STORAGE_SC_SUPPORT) &&
|
||||
btc_config_exist(name, BTC_STORAGE_LINK_KEY_STR) && btc_config_exist(name, "HidAttrMask")) {
|
||||
btc_config_get_int(name, "HidAttrMask", &value);
|
||||
uint16_t attr_mask = (uint16_t)value;
|
||||
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info;
|
||||
memset(&dscp_info, 0, sizeof(dscp_info));
|
||||
|
||||
btc_config_get_int(name, "HidSubClass", &value);
|
||||
uint8_t sub_class = (uint8_t)value;
|
||||
|
||||
btc_config_get_int(name, "HidAppId", &value);
|
||||
uint8_t app_id = (uint8_t)value;
|
||||
|
||||
btc_config_get_int(name, "HidVendorId", &value);
|
||||
dscp_info.vendor_id = (uint16_t)value;
|
||||
|
||||
btc_config_get_int(name, "HidProductId", &value);
|
||||
dscp_info.product_id = (uint16_t)value;
|
||||
|
||||
btc_config_get_int(name, "HidVersion", &value);
|
||||
dscp_info.version = (uint8_t)value;
|
||||
|
||||
btc_config_get_int(name, "HidCountryCode", &value);
|
||||
dscp_info.ctry_code = (uint8_t)value;
|
||||
|
||||
value = 0;
|
||||
btc_config_get_int(name, "HidSSRMaxLatency", &value);
|
||||
dscp_info.ssr_max_latency = (uint16_t)value;
|
||||
|
||||
value = 0;
|
||||
btc_config_get_int(name, "HidSSRMinTimeout", &value);
|
||||
dscp_info.ssr_min_tout = (uint16_t)value;
|
||||
|
||||
size_t len = btc_config_get_bin_length(name, "HidDescriptor");
|
||||
if (len > 0) {
|
||||
dscp_info.descriptor.dl_len = (uint16_t)len;
|
||||
dscp_info.descriptor.dsc_list = (uint8_t *)osi_malloc(len);
|
||||
btc_config_get_bin(name, "HidDescriptor", (uint8_t *)dscp_info.descriptor.dsc_list, &len);
|
||||
}
|
||||
|
||||
// add extracted information to BTA HH
|
||||
bt_bdaddr_t bd_addr;
|
||||
if (string_to_bdaddr(name, &bd_addr) && btc_hh_add_added_dev(*(BD_ADDR *)&bd_addr, attr_mask)) {
|
||||
BTA_HhAddDev(*(BD_ADDR *)&bd_addr, attr_mask, sub_class, app_id, dscp_info);
|
||||
}
|
||||
|
||||
if (dscp_info.descriptor.dsc_list) {
|
||||
osi_free(dscp_info.descriptor.dsc_list);
|
||||
dscp_info.descriptor.dsc_list = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
btc_config_unlock();
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_remove_hid_info
|
||||
*
|
||||
* Description BTC storage API - Deletes the bonded hid device info from
|
||||
* NVRAM
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if the deletion was successful,
|
||||
* BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
int ret = 1;
|
||||
btc_config_lock();
|
||||
if (btc_config_exist(bdstr, "HidAttrMask")) {
|
||||
ret &= btc_config_remove(bdstr, "HidAttrMask");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidSubClass")) {
|
||||
ret &= btc_config_remove(bdstr, "HidSubClass");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidAppId")) {
|
||||
ret &= btc_config_remove(bdstr, "HidAppId");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidVendorId")) {
|
||||
ret &= btc_config_remove(bdstr, "HidVendorId");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidProductId")) {
|
||||
ret &= btc_config_remove(bdstr, "HidProductId");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidVersion")) {
|
||||
ret &= btc_config_remove(bdstr, "HidVersion");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidCountryCode")) {
|
||||
ret &= btc_config_remove(bdstr, "HidCountryCode");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidSSRMaxLatency")) {
|
||||
ret &= btc_config_remove(bdstr, "HidSSRMaxLatency");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidSSRMinTimeout")) {
|
||||
ret &= btc_config_remove(bdstr, "HidSSRMinTimeout");
|
||||
}
|
||||
if (btc_config_exist(bdstr, "HidDescriptor")) {
|
||||
ret &= btc_config_remove(bdstr, "HidDescriptor");
|
||||
}
|
||||
btc_config_flush();
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_DEBUG("%s ret:%d", __func__, ret);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
}
|
||||
#endif //(defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
|
||||
#if (defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
#include "bta/bta_hd_api.h"
|
||||
/*******************************************************************************
|
||||
* Function btc_storage_load_hidd
|
||||
*
|
||||
* Description Loads hidd bonded device and "plugs" it into hidd
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_load_hidd(void)
|
||||
{
|
||||
bt_bdaddr_t bd_addr;
|
||||
int value;
|
||||
btc_config_lock();
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (string_is_bdaddr(name) && btc_config_exist(name, BTC_STORAGE_LINK_KEY_TYPE_STR) &&
|
||||
btc_config_exist(name, BTC_STORAGE_PIN_LENGTH_STR) && btc_config_exist(name, BTC_STORAGE_SC_SUPPORT) &&
|
||||
btc_config_exist(name, BTC_STORAGE_LINK_KEY_STR)) {
|
||||
BTC_TRACE_DEBUG("Remote device:%s", name);
|
||||
if (btc_config_get_int(name, "HidDeviceCabled", &value)) {
|
||||
string_to_bdaddr(name, &bd_addr);
|
||||
BTA_HdAddDevice(bd_addr.address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
btc_config_unlock();
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_set_hidd
|
||||
*
|
||||
* Description Stores hidd bonded device info in nvram.
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_set_hidd(bt_bdaddr_t *remote_bd_addr)
|
||||
{
|
||||
bdstr_t bdstr = {0};
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
btc_config_lock();
|
||||
int ret = btc_config_set_int(bdstr, "HidDeviceCabled", 1);
|
||||
btc_config_flush();
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_DEBUG("%s ret:%d", __func__, ret);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_remove_hidd
|
||||
*
|
||||
* Description Removes hidd bonded device info from nvram
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_remove_hidd(bt_bdaddr_t *remote_bd_addr)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
int ret = 0;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
btc_config_lock();
|
||||
if (btc_config_exist(bdstr, "HidVersion")) {
|
||||
ret = btc_config_remove(bdstr, "HidDeviceCabled");
|
||||
}
|
||||
btc_config_flush();
|
||||
btc_config_unlock();
|
||||
|
||||
BTC_TRACE_DEBUG("%s ret:%d", __func__, ret);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
}
|
||||
#endif //(defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "bta/bta_ag_api.h"
|
||||
#endif ///BTA_AG_INCLUDED == TRUE
|
||||
|
||||
#if (BTA_HH_INCLUDED == TRUE)
|
||||
#include "bta/bta_hh_api.h"
|
||||
#endif ///BTA_HH_INCLUDED == TRUE
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "common/bt_defs.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "bta/bta_api.h"
|
||||
@ -209,6 +213,56 @@ const char* dump_hf_call_setup_state(esp_hf_call_setup_status_t call_setup_state
|
||||
|
||||
#endif // #if (BTA_AG_INCLUDED == TRUE)
|
||||
|
||||
#if (BTA_HH_INCLUDED == TRUE)
|
||||
const char *dump_hh_event(uint16_t event)
|
||||
{
|
||||
switch (event) {
|
||||
CASE_RETURN_STR(BTA_HH_ENABLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_DISABLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_OPEN_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_CLOSE_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_GET_RPT_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_SET_RPT_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_GET_PROTO_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_SET_PROTO_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_GET_IDLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_SET_IDLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_GET_DSCP_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_ADD_DEV_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_RMV_DEV_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_VC_UNPLUG_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_DATA_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_API_ERR_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_UPDATE_SCPP_EVT)
|
||||
CASE_RETURN_STR(BTA_HH_DATA_IND_EVT)
|
||||
default:
|
||||
return "UNKNOWN MSG ID";
|
||||
}
|
||||
}
|
||||
#endif ///BTA_HH_INCLUDED
|
||||
|
||||
#if BTA_HD_INCLUDED == TRUE
|
||||
const char* dump_hd_event(uint16_t event) {
|
||||
switch (event) {
|
||||
CASE_RETURN_STR(BTA_HD_ENABLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_DISABLE_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_REGISTER_APP_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_UNREGISTER_APP_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_OPEN_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_CLOSE_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_GET_REPORT_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_SET_REPORT_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_SET_PROTOCOL_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_INTR_DATA_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_VC_UNPLUG_EVT)
|
||||
//CASE_RETURN_STR(BTA_HD_CONN_STATE_EVT)
|
||||
CASE_RETURN_STR(BTA_HD_API_ERR_EVT)
|
||||
default:
|
||||
return "UNKNOWN MSG ID";
|
||||
}
|
||||
}
|
||||
#endif ///BTA_HD_INCLUDED
|
||||
|
||||
UINT32 devclass2uint(DEV_CLASS dev_class)
|
||||
{
|
||||
UINT32 cod = 0;
|
||||
|
@ -27,6 +27,10 @@
|
||||
#define BTC_STORAGE_PIN_LENGTH_STR "PinLength"
|
||||
#define BTC_STORAGE_SC_SUPPORT "SCSupport"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btc_storage_add_bonded_device
|
||||
@ -91,4 +95,85 @@ int btc_storage_get_num_bt_bond_devices(void);
|
||||
*******************************************************************************/
|
||||
bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *dev_num);
|
||||
|
||||
#if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_add_hid_device_info
|
||||
*
|
||||
* Description BTC storage API - Adds the hid information of bonded hid
|
||||
* devices-to NVRAM
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if the store was successful,
|
||||
* BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bt_status_t btc_storage_add_hid_device_info(bt_bdaddr_t *remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
|
||||
uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version,
|
||||
uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
|
||||
uint16_t dl_len, uint8_t *dsc_list);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_load_bonded_hid_info
|
||||
*
|
||||
* Description BTIF storage API - Loads hid info for all the bonded devices
|
||||
* from NVRAM and adds those devices to the BTA_HH.
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_load_bonded_hid_info(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_remove_hid_info
|
||||
*
|
||||
* Description BTC storage API - Deletes the bonded hid device info from
|
||||
* NVRAM
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if the deletion was successful,
|
||||
* BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr);
|
||||
#endif // (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
|
||||
|
||||
#if (defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
* Function btc_storage_load_hidd
|
||||
*
|
||||
* Description Loads hidd bonded device and "plugs" it into hidd
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_load_hidd(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_set_hidd
|
||||
*
|
||||
* Description Stores hidd bonded device info in nvram.
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_set_hidd(bt_bdaddr_t *remote_bd_addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_storage_remove_hidd
|
||||
*
|
||||
* Description Removes hidd bonded device info from nvram
|
||||
*
|
||||
* Returns BT_STATUS_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
bt_status_t btc_storage_remove_hidd(bt_bdaddr_t *remote_bd_addr);
|
||||
#endif //(defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTC_STORAGE_H */
|
||||
|
@ -31,7 +31,9 @@
|
||||
********************************************************************************/
|
||||
typedef char bdstr_t[18];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
** Functions
|
||||
********************************************************************************/
|
||||
@ -48,6 +50,14 @@ const char *dump_hf_call_state(esp_hf_call_status_t call_state);
|
||||
const char* dump_hf_call_setup_state(esp_hf_call_setup_status_t call_setup_state);
|
||||
#endif
|
||||
|
||||
#if(BTA_HD_INCLUDED == TRUE)
|
||||
const char* dump_hd_event(uint16_t event);
|
||||
#endif
|
||||
|
||||
#if(BTA_HH_INCLUDED == TRUE)
|
||||
const char* dump_hh_event(uint16_t event);
|
||||
#endif
|
||||
|
||||
UINT32 devclass2uint(DEV_CLASS dev_class);
|
||||
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
|
||||
void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128);
|
||||
@ -58,4 +68,8 @@ esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status);
|
||||
esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status);
|
||||
esp_bt_status_t btc_bta_status_to_esp_status (uint8_t bta_status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BTC_UTIL_H__ */
|
||||
|
152
components/bt/host/bluedroid/btc/profile/std/hid/bta_hh_co.c
Normal file
152
components/bt/host/bluedroid/btc/profile/std/hid/bta_hh_co.c
Normal file
@ -0,0 +1,152 @@
|
||||
#include "btc_hh.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "string.h"
|
||||
#if HID_HOST_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hh_co_open
|
||||
*
|
||||
* Description When connection is opened, this call-out function is executed
|
||||
* by HH to do platform specific initialization.
|
||||
*
|
||||
* Returns void.
|
||||
******************************************************************************/
|
||||
void bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, tBTA_HH_ATTR_MASK attr_mask, uint8_t app_id)
|
||||
{
|
||||
uint32_t i;
|
||||
btc_hh_device_t *p_dev = NULL;
|
||||
|
||||
if (dev_handle == BTA_HH_INVALID_HANDLE) {
|
||||
APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __func__, dev_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < BTC_HH_MAX_HID; i++) {
|
||||
p_dev = &btc_hh_cb.devices[i];
|
||||
if (p_dev->dev_status != ESP_HIDH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) {
|
||||
// We found a device with the same handle. Must be a device reconnected.
|
||||
APPL_TRACE_WARNING("%s: Found an existing device with the same handle dev_status=%d, "
|
||||
"dev_handle=0x%2x, attr_mask=0x%04x, sub_class=0x%02x, app_id=%d",
|
||||
__func__, p_dev->dev_status, dev_handle, p_dev->attr_mask, p_dev->sub_class,
|
||||
p_dev->app_id);
|
||||
break;
|
||||
}
|
||||
p_dev = NULL;
|
||||
}
|
||||
|
||||
if (p_dev == NULL) {
|
||||
// Did not find a device reconnection case. Find an empty slot now.
|
||||
for (i = 0; i < BTC_HH_MAX_HID; i++) {
|
||||
if (btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_UNKNOWN) {
|
||||
p_dev = &btc_hh_cb.devices[i];
|
||||
p_dev->dev_handle = dev_handle;
|
||||
p_dev->attr_mask = attr_mask;
|
||||
p_dev->sub_class = sub_class;
|
||||
p_dev->app_id = app_id;
|
||||
p_dev->local_vup = false;
|
||||
|
||||
btc_hh_cb.device_num++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_dev == NULL) {
|
||||
APPL_TRACE_ERROR("%s: Error: too many HID devices are connected", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
p_dev->dev_status = ESP_HIDH_CONN_STATE_CONNECTED;
|
||||
APPL_TRACE_DEBUG("%s: Return device status %d", __func__, p_dev->dev_status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hh_co_close
|
||||
*
|
||||
* Description When connection is closed, this call-out function is executed
|
||||
* by HH to do platform specific finalization.
|
||||
*
|
||||
* Parameters dev_handle - device handle
|
||||
* app_id - application id
|
||||
*
|
||||
* Returns void.
|
||||
******************************************************************************/
|
||||
void bta_hh_co_close(uint8_t dev_handle, uint8_t app_id)
|
||||
{
|
||||
uint32_t i;
|
||||
btc_hh_device_t *p_dev = NULL;
|
||||
|
||||
APPL_TRACE_WARNING("%s: dev_handle = %d, app_id = %d", __func__, dev_handle, app_id);
|
||||
if (dev_handle == BTA_HH_INVALID_HANDLE) {
|
||||
APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __func__, dev_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < BTC_HH_MAX_HID; i++) {
|
||||
p_dev = &btc_hh_cb.devices[i];
|
||||
if (p_dev->dev_status != ESP_HIDH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) {
|
||||
APPL_TRACE_WARNING("%s: Found an existing device with the same handle "
|
||||
"dev_status = %d, dev_handle =%d",
|
||||
__func__, p_dev->dev_status, p_dev->dev_handle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bta_hh_co_data
|
||||
*
|
||||
* Description This function is executed by BTA when HID host receive a
|
||||
* data report on interrupt channel.
|
||||
*
|
||||
* Parameters dev_handle - device handle
|
||||
* *p_rpt - pointer to the report data
|
||||
* len - length of report data
|
||||
* mode - Hid host Protocol Mode
|
||||
* sub_clas - Device Subclass
|
||||
* app_id - application id
|
||||
*
|
||||
* Returns void
|
||||
******************************************************************************/
|
||||
void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MODE mode, UINT8 sub_class, UINT8 ctry_code,
|
||||
BD_ADDR peer_addr, UINT8 app_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
tBTA_HH p_data;
|
||||
BT_HDR *p_buf = NULL;
|
||||
bt_status_t status;
|
||||
tBTA_HH_STATUS ret = BTA_HH_OK;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_HH;
|
||||
msg.act = BTA_HH_DATA_IND_EVT;
|
||||
|
||||
APPL_TRACE_DEBUG("%s: dev_handle = %d, subclass = 0x%02X, mode = %d, "
|
||||
"ctry_code = %d, app_id = %d",
|
||||
__func__, dev_handle, sub_class, mode, ctry_code, app_id);
|
||||
|
||||
do {
|
||||
if ((p_buf = osi_malloc(sizeof(BT_HDR) + len)) == NULL) {
|
||||
APPL_TRACE_ERROR("%s malloc failed!", __func__);
|
||||
ret = BTA_HH_ERR_NO_RES;
|
||||
break;
|
||||
}
|
||||
p_buf->offset = 0;
|
||||
p_buf->len = len;
|
||||
p_buf->event = 0;
|
||||
p_buf->layer_specific = dev_handle;
|
||||
memcpy(p_buf->data, p_rpt, len);
|
||||
} while (0);
|
||||
|
||||
p_data.int_data.status = ret;
|
||||
p_data.int_data.handle = dev_handle;
|
||||
p_data.int_data.p_data = p_buf;
|
||||
p_data.int_data.proto_mode = mode;
|
||||
status = btc_transfer_context(&msg, &p_data, sizeof(tBTA_HH), NULL);
|
||||
assert(status == BT_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
#endif /* HID_HOST_INCLUDED == TRUE */
|
831
components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c
Normal file
831
components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c
Normal file
@ -0,0 +1,831 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2009-2012 Broadcom Corporation
|
||||
* Copyright (C) 2019 Blake Felt
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/************************************************************************************
|
||||
*
|
||||
* Filename: btc_hd.c
|
||||
*
|
||||
* Description: HID Device Profile Bluetooth Interface
|
||||
*
|
||||
*
|
||||
***********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bta/bta_api.h"
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "bta/bta_hh_api.h"
|
||||
#include "bta/utl.h"
|
||||
#include "btc/btc_storage.h"
|
||||
#include "btc/btc_util.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_hd.h"
|
||||
|
||||
#include "osi/allocator.h"
|
||||
|
||||
#include "esp_hidd_api.h"
|
||||
|
||||
#if HID_DEV_INCLUDED == TRUE
|
||||
#include "bta_dm_int.h"
|
||||
|
||||
/* HD request events */
|
||||
typedef enum { BTC_HD_DUMMY_REQ_EVT = 0 } btc_hd_req_evt_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Static variables
|
||||
******************************************************************************/
|
||||
btc_hd_cb_t btc_hd_cb;
|
||||
|
||||
// static tBTA_HD_APP_INFO app_info;
|
||||
// static tBTA_HD_QOS_INFO in_qos;
|
||||
// static tBTA_HD_QOS_INFO out_qos;
|
||||
|
||||
/******************************************************************************
|
||||
* Constants & Macros
|
||||
*****************************************************************************/
|
||||
#define BTC_HD_APP_NAME_LEN 50
|
||||
#define BTC_HD_APP_DESCRIPTION_LEN 50
|
||||
#define BTC_HD_APP_PROVIDER_LEN 50
|
||||
#define BTC_HD_APP_DESCRIPTOR_LEN 2048
|
||||
#define COD_HID_KEYBOARD 0x0540
|
||||
#define COD_HID_POINTING 0x0580
|
||||
#define COD_HID_COMBO 0x05C0
|
||||
#define COD_HID_MAJOR 0x0500
|
||||
|
||||
#define is_hidd_init() (btc_hd_cb.status > BTC_HD_DISABLED)
|
||||
#define is_hidd_app_register() (btc_hd_cb.app_registered)
|
||||
|
||||
typedef void (bt_hid_copy_cb_t)(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
|
||||
static inline void btc_hd_cb_to_app(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param)
|
||||
{
|
||||
esp_hd_cb_t *btc_hd_cb = (esp_hd_cb_t *)btc_profile_cb_get(BTC_PID_HD);
|
||||
if (btc_hd_cb) {
|
||||
btc_hd_cb(event, param);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_app_info_param(void)
|
||||
{
|
||||
utl_freebuf((void **)&btc_hd_cb.app_info.descriptor.dsc_list);
|
||||
utl_freebuf((void **)&btc_hd_cb.app_info.p_provider);
|
||||
utl_freebuf((void **)&btc_hd_cb.app_info.p_description);
|
||||
utl_freebuf((void **)&btc_hd_cb.app_info.p_name);
|
||||
}
|
||||
|
||||
static void bte_hd_arg_deep_copy(btc_msg_t *msg, void *p_dst, void *p_src)
|
||||
{
|
||||
tBTA_HD *p_dst_data = (tBTA_HD *)p_dst;
|
||||
tBTA_HD *p_src_data = (tBTA_HD *)p_src;
|
||||
switch (msg->act)
|
||||
{
|
||||
case BTA_HD_SET_REPORT_EVT: {
|
||||
uint8_t *src_data = p_src_data->set_report.p_data;
|
||||
if (src_data) {
|
||||
p_dst_data->set_report.p_data = osi_malloc(p_src_data->set_report.len);
|
||||
if (p_dst_data->set_report.p_data == NULL) {
|
||||
BTC_TRACE_ERROR("%s malloc set_report data failed!", __func__);
|
||||
break;
|
||||
}
|
||||
memcpy(p_dst_data->set_report.p_data, src_data, p_src_data->set_report.len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTA_HD_INTR_DATA_EVT: {
|
||||
uint8_t *src_data = p_src_data->intr_data.p_data;
|
||||
if (src_data) {
|
||||
p_dst_data->intr_data.p_data = osi_malloc(p_src_data->intr_data.len);
|
||||
if (p_dst_data->intr_data.p_data == NULL) {
|
||||
BTC_TRACE_ERROR("%s malloc intr_data data failed!", __func__);
|
||||
break;
|
||||
}
|
||||
memcpy(p_dst_data->intr_data.p_data, src_data, p_src_data->intr_data.len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_remove_device
|
||||
*
|
||||
* Description Removes plugged device
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void btc_hd_remove_device(bt_bdaddr_t bd_addr)
|
||||
{
|
||||
BTA_HdRemoveDevice((uint8_t *)&bd_addr);
|
||||
// btc_storage_remove_hidd(&bd_addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function bte_hd_evt
|
||||
*
|
||||
* Description Switches context from BTE to BTC for all BT-HD events
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void bte_hd_evt(tBTA_HD_EVT event, tBTA_HD *p_data)
|
||||
{
|
||||
bt_status_t status;
|
||||
int param_len = 0;
|
||||
|
||||
BTC_TRACE_API("%s event=%d", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case BTA_HD_ENABLE_EVT:
|
||||
case BTA_HD_DISABLE_EVT:
|
||||
case BTA_HD_UNREGISTER_APP_EVT:
|
||||
param_len = sizeof(tBTA_HD_STATUS);
|
||||
break;
|
||||
case BTA_HD_REGISTER_APP_EVT:
|
||||
param_len = sizeof(tBTA_HD_REG_STATUS);
|
||||
break;
|
||||
case BTA_HD_OPEN_EVT:
|
||||
case BTA_HD_CLOSE_EVT:
|
||||
case BTA_HD_VC_UNPLUG_EVT:
|
||||
param_len = sizeof(tBTA_HD_CONN);
|
||||
break;
|
||||
case BTA_HD_GET_REPORT_EVT:
|
||||
param_len += sizeof(tBTA_HD_GET_REPORT);
|
||||
break;
|
||||
case BTA_HD_SET_REPORT_EVT:
|
||||
param_len = sizeof(tBTA_HD_SET_REPORT);
|
||||
break;
|
||||
case BTA_HD_SET_PROTOCOL_EVT:
|
||||
param_len += sizeof(p_data->set_protocol);
|
||||
break;
|
||||
case BTA_HD_INTR_DATA_EVT:
|
||||
param_len = sizeof(tBTA_HD_INTR_DATA);
|
||||
break;
|
||||
case BTA_HD_SEND_REPORT_EVT:
|
||||
param_len = sizeof(tBTA_HD_API_SEND_REPORT);
|
||||
break;
|
||||
case BTA_HD_REPORT_ERR_EVT:
|
||||
param_len = sizeof(tBTA_HD_API_REPORT_ERR);
|
||||
break;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_HD;
|
||||
msg.act = event;
|
||||
|
||||
status = btc_transfer_context(&msg, p_data, param_len, bte_hd_arg_deep_copy);
|
||||
if (status != BT_STATUS_SUCCESS) {
|
||||
BTC_TRACE_ERROR("context transfer failed");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_init
|
||||
*
|
||||
* Description Initializes BT-HD interface
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_init(void)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has been initiated, shall uninit first!", __func__);
|
||||
ret = ESP_HIDD_NEED_DEINIT;
|
||||
break;
|
||||
}
|
||||
memset(&btc_hd_cb, 0, sizeof(btc_hd_cb));
|
||||
/* enable HD */
|
||||
BTA_HdEnable(bte_hd_evt);
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.init.status = ret;
|
||||
btc_hd_cb_to_app(ESP_HIDD_INIT_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_deinit
|
||||
*
|
||||
* Description de-initializes the hd interface
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_unregister_app(void);
|
||||
static void btc_hd_deinit(void)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
btc_hd_cb.service_dereg_active = FALSE;
|
||||
btc_hd_cb.status = BTC_HD_DISABLING;
|
||||
// unresgister app will also relase the connection
|
||||
// and disable after receiving unregister event from lower layer
|
||||
if (is_hidd_app_register()) {
|
||||
btc_hd_unregister_app();
|
||||
} else {
|
||||
BTC_TRACE_WARNING("%s disabling hid device service now", __func__);
|
||||
BTA_HdDisable();
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.deinit.status = ret;
|
||||
btc_hd_cb_to_app(ESP_HIDD_DEINIT_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_register_app
|
||||
*
|
||||
* Description Registers HID Device application
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_param_t *p_in_qos,
|
||||
esp_hidd_qos_param_t *p_out_qos)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application already registered, shall deregister first!", __func__);
|
||||
ret = ESP_HIDD_NEED_DEREG;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((btc_hd_cb.app_info.p_name = (char *)osi_malloc(BTC_HD_APP_NAME_LEN)) == NULL ||
|
||||
(btc_hd_cb.app_info.p_description = (char *)osi_malloc(BTC_HD_APP_DESCRIPTION_LEN)) == NULL ||
|
||||
(btc_hd_cb.app_info.p_provider = (char *)osi_malloc(BTC_HD_APP_PROVIDER_LEN)) == NULL ||
|
||||
(btc_hd_cb.app_info.descriptor.dsc_list = (uint8_t *)osi_malloc(p_app_param->desc_list_len)) == NULL) {
|
||||
BTC_TRACE_ERROR(
|
||||
"%s malloc app_info failed! p_name:%p, p_description:%p, p_provider:%p, descriptor.dsc_list:%p",
|
||||
__func__, btc_hd_cb.app_info.p_name, btc_hd_cb.app_info.p_description, btc_hd_cb.app_info.p_provider,
|
||||
btc_hd_cb.app_info.descriptor.dsc_list);
|
||||
ret = ESP_HIDD_NO_RES;
|
||||
break;
|
||||
}
|
||||
memcpy(btc_hd_cb.app_info.p_name, p_app_param->name, BTC_HD_APP_NAME_LEN);
|
||||
memcpy(btc_hd_cb.app_info.p_description, p_app_param->description, BTC_HD_APP_DESCRIPTION_LEN);
|
||||
memcpy(btc_hd_cb.app_info.p_provider, p_app_param->provider, BTC_HD_APP_PROVIDER_LEN);
|
||||
memcpy(btc_hd_cb.app_info.descriptor.dsc_list, p_app_param->desc_list, p_app_param->desc_list_len);
|
||||
btc_hd_cb.app_info.subclass = p_app_param->subclass;
|
||||
btc_hd_cb.app_info.descriptor.dl_len = p_app_param->desc_list_len;
|
||||
|
||||
btc_hd_cb.in_qos.service_type = p_in_qos->service_type;
|
||||
btc_hd_cb.in_qos.token_rate = p_in_qos->token_rate;
|
||||
btc_hd_cb.in_qos.token_bucket_size = p_in_qos->token_bucket_size;
|
||||
btc_hd_cb.in_qos.peak_bandwidth = p_in_qos->peak_bandwidth;
|
||||
btc_hd_cb.in_qos.access_latency = p_in_qos->access_latency;
|
||||
btc_hd_cb.in_qos.delay_variation = p_in_qos->delay_variation;
|
||||
btc_hd_cb.out_qos.service_type = p_out_qos->service_type;
|
||||
btc_hd_cb.out_qos.token_rate = p_out_qos->token_rate;
|
||||
btc_hd_cb.out_qos.token_bucket_size = p_out_qos->token_bucket_size;
|
||||
btc_hd_cb.out_qos.peak_bandwidth = p_out_qos->peak_bandwidth;
|
||||
btc_hd_cb.out_qos.access_latency = p_out_qos->access_latency;
|
||||
btc_hd_cb.out_qos.delay_variation = p_out_qos->delay_variation;
|
||||
|
||||
BTA_HdRegisterApp(&btc_hd_cb.app_info, &btc_hd_cb.in_qos, &btc_hd_cb.out_qos);
|
||||
} while(0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.register_app.status = ret;
|
||||
param.register_app.in_use = false;
|
||||
memset(param.register_app.bd_addr, 0, BD_ADDR_LEN);
|
||||
btc_hd_cb_to_app(ESP_HIDD_REGISTER_APP_EVT, ¶m);
|
||||
}
|
||||
free_app_info_param();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_unregister_app
|
||||
*
|
||||
* Description Unregisters HID Device application
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_unregister_app(void)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (btc_hd_cb.service_dereg_active) {
|
||||
BTC_TRACE_ERROR("%s: BT-HD deregistering in progress", __func__);
|
||||
ret = ESP_HIDD_BUSY;
|
||||
break;
|
||||
}
|
||||
btc_hd_cb.service_dereg_active = TRUE;
|
||||
BTA_HdUnregisterApp();
|
||||
} while(0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.unregister_app.status = ret;
|
||||
btc_hd_cb_to_app(ESP_HIDD_UNREGISTER_APP_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_connect
|
||||
*
|
||||
* Description Connects to host
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_connect(BD_ADDR bd_addr)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
BTA_HdConnect(bd_addr);
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.open.status = ret;
|
||||
param.open.conn_status = ESP_HIDD_CONN_STATE_DISCONNECTED;
|
||||
memcpy(param.open.bd_addr, bd_addr, BD_ADDR_LEN);
|
||||
btc_hd_cb_to_app(ESP_HIDD_OPEN_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_disconnect
|
||||
*
|
||||
* Description Disconnects from host
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_disconnect(void)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
BTA_HdDisconnect();
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.close.status = ret;
|
||||
param.close.conn_status = ESP_HIDD_CONN_STATE_DISCONNECTED;
|
||||
btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_send_report
|
||||
*
|
||||
* Description Sends Reports to hid host
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data)
|
||||
{
|
||||
tBTA_HD_REPORT report;
|
||||
|
||||
BTC_TRACE_API("%s: type=%d id=%d len=%d", __func__, type, id, len);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
if (type == ESP_HIDD_REPORT_TYPE_INTRDATA) {
|
||||
report.type = ESP_HIDD_REPORT_TYPE_INPUT;
|
||||
report.use_intr = TRUE;
|
||||
} else {
|
||||
report.type = (type & 0x03);
|
||||
report.use_intr = FALSE;
|
||||
}
|
||||
|
||||
report.id = id;
|
||||
report.len = len;
|
||||
report.p_data = p_data;
|
||||
|
||||
BTA_HdSendReport(&report);
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.send_report.status = ret;
|
||||
param.send_report.reason = 0;
|
||||
param.send_report.report_type = report.type;
|
||||
param.send_report.report_id = report.id;
|
||||
btc_hd_cb_to_app(ESP_HIDD_SEND_REPORT_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_report_error
|
||||
*
|
||||
* Description Sends HANDSHAKE with error info for invalid SET_REPORT
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_report_error(uint8_t error)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
BTA_HdReportError(error);
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.report_err.status = ret;
|
||||
param.report_err.reason = 0;
|
||||
btc_hd_cb_to_app(ESP_HIDD_REPORT_ERR_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function btc_hd_virtual_cable_unplug
|
||||
*
|
||||
* Description Sends Virtual Cable Unplug to host
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void btc_hd_virtual_cable_unplug(void)
|
||||
{
|
||||
BTC_TRACE_API("%s", __func__);
|
||||
esp_hidd_status_t ret = ESP_HIDD_SUCCESS;
|
||||
do {
|
||||
if (!is_hidd_init()) {
|
||||
BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__);
|
||||
ret = ESP_HIDD_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_hidd_app_register()) {
|
||||
BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__);
|
||||
ret = ESP_HIDD_NEED_REG;
|
||||
break;
|
||||
}
|
||||
BTA_HdVirtualCableUnplug();
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_HIDD_SUCCESS) {
|
||||
esp_hidd_cb_param_t param;
|
||||
param.report_err.status = ret;
|
||||
param.report_err.reason = 0;
|
||||
btc_hd_cb_to_app(ESP_HIDD_VC_UNPLUG_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_hd_call_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
btc_hidd_args_t *arg = (btc_hidd_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_HD_SEND_REPORT_EVT:
|
||||
utl_freebuf((void **)&arg->send_report.data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_hd_call_handler(btc_msg_t *msg)
|
||||
{
|
||||
btc_hidd_args_t *arg = (btc_hidd_args_t *)(msg->arg);
|
||||
switch (msg->act) {
|
||||
case BTC_HD_INIT_EVT:
|
||||
btc_hd_init();
|
||||
break;
|
||||
case BTC_HD_DEINIT_EVT:
|
||||
btc_hd_deinit();
|
||||
break;
|
||||
case BTC_HD_REGISTER_APP_EVT:
|
||||
btc_hd_register_app(arg->register_app.app_param, arg->register_app.in_qos, arg->register_app.out_qos);
|
||||
break;
|
||||
case BTC_HD_UNREGISTER_APP_EVT:
|
||||
btc_hd_unregister_app();
|
||||
break;
|
||||
case BTC_HD_CONNECT_EVT:
|
||||
btc_hd_connect(arg->connect.bd_addr);
|
||||
break;
|
||||
case BTC_HD_DISCONNECT_EVT:
|
||||
btc_hd_disconnect();
|
||||
break;
|
||||
case BTC_HD_SEND_REPORT_EVT:
|
||||
btc_hd_send_report(arg->send_report.type, arg->send_report.id, arg->send_report.len, arg->send_report.data);
|
||||
break;
|
||||
case BTC_HD_REPORT_ERROR_EVT:
|
||||
btc_hd_report_error(arg->error);
|
||||
break;
|
||||
case BTC_HD_UNPLUG_EVT:
|
||||
btc_hd_virtual_cable_unplug();
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_WARNING("unknown hidd action %i", msg->act);
|
||||
break;
|
||||
}
|
||||
btc_hd_call_arg_deep_free(msg);
|
||||
}
|
||||
|
||||
static void btc_hd_cb_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
tBTA_HD *arg = (tBTA_HD *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTA_HD_SET_REPORT_EVT:
|
||||
utl_freebuf((void **)&arg->set_report.p_data);
|
||||
break;
|
||||
case BTA_HD_INTR_DATA_EVT:
|
||||
utl_freebuf((void **)&arg->intr_data.p_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_hd_cb_handler(btc_msg_t *msg)
|
||||
{
|
||||
uint16_t event = msg->act;
|
||||
tBTA_HD *p_data = (tBTA_HD *)msg->arg;
|
||||
esp_hidd_cb_param_t param = {0};
|
||||
BTC_TRACE_API("%s: event=%s", __func__, dump_hd_event(event));
|
||||
|
||||
switch (event) {
|
||||
case BTA_HD_ENABLE_EVT:
|
||||
BTC_TRACE_DEBUG("%s: status=%d", __func__, p_data->status);
|
||||
if (p_data->status == BTA_HD_OK) {
|
||||
btc_storage_load_hidd();
|
||||
btc_hd_cb.status = BTC_HD_ENABLED;
|
||||
} else {
|
||||
btc_hd_cb.status = BTC_HD_DISABLED;
|
||||
BTC_TRACE_WARNING("Failed to enable BT-HD, status=%d", p_data->status);
|
||||
}
|
||||
param.init.status = p_data->status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_INIT_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_DISABLE_EVT:
|
||||
BTC_TRACE_DEBUG("%s: status=%d", __func__, p_data->status);
|
||||
if (p_data->status == BTA_HD_OK){
|
||||
btc_hd_cb.status = BTC_HD_DISABLED;
|
||||
if (btc_hd_cb.service_dereg_active) {
|
||||
btc_hd_cb.service_dereg_active = FALSE;
|
||||
}
|
||||
free_app_info_param();
|
||||
memset(&btc_hd_cb, 0, sizeof(btc_hd_cb));
|
||||
} else {
|
||||
BTC_TRACE_WARNING("Failed to disable BT-HD, status=%d", p_data->status);
|
||||
}
|
||||
param.deinit.status = p_data->status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_DEINIT_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_REGISTER_APP_EVT:
|
||||
if (p_data->reg_status.status == BTA_HD_OK) {
|
||||
btc_hd_cb.app_registered = TRUE;
|
||||
}
|
||||
param.register_app.status = p_data->reg_status.status;
|
||||
param.register_app.in_use = p_data->reg_status.in_use;
|
||||
if (!p_data->reg_status.in_use) {
|
||||
memset(param.register_app.bd_addr, 0, BD_ADDR_LEN);
|
||||
} else {
|
||||
memcpy(param.register_app.bd_addr, p_data->reg_status.bda, BD_ADDR_LEN);
|
||||
}
|
||||
btc_hd_cb_to_app(ESP_HIDD_REGISTER_APP_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_UNREGISTER_APP_EVT:
|
||||
btc_hd_cb.app_registered = FALSE;
|
||||
param.unregister_app.status = p_data->status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_UNREGISTER_APP_EVT, ¶m);
|
||||
if (btc_hd_cb.status == BTC_HD_DISABLING) {
|
||||
BTC_TRACE_WARNING("disabling hid device service now");
|
||||
BTA_HdDisable();
|
||||
}
|
||||
break;
|
||||
case BTA_HD_OPEN_EVT: {
|
||||
bt_bdaddr_t *addr = (bt_bdaddr_t *)&p_data->conn.bda;
|
||||
BTC_TRACE_EVENT("BTA_HD_OPEN_EVT, address (%02x:%02x:%02x:%02x:%02x:%02x)", addr->address[0], addr->address[1],
|
||||
addr->address[2], addr->address[3], addr->address[4], addr->address[5]);
|
||||
if (p_data->conn.status == BTA_HD_OK && p_data->conn.conn_status == BTA_HD_CONN_STATE_CONNECTED) {
|
||||
// /* Check if the connection is from hid host and not hid device */
|
||||
// if (check_cod_hid(addr)) {
|
||||
// /* Incoming connection from hid device, reject it */
|
||||
// BTC_TRACE_WARNING("remote device is not hid host, disconnecting");
|
||||
// btc_hd_cb.forced_disc = TRUE;
|
||||
// BTA_HdDisconnect();
|
||||
// break;
|
||||
// }
|
||||
// btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda);
|
||||
}
|
||||
param.open.status = p_data->conn.status;
|
||||
param.open.conn_status = p_data->conn.conn_status;
|
||||
memcpy(param.open.bd_addr, p_data->conn.bda, BD_ADDR_LEN);
|
||||
btc_hd_cb_to_app(ESP_HIDD_OPEN_EVT, ¶m);
|
||||
break;
|
||||
}
|
||||
case BTA_HD_CLOSE_EVT:
|
||||
if (btc_hd_cb.forced_disc && p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) {
|
||||
bt_bdaddr_t *addr = (bt_bdaddr_t *)&p_data->conn.bda;
|
||||
BTC_TRACE_WARNING("remote device was forcefully disconnected");
|
||||
btc_hd_remove_device(*addr);
|
||||
btc_hd_cb.forced_disc = FALSE;
|
||||
break;
|
||||
}
|
||||
param.close.status = p_data->conn.status;
|
||||
param.close.conn_status = p_data->conn.conn_status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_GET_REPORT_EVT:
|
||||
param.get_report.report_type = p_data->get_report.report_type;
|
||||
param.get_report.report_id = p_data->get_report.report_id;
|
||||
param.get_report.buffer_size = p_data->get_report.buffer_size;
|
||||
btc_hd_cb_to_app(ESP_HIDD_GET_REPORT_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_SET_REPORT_EVT:
|
||||
param.set_report.report_type = p_data->set_report.report_type;
|
||||
param.set_report.report_id = p_data->set_report.report_id;
|
||||
param.set_report.len = p_data->set_report.len;
|
||||
param.set_report.data = p_data->set_report.p_data;
|
||||
btc_hd_cb_to_app(ESP_HIDD_SET_REPORT_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_SET_PROTOCOL_EVT:
|
||||
switch (p_data->set_protocol) {
|
||||
case HID_PAR_PROTOCOL_BOOT_MODE:
|
||||
param.set_protocol.protocol_mode = ESP_HIDD_BOOT_MODE;
|
||||
break;
|
||||
case HID_PAR_PROTOCOL_REPORT:
|
||||
param.set_protocol.protocol_mode = ESP_HIDD_REPORT_MODE;
|
||||
break;
|
||||
default:
|
||||
param.set_protocol.protocol_mode = ESP_HIDD_UNSUPPORTED_MODE;
|
||||
break;
|
||||
}
|
||||
btc_hd_cb_to_app(ESP_HIDD_SET_PROTOCOL_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_INTR_DATA_EVT:
|
||||
param.intr_data.report_id = p_data->intr_data.report_id;
|
||||
param.intr_data.len = p_data->intr_data.len;
|
||||
param.intr_data.data = p_data->intr_data.p_data;
|
||||
btc_hd_cb_to_app(ESP_HIDD_INTR_DATA_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_VC_UNPLUG_EVT: {
|
||||
bt_bdaddr_t *bd_addr = (bt_bdaddr_t *)&p_data->conn.bda;
|
||||
if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) {
|
||||
BTC_TRACE_DEBUG("%s: Removing bonding as only HID profile connected", __func__);
|
||||
BTA_DmRemoveDevice((uint8_t *)&p_data->conn.bda, BT_TRANSPORT_BR_EDR);
|
||||
} else {
|
||||
BTC_TRACE_DEBUG("%s: Only removing HID data as some other profiles connected", __func__);
|
||||
btc_hd_remove_device(*bd_addr);
|
||||
}
|
||||
param.close.status = p_data->conn.status;
|
||||
param.close.conn_status = p_data->conn.conn_status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m);
|
||||
param.vc_unplug.status = p_data->conn.status;
|
||||
param.vc_unplug.conn_status = p_data->conn.conn_status;
|
||||
btc_hd_cb_to_app(ESP_HIDD_VC_UNPLUG_EVT, ¶m);
|
||||
break;
|
||||
}
|
||||
case BTA_HD_SEND_REPORT_EVT:
|
||||
param.send_report.status = p_data->send_report.status;
|
||||
param.send_report.reason = p_data->send_report.reason;
|
||||
param.send_report.report_type = p_data->send_report.report_type;
|
||||
param.send_report.report_id = p_data->send_report.report_id;
|
||||
btc_hd_cb_to_app(ESP_HIDD_SEND_REPORT_EVT, ¶m);
|
||||
break;
|
||||
case BTA_HD_REPORT_ERR_EVT:
|
||||
param.report_err.status = p_data->report_err.status;
|
||||
param.report_err.reason = p_data->report_err.reason;
|
||||
btc_hd_cb_to_app(ESP_HIDD_REPORT_ERR_EVT, ¶m);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_WARNING("%s: unknown event (%d)", __func__, event);
|
||||
break;
|
||||
}
|
||||
btc_hd_cb_arg_deep_free(msg);
|
||||
}
|
||||
|
||||
void btc_hd_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
btc_hidd_args_t *dst = (btc_hidd_args_t *)p_dest;
|
||||
btc_hidd_args_t *src = (btc_hidd_args_t *)p_src;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_HD_SEND_REPORT_EVT:
|
||||
dst->send_report.data = (uint8_t *)osi_malloc(src->send_report.len);
|
||||
if (dst->send_report.data) {
|
||||
memcpy(dst->send_report.data, src->send_report.data, src->send_report.len);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HID_DEV_INCLUDED==TRUE
|
1569
components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c
Normal file
1569
components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c
Normal file
File diff suppressed because it is too large
Load Diff
103
components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h
Normal file
103
components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h
Normal file
@ -0,0 +1,103 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2009-2012 Broadcom Corporation
|
||||
* Copyright (C) 2019 Blake Felt
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTC_HD_H
|
||||
#define BTC_HD_H
|
||||
|
||||
#if BTC_HD_INCLUDED == TRUE
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bta/bta_hd_api.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "esp_hidd_api.h"
|
||||
|
||||
typedef enum {
|
||||
BTC_HD_INIT_EVT = 0,
|
||||
BTC_HD_DEINIT_EVT,
|
||||
BTC_HD_REGISTER_APP_EVT,
|
||||
BTC_HD_UNREGISTER_APP_EVT,
|
||||
BTC_HD_CONNECT_EVT,
|
||||
BTC_HD_DISCONNECT_EVT,
|
||||
BTC_HD_SEND_REPORT_EVT,
|
||||
BTC_HD_REPORT_ERROR_EVT,
|
||||
BTC_HD_UNPLUG_EVT,
|
||||
} BTC_HD_EVT;
|
||||
|
||||
typedef enum { BTC_HD_DISABLED = 0, BTC_HD_ENABLED, BTC_HD_DISABLING } BTC_HD_STATUS;
|
||||
|
||||
/* BTIF-HD control block */
|
||||
typedef struct {
|
||||
BTC_HD_STATUS status;
|
||||
bool app_registered;
|
||||
bool service_dereg_active;
|
||||
bool forced_disc;
|
||||
tBTA_HD_APP_INFO app_info;
|
||||
tBTA_HD_QOS_INFO in_qos;
|
||||
tBTA_HD_QOS_INFO out_qos;
|
||||
} btc_hd_cb_t;
|
||||
|
||||
/* btc_hidd_args_t */
|
||||
typedef union {
|
||||
// BTC_HD_CONNECT_EVT
|
||||
struct connect_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} connect;
|
||||
|
||||
// BTC_HD_REGISTER_APP_EVT
|
||||
struct register_app_arg {
|
||||
esp_hidd_app_param_t *app_param;
|
||||
esp_hidd_qos_param_t *in_qos;
|
||||
esp_hidd_qos_param_t *out_qos;
|
||||
} register_app;
|
||||
|
||||
// BTC_HD_SEND_REPORT_EVT
|
||||
struct send_report_arg {
|
||||
esp_hidd_report_type_t type;
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t *data;
|
||||
} send_report;
|
||||
|
||||
// BTC_HD_REPORT_ERROR_EVT
|
||||
uint8_t error;
|
||||
} btc_hidd_args_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Functions
|
||||
******************************************************************************/
|
||||
void btc_hd_call_handler(btc_msg_t *msg);
|
||||
|
||||
void btc_hd_cb_handler(btc_msg_t *msg);
|
||||
|
||||
// extern btc_hd_cb_t btc_hd_cb;
|
||||
// extern void btc_hd_remove_device(bt_bdaddr_t bd_addr);
|
||||
// extern void btc_hd_service_registration();
|
||||
|
||||
void btc_hd_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTC_HD_INCLUDED == TRUE */
|
||||
#endif /* BTC_HD_H */
|
187
components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h
Normal file
187
components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h
Normal file
@ -0,0 +1,187 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2009-2012 Broadcom Corporation
|
||||
* Copyright (C) 2019 Blake Felt
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTC_HH_H
|
||||
#define BTC_HH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bta/bta_hh_api.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "osi/alarm.h"
|
||||
#include "esp_hidh_api.h"
|
||||
|
||||
#define BTC_HH_MAX_HID 8
|
||||
#define BTC_HH_MAX_ADDED_DEV 32
|
||||
|
||||
#define BTC_HH_MAX_KEYSTATES 3
|
||||
#define BTC_HH_KEYSTATE_MASK_NUMLOCK 0x01
|
||||
#define BTC_HH_KEYSTATE_MASK_CAPSLOCK 0x02
|
||||
#define BTC_HH_KEYSTATE_MASK_SCROLLLOCK 0x04
|
||||
|
||||
#define BTC_HH_MAX_POLLING_ATTEMPTS 10
|
||||
#define BTC_HH_POLLING_SLEEP_DURATION_US 5000
|
||||
|
||||
/*******************************************************************************
|
||||
* Type definitions and return values
|
||||
******************************************************************************/
|
||||
typedef enum {
|
||||
BTC_HH_INIT_EVT = 0,
|
||||
BTC_HH_CONNECT_EVT,
|
||||
BTC_HH_DISCONNECT_EVT,
|
||||
BTC_HH_UNPLUG_EVT,
|
||||
BTC_HH_SET_INFO_EVT,
|
||||
BTC_HH_GET_PROTO_EVT,
|
||||
BTC_HH_SET_PROTO_EVT,
|
||||
BTC_HH_GET_IDLE_EVT,
|
||||
BTC_HH_SET_IDLE_EVT,
|
||||
BTC_HH_GET_REPORT_EVT,
|
||||
BTC_HH_SET_REPORT_EVT,
|
||||
BTC_HH_SEND_DATA_EVT,
|
||||
BTC_HH_DEINIT_EVT,
|
||||
} BTC_HH_EVT;
|
||||
|
||||
typedef enum {
|
||||
BTC_HH_DISABLED = 0,
|
||||
BTC_HH_ENABLED,
|
||||
BTC_HH_DISABLING,
|
||||
BTC_HH_DEV_UNKNOWN,
|
||||
BTC_HH_DEV_CONNECTING,
|
||||
BTC_HH_DEV_CONNECTED,
|
||||
BTC_HH_DEV_DISCONNECTED
|
||||
} BTC_HH_STATUS;
|
||||
|
||||
typedef struct {
|
||||
esp_hidh_connection_state_t dev_status;
|
||||
uint8_t dev_handle;
|
||||
BD_ADDR bd_addr;
|
||||
uint16_t attr_mask;
|
||||
uint8_t sub_class;
|
||||
uint8_t app_id;
|
||||
bool ready_for_data;
|
||||
osi_alarm_t *vup_timer;
|
||||
bool local_vup; // Indicated locally initiated VUP
|
||||
} btc_hh_device_t;
|
||||
|
||||
/* Control block to maintain properties of devices */
|
||||
typedef struct {
|
||||
uint8_t dev_handle;
|
||||
BD_ADDR bd_addr;
|
||||
uint16_t attr_mask;
|
||||
} btc_hh_added_device_t;
|
||||
|
||||
/**
|
||||
* BTC-HH control block to maintain added devices and currently
|
||||
* connected hid devices
|
||||
*/
|
||||
typedef struct {
|
||||
BTC_HH_STATUS status;
|
||||
btc_hh_device_t devices[BTC_HH_MAX_HID];
|
||||
uint32_t device_num;
|
||||
BTC_HH_EVT add_event;
|
||||
btc_hh_added_device_t added_devices[BTC_HH_MAX_ADDED_DEV];
|
||||
btc_hh_device_t *p_curr_dev;
|
||||
bool service_dereg_active;
|
||||
BD_ADDR pending_conn_address;
|
||||
} btc_hh_cb_t;
|
||||
|
||||
/* btc_spp_args_t */
|
||||
typedef union {
|
||||
// BTC_HH_CONNECT_EVT
|
||||
struct connect_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} connect;
|
||||
|
||||
// BTC_HH_DISCONNECT_EVT
|
||||
struct disconnect_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} disconnect;
|
||||
|
||||
// BTC_HH_UNPLUG_EVT
|
||||
struct unplug_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} unplug;
|
||||
|
||||
// BTC_HH_SET_INFO_EVT
|
||||
struct set_info_arg {
|
||||
BD_ADDR bd_addr;
|
||||
esp_hidh_hid_info_t *hid_info;
|
||||
} set_info;
|
||||
|
||||
// BTC_HH_GET_PROTO_EVT
|
||||
struct get_protocol_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} get_protocol;
|
||||
|
||||
// BTC_HH_SET_PROTO_EVT
|
||||
struct set_protocol_arg {
|
||||
BD_ADDR bd_addr;
|
||||
esp_hidh_protocol_mode_t protocol_mode;
|
||||
} set_protocol;
|
||||
|
||||
// BTC_HH_GET_IDLE_EVT
|
||||
struct get_idle_arg {
|
||||
BD_ADDR bd_addr;
|
||||
} get_idle;
|
||||
|
||||
// BTC_HH_SET_IDLE_EVT
|
||||
struct set_idle_arg {
|
||||
BD_ADDR bd_addr;
|
||||
uint16_t idle_time;
|
||||
} set_idle;
|
||||
|
||||
// BTC_HH_GET_REPORT_EVT
|
||||
struct get_report_arg {
|
||||
BD_ADDR bd_addr;
|
||||
esp_hidh_report_type_t report_type;
|
||||
uint8_t report_id;
|
||||
int buffer_size;
|
||||
} get_report;
|
||||
|
||||
// BTC_HH_SET_REPORT_EVT
|
||||
struct set_report_arg {
|
||||
BD_ADDR bd_addr;
|
||||
esp_hidh_report_type_t report_type;
|
||||
size_t len;
|
||||
uint8_t *report;
|
||||
} set_report;
|
||||
|
||||
// BTC_HH_SEND_DATA_EVT
|
||||
struct send_data_arg {
|
||||
BD_ADDR bd_addr;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
} send_data;
|
||||
} btc_hidh_args_t;
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
extern btc_hh_cb_t btc_hh_cb;
|
||||
/*******************************************************************************
|
||||
* Functions
|
||||
******************************************************************************/
|
||||
|
||||
void btc_hh_call_handler(btc_msg_t *msg);
|
||||
|
||||
void btc_hh_cb_handler(btc_msg_t *msg);
|
||||
|
||||
void btc_hh_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
|
||||
bool btc_hh_add_added_dev(BD_ADDR bd_addr, uint16_t attr_mask);
|
||||
|
||||
#endif /* BTC_HH_H */
|
@ -67,6 +67,13 @@
|
||||
#define UC_BT_HFP_CLIENT_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//HID
|
||||
#ifdef CONFIG_BT_HID_ENABLED
|
||||
#define UC_BT_HID_ENABLED CONFIG_BT_HID_ENABLED
|
||||
#else
|
||||
#define UC_BT_HID_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//HID HOST(BT)
|
||||
#ifdef CONFIG_BT_HID_HOST_ENABLED
|
||||
#define UC_BT_HID_HOST_ENABLED CONFIG_BT_HID_HOST_ENABLED
|
||||
@ -74,6 +81,13 @@
|
||||
#define UC_BT_HID_HOST_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//HID Device(BT)
|
||||
#ifdef CONFIG_BT_HID_DEVICE_ENABLED
|
||||
#define UC_BT_HID_DEVICE_ENABLED CONFIG_BT_HID_DEVICE_ENABLED
|
||||
#else
|
||||
#define UC_BT_HID_DEVICE_ENABLED FALSE
|
||||
#endif
|
||||
|
||||
//SSP
|
||||
#ifdef CONFIG_BT_SSP_ENABLED
|
||||
#define UC_BT_SSP_ENABLED CONFIG_BT_SSP_ENABLED
|
||||
@ -365,10 +379,18 @@
|
||||
#define UC_BT_LOG_MCA_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LOG_HIDH_TRACE_LEVEL
|
||||
#define UC_BT_LOG_HIDH_TRACE_LEVEL CONFIG_BT_LOG_HIDH_TRACE_LEVEL
|
||||
#ifdef CONFIG_BT_LOG_HID_TRACE_LEVEL
|
||||
#if UC_BT_HID_HOST_ENABLED
|
||||
#define UC_BT_LOG_HIDH_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL
|
||||
#elif UC_BT_HID_DEVICE_ENABLED
|
||||
#define UC_BT_LOG_HIDD_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL
|
||||
#endif
|
||||
#else
|
||||
#if UC_BT_HID_HOST_ENABLED
|
||||
#define UC_BT_LOG_HIDH_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#elif UC_BT_HID_DEVICE_ENABLED
|
||||
#define UC_BT_LOG_HIDD_TRACE_LEVEL UC_TRACE_LEVEL_WARNING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_LOG_APPL_TRACE_LEVEL
|
||||
|
@ -130,11 +130,22 @@
|
||||
#define BT_SSP_INCLUDED TRUE
|
||||
#endif /* UC_BT_SSP_ENABLED */
|
||||
|
||||
#if UC_BT_HID_ENABLED
|
||||
#define BT_HID_INCLUDED TRUE
|
||||
#endif /* UC_BT_HID_ENABLED */
|
||||
|
||||
#if UC_BT_HID_HOST_ENABLED
|
||||
#define HID_HOST_INCLUDED TRUE
|
||||
#define BTA_HH_INCLUDED TRUE
|
||||
#define BTC_HH_INCLUDED TRUE
|
||||
#endif /* UC_BT_HID_HOST_ENABLED */
|
||||
|
||||
#if UC_BT_HID_DEVICE_ENABLED
|
||||
#define HID_DEV_INCLUDED TRUE
|
||||
#define BTA_HD_INCLUDED TRUE
|
||||
#define BTC_HD_INCLUDED TRUE
|
||||
#endif /* UC_BT_HID_DEVICE_ENABLED */
|
||||
|
||||
#endif /* UC_BT_CLASSIC_ENABLED */
|
||||
|
||||
/* This is set to enable use of GAP L2CAP connections. */
|
||||
@ -321,6 +332,14 @@
|
||||
#define BTC_SPP_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HH_INCLUDED
|
||||
#define BTC_HH_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HD_INCLUDED
|
||||
#define BTC_HD_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef SBC_DEC_INCLUDED
|
||||
#define SBC_DEC_INCLUDED FALSE
|
||||
#endif
|
||||
@ -350,6 +369,10 @@
|
||||
#define BTA_PAN_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HD_INCLUDED
|
||||
#define BTA_HD_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_INCLUDED
|
||||
#define BTA_HH_INCLUDED FALSE
|
||||
#endif
|
||||
@ -1378,7 +1401,11 @@
|
||||
|
||||
/* The maximum number of attributes in each record. */
|
||||
#ifndef SDP_MAX_REC_ATTR
|
||||
#if defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)
|
||||
#define SDP_MAX_REC_ATTR 25
|
||||
#else
|
||||
#define SDP_MAX_REC_ATTR 8
|
||||
#endif /* defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE) */
|
||||
#endif
|
||||
|
||||
#ifndef SDP_MAX_PAD_LEN
|
||||
@ -1845,6 +1872,18 @@ Range: 2 octets
|
||||
** HID
|
||||
**
|
||||
******************************************************************************/
|
||||
#ifndef BT_HID_INCLUDED
|
||||
#define BT_HID_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/* HID Device Role Included */
|
||||
#ifndef HID_DEV_INCLUDED
|
||||
#define HID_DEV_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
#ifndef HID_DEV_SUBCLASS
|
||||
#define HID_DEV_SUBCLASS COD_MINOR_POINTING
|
||||
#endif
|
||||
|
||||
#ifndef HID_CONTROL_BUF_SIZE
|
||||
#define HID_CONTROL_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
|
||||
@ -1854,6 +1893,14 @@ Range: 2 octets
|
||||
#define HID_INTERRUPT_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef HID_DEV_MTU_SIZE
|
||||
#define HID_DEV_MTU_SIZE 64
|
||||
#endif
|
||||
|
||||
#ifndef HID_DEV_FLUSH_TO
|
||||
#define HID_DEV_FLUSH_TO 0xffff
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
** Definitions for Both HID-Host & Device
|
||||
*/
|
||||
|
@ -106,6 +106,7 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
|
||||
#define BTTRC_ID_STK_CE 51
|
||||
#define BTTRC_ID_STK_SNEP 52
|
||||
#define BTTRC_ID_STK_NDEF 53
|
||||
#define BTTRC_ID_STK_HIDD 54
|
||||
|
||||
/* LayerIDs for BTA */
|
||||
#define BTTRC_ID_BTA_ACC 55 /* Advanced Camera Client */
|
||||
@ -199,6 +200,7 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
|
||||
#define AVRC_INITIAL_TRACE_LEVEL UC_BT_LOG_AVRC_TRACE_LEVEL
|
||||
#define MCA_INITIAL_TRACE_LEVEL UC_BT_LOG_MCA_TRACE_LEVEL
|
||||
#define HIDH_INITIAL_TRACE_LEVEL UC_BT_LOG_HIDH_TRACE_LEVEL
|
||||
#define HIDD_INITIAL_TRACE_LEVEL UC_BT_LOG_HIDD_TRACE_LEVEL
|
||||
#define APPL_INITIAL_TRACE_LEVEL UC_BT_LOG_APPL_TRACE_LEVEL
|
||||
#define GATT_INITIAL_TRACE_LEVEL UC_BT_LOG_GATT_TRACE_LEVEL
|
||||
#define SMP_INITIAL_TRACE_LEVEL UC_BT_LOG_SMP_TRACE_LEVEL
|
||||
@ -258,6 +260,14 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l
|
||||
#define HIDH_TRACE_EVENT(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(HIDH,EVENT)) BT_PRINT_D("BT_HIDH", fmt, ## args);}
|
||||
#define HIDH_TRACE_DEBUG(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(HIDH,DEBUG)) BT_PRINT_D("BT_HIDH", fmt, ## args);}
|
||||
|
||||
/* define traces for HID Device */
|
||||
#define HIDD_TRACE_ERROR(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDD, ERROR)) BT_PRINT_E("BT_HIDD", fmt, ## args);}
|
||||
#define HIDD_TRACE_WARNING(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDD, WARNING)) BT_PRINT_W("BT_HIDD", fmt, ## args);}
|
||||
#define HIDD_TRACE_API(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(HIDD,API)) BT_PRINT_I("BT_HIDD", fmt, ## args);}
|
||||
#define HIDD_TRACE_EVENT(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(HIDD,EVENT)) BT_PRINT_D("BT_HIDD", fmt, ## args);}
|
||||
#define HIDD_TRACE_DEBUG(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(HIDD,DEBUG)) BT_PRINT_D("BT_HIDD", fmt, ## args);}
|
||||
#define HIDD_TRACE_VERBOSE(fmt, args...) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(HIDD,VERBOSE)) BT_PRINT_D("BT_HIDD", fmt, ## args);}
|
||||
|
||||
/* define traces for BNEP */
|
||||
|
||||
#define BNEP_TRACE_ERROR(fmt, args...) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BNEP, ERROR)) BT_PRINT_E("BT_BNEP", fmt, ## args);}
|
||||
@ -418,6 +428,14 @@ extern UINT8 btif_trace_level;
|
||||
#define HIDH_TRACE_EVENT(fmt, args...)
|
||||
#define HIDH_TRACE_DEBUG(fmt, args...)
|
||||
|
||||
/* define traces for HID Device */
|
||||
#define HIDD_TRACE_ERROR(fmt, args...)
|
||||
#define HIDD_TRACE_WARNING(fmt, args...)
|
||||
#define HIDD_TRACE_API(fmt, args...)
|
||||
#define HIDD_TRACE_EVENT(fmt, args...)
|
||||
#define HIDD_TRACE_DEBUG(fmt, args...)
|
||||
#define HIDD_TRACE_VERBOSE(fmt, args...)
|
||||
|
||||
/* define traces for BNEP */
|
||||
|
||||
#define BNEP_TRACE_ERROR(fmt, args...)
|
||||
|
@ -52,6 +52,14 @@
|
||||
#include "pan_api.h"
|
||||
#endif
|
||||
|
||||
#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
|
||||
#include "stack/hidh_api.h"
|
||||
#endif
|
||||
|
||||
#if (defined(HID_DEV_INCLUDED) && HID_DEV_INCLUDED == TRUE)
|
||||
#include "stack/hidd_api.h"
|
||||
#endif
|
||||
|
||||
#if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)
|
||||
#include "stack/avrc_api.h"
|
||||
#endif
|
||||
@ -118,6 +126,10 @@
|
||||
#include "bta_hh_int.h"
|
||||
#endif
|
||||
|
||||
#if BTA_HD_INCLUDED==TRUE
|
||||
#include "bta_hd_int.h"
|
||||
#endif
|
||||
|
||||
#if BTA_JV_INCLUDED==TRUE
|
||||
#include "bta_jv_int.h"
|
||||
#endif
|
||||
@ -175,6 +187,12 @@ void BTE_DeinitStack(void)
|
||||
bta_gattc_cb_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
#if BTA_HD_INCLUDED==TRUE
|
||||
if (bta_hd_cb_ptr){
|
||||
osi_free(bta_hd_cb_ptr);
|
||||
bta_hd_cb_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
#if BTA_HH_INCLUDED==TRUE
|
||||
if (bta_hh_cb_ptr){
|
||||
osi_free(bta_hh_cb_ptr);
|
||||
@ -249,6 +267,14 @@ void BTE_DeinitStack(void)
|
||||
}
|
||||
#endif // BTA_INCLUDED == TRUE
|
||||
|
||||
#if (defined(HID_DEV_INCLUDED) && HID_DEV_INCLUDED == TRUE)
|
||||
HID_DevDeinit();
|
||||
#endif
|
||||
|
||||
#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
|
||||
HID_HostDeinit();
|
||||
#endif
|
||||
|
||||
#if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE)
|
||||
GAP_Deinit();
|
||||
#endif
|
||||
@ -347,7 +373,15 @@ bt_status_t BTE_InitStack(void)
|
||||
#endif
|
||||
|
||||
#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
|
||||
HID_HostInit();
|
||||
if (HID_HostInit() != HID_SUCCESS) {
|
||||
goto error_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(HID_DEV_INCLUDED) && HID_DEV_INCLUDED == TRUE)
|
||||
if (HID_DevInit() != HID_SUCCESS) {
|
||||
goto error_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(MCA_INCLUDED) && MCA_INCLUDED == TRUE)
|
||||
@ -434,6 +468,12 @@ bt_status_t BTE_InitStack(void)
|
||||
}
|
||||
memset((void *)bta_hh_cb_ptr, 0, sizeof(tBTA_HH_CB));
|
||||
#endif
|
||||
#if BTA_HD_INCLUDED==TRUE
|
||||
if ((bta_hd_cb_ptr = (tBTA_HD_CB *)osi_malloc(sizeof(tBTA_HD_CB))) == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
memset((void *)bta_hd_cb_ptr, 0, sizeof(tBTA_HD_CB));
|
||||
#endif
|
||||
#if BTA_HL_INCLUDED==TRUE
|
||||
memset((void *)bta_hl_cb_ptr, 0, sizeof(tBTA_HL_CB));
|
||||
#endif
|
||||
|
@ -394,9 +394,7 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration);
|
||||
void btm_ble_stop_scan(void);
|
||||
void btm_clear_all_pending_le_entry(void);
|
||||
|
||||
BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int,
|
||||
UINT32 scan_win, UINT8 addr_type_own,
|
||||
UINT8 scan_filter_policy);
|
||||
BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int, UINT32 scan_win, UINT8 addr_type_own, UINT8 scan_filter_policy);
|
||||
void btm_ble_stop_inquiry(void);
|
||||
void btm_ble_init (void);
|
||||
void btm_ble_free (void);
|
||||
@ -407,8 +405,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced);
|
||||
void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len);
|
||||
tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
|
||||
void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st);
|
||||
UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
|
||||
tBTM_BLE_ADV_DATA *p_data);
|
||||
UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data);
|
||||
tBTM_STATUS btm_ble_start_adv(void);
|
||||
tBTM_STATUS btm_ble_stop_adv(void);
|
||||
tBTM_STATUS btm_ble_start_scan(void);
|
||||
|
@ -961,12 +961,10 @@ extern tBTM_CallbackFunc conn_param_update_cb;
|
||||
|
||||
typedef UINT8 tBTM_SEC_ACTION;
|
||||
|
||||
/*
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if BTM_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTM_CB btm_cb;
|
||||
|
@ -54,7 +54,7 @@
|
||||
#endif
|
||||
|
||||
#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE )
|
||||
#include "hidh_int.h"
|
||||
#include "hid_int.h"
|
||||
#endif
|
||||
|
||||
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
|
||||
|
586
components/bt/host/bluedroid/stack/hid/hidd_api.c
Normal file
586
components/bt/host/bluedroid/stack/hid/hidd_api.c
Normal file
@ -0,0 +1,586 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID Device API entry points
|
||||
*
|
||||
******************************************************************************/
|
||||
//#include <errno.h>
|
||||
//#include <hardware/bluetooth.h>
|
||||
//#include <hardware/bt_hd.h>
|
||||
#include "stack/hidd_api.h"
|
||||
#include "esp_hidd_api.h"
|
||||
#include "hid_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "stack/btu.h"
|
||||
#include "stack/hiddefs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (HID_DEV_INCLUDED == TRUE)
|
||||
|
||||
#if HID_DYNAMIC_MEMORY == FALSE
|
||||
tHID_DEV_CTB hd_cb;
|
||||
#else
|
||||
tHID_DEV_CTB *hidd_cb_ptr = NULL;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevInit
|
||||
*
|
||||
* Description Initializes control block
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevInit(void)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidd_cb_ptr) {
|
||||
hidd_cb_ptr = (tHID_DEV_CTB *)osi_malloc(sizeof(tHID_DEV_CTB));
|
||||
if (!hidd_cb_ptr) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
memset(&hd_cb, 0, sizeof(tHID_DEV_CTB));
|
||||
#if defined(HIDD_INITIAL_TRACE_LEVEL)
|
||||
hd_cb.trace_level = HIDD_INITIAL_TRACE_LEVEL;
|
||||
#else
|
||||
hd_cb.trace_level = BT_TRACE_LEVEL_NONE;
|
||||
#endif
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevDeinit
|
||||
*
|
||||
* Description Deinitializes control block
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void HID_DevDeinit(void)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (hidd_cb_ptr) {
|
||||
osi_free(hidd_cb_ptr);
|
||||
hidd_cb_ptr = NULL;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetTraceLevel
|
||||
*
|
||||
* Description This function sets the trace level for HID Dev. If called
|
||||
* with
|
||||
* a value of 0xFF, it simply reads the current trace level.
|
||||
*
|
||||
* Returns the new (current) trace level
|
||||
*
|
||||
******************************************************************************/
|
||||
uint8_t HID_DevSetTraceLevel(uint8_t new_level)
|
||||
{
|
||||
if (new_level != 0xFF) {
|
||||
hd_cb.trace_level = new_level;
|
||||
}
|
||||
|
||||
return (hd_cb.trace_level);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevRegister
|
||||
*
|
||||
* Description Registers HID device with lower layers
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK *host_cback)
|
||||
{
|
||||
tHID_STATUS st;
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
if (hd_cb.reg_flag) {
|
||||
return HID_ERR_ALREADY_REGISTERED;
|
||||
}
|
||||
|
||||
if (host_cback == NULL) {
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
/* Register with L2CAP */
|
||||
if ((st = hidd_conn_reg()) != HID_SUCCESS) {
|
||||
return st;
|
||||
}
|
||||
|
||||
hd_cb.callback = host_cback;
|
||||
hd_cb.reg_flag = TRUE;
|
||||
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevDeregister
|
||||
*
|
||||
* Description Deregisters HID device with lower layers
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevDeregister(void)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
if (!hd_cb.reg_flag)
|
||||
return (HID_ERR_NOT_REGISTERED);
|
||||
hidd_conn_dereg();
|
||||
hd_cb.reg_flag = FALSE;
|
||||
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
if (!BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HIDD_SEC_CTRL, sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID,
|
||||
HIDD_SEC_CHN)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 1 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
if (!BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_HIDD_SEC_CTRL, sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID,
|
||||
HIDD_SEC_CHN)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 2 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
if (!BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HIDD_NOSEC_CTRL, BTM_SEC_NONE, HID_PSM_CONTROL,
|
||||
BTM_SEC_PROTO_HID, HIDD_NOSEC_CHN)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 3 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
if (!BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_HIDD_NOSEC_CTRL, BTM_SEC_NONE, HID_PSM_CONTROL,
|
||||
BTM_SEC_PROTO_HID, HIDD_NOSEC_CHN)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 4 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
if (!BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_HIDD_INTR, BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID,
|
||||
0)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 5 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
if (!BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HIDD_INTR, BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID,
|
||||
0)) {
|
||||
HIDD_TRACE_ERROR("Security Registration 6 failed");
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevAddRecord
|
||||
*
|
||||
* Description Creates SDP record for HID device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevAddRecord(uint32_t handle, char *p_name, char *p_description, char *p_provider, uint16_t subclass,
|
||||
uint16_t desc_len, uint8_t *p_desc_data)
|
||||
{
|
||||
bool result = TRUE;
|
||||
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
// Service Class ID List
|
||||
if (result) {
|
||||
uint16_t uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
|
||||
result &= SDP_AddServiceClassIdList(handle, 1, &uuid);
|
||||
}
|
||||
// Protocol Descriptor List
|
||||
if (result) {
|
||||
tSDP_PROTOCOL_ELEM proto_list[2];
|
||||
proto_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
|
||||
proto_list[0].num_params = 1;
|
||||
proto_list[0].params[0] = BT_PSM_HIDC;
|
||||
proto_list[1].protocol_uuid = UUID_PROTOCOL_HIDP;
|
||||
proto_list[1].num_params = 0;
|
||||
result &= SDP_AddProtocolList(handle, 2, proto_list);
|
||||
}
|
||||
// Language Base Attribute ID List
|
||||
if (result) {
|
||||
result &=
|
||||
SDP_AddLanguageBaseAttrIDList(handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID);
|
||||
}
|
||||
// Additional Protocol Descriptor List
|
||||
if (result) {
|
||||
tSDP_PROTO_LIST_ELEM add_proto_list;
|
||||
add_proto_list.num_elems = 2;
|
||||
add_proto_list.list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
|
||||
add_proto_list.list_elem[0].num_params = 1;
|
||||
add_proto_list.list_elem[0].params[0] = BT_PSM_HIDI;
|
||||
add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_HIDP;
|
||||
add_proto_list.list_elem[1].num_params = 0;
|
||||
result &= SDP_AddAdditionProtoLists(handle, 1, &add_proto_list);
|
||||
}
|
||||
// Service Name (O)
|
||||
// Service Description (O)
|
||||
// Provider Name (O)
|
||||
if (result) {
|
||||
const char *srv_name = p_name;
|
||||
const char *srv_desc = p_description;
|
||||
const char *provider_name = p_provider;
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, strlen(srv_name) + 1,
|
||||
(uint8_t *)srv_name);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, strlen(srv_desc) + 1,
|
||||
(uint8_t *)srv_desc);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE, strlen(provider_name) + 1,
|
||||
(uint8_t *)provider_name);
|
||||
}
|
||||
// Bluetooth Profile Descriptor List
|
||||
if (result) {
|
||||
const uint16_t profile_uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
|
||||
const uint16_t version = 0x0100;
|
||||
result &= SDP_AddProfileDescriptorList(handle, profile_uuid, version);
|
||||
}
|
||||
// HID Parser Version
|
||||
if (result) {
|
||||
uint8_t *p;
|
||||
const uint16_t rel_num = 0x0100;
|
||||
const uint16_t parser_version = 0x0111;
|
||||
const uint16_t prof_ver = 0x0100;
|
||||
const uint8_t dev_subclass = subclass;
|
||||
const uint8_t country_code = 0x21;
|
||||
const uint8_t bool_false = 0x00;
|
||||
const uint8_t bool_true = 0x01;
|
||||
uint16_t temp;
|
||||
p = (uint8_t *)&temp;
|
||||
UINT16_TO_BE_STREAM(p, rel_num);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DEVICE_RELNUM, UINT_DESC_TYPE, 2, (uint8_t *)&temp);
|
||||
p = (uint8_t *)&temp;
|
||||
UINT16_TO_BE_STREAM(p, parser_version);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_PARSER_VERSION, UINT_DESC_TYPE, 2, (uint8_t *)&temp);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DEVICE_SUBCLASS, UINT_DESC_TYPE, 1, (uint8_t *)&dev_subclass);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_COUNTRY_CODE, UINT_DESC_TYPE, 1, (uint8_t *)&country_code);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_VIRTUAL_CABLE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_RECONNECT_INITIATE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
{
|
||||
static uint8_t cdt = 0x22;
|
||||
uint8_t *p_buf;
|
||||
uint8_t seq_len = 4 + desc_len;
|
||||
p_buf = (uint8_t *)osi_malloc(2048);
|
||||
if (p_buf == NULL) {
|
||||
HIDD_TRACE_ERROR("%s: Buffer allocation failure for size = 2048 ", __func__);
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
}
|
||||
p = p_buf;
|
||||
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, seq_len);
|
||||
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, cdt);
|
||||
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, desc_len);
|
||||
ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE, p - p_buf, p_buf);
|
||||
osi_free(p_buf);
|
||||
}
|
||||
{
|
||||
uint8_t lang_buf[8];
|
||||
p = lang_buf;
|
||||
uint8_t seq_len = 6;
|
||||
uint16_t lang_english = 0x0409;
|
||||
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
UINT8_TO_BE_STREAM(p, seq_len);
|
||||
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
|
||||
UINT16_TO_BE_STREAM(p, lang_english);
|
||||
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
|
||||
UINT16_TO_BE_STREAM(p, LANGUAGE_BASE_ID);
|
||||
result &=
|
||||
SDP_AddAttribute(handle, ATTR_ID_HID_LANGUAGE_ID_BASE, DATA_ELE_SEQ_DESC_TYPE, p - lang_buf, lang_buf);
|
||||
}
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_BATTERY_POWER, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_REMOTE_WAKE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_false);
|
||||
result &=
|
||||
SDP_AddAttribute(handle, ATTR_ID_HID_NORMALLY_CONNECTABLE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_BOOT_DEVICE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
|
||||
p = (uint8_t *)&temp;
|
||||
UINT16_TO_BE_STREAM(p, prof_ver);
|
||||
result &= SDP_AddAttribute(handle, ATTR_ID_HID_PROFILE_VERSION, UINT_DESC_TYPE, 2, (uint8_t *)&temp);
|
||||
}
|
||||
if (result) {
|
||||
uint16_t browse_group = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
|
||||
result &= SDP_AddUuidSequence(handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_group);
|
||||
}
|
||||
if (!result) {
|
||||
HIDD_TRACE_ERROR("%s: failed to complete SDP record", __func__);
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
}
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSendReport
|
||||
*
|
||||
* Description Sends report
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id, uint16_t len, uint8_t *p_data)
|
||||
{
|
||||
HIDD_TRACE_VERBOSE("%s: channel=%d type=%d id=%d len=%d", __func__, channel, type, id, len);
|
||||
|
||||
if (channel == HID_CHANNEL_CTRL) {
|
||||
return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, type, id, len, p_data);
|
||||
}
|
||||
|
||||
if (channel == HID_CHANNEL_INTR && type == HID_PAR_REP_TYPE_INPUT) {
|
||||
// on INTR we can only send INPUT
|
||||
return hidd_conn_send_data(HID_CHANNEL_INTR, HID_TRANS_DATA, HID_PAR_REP_TYPE_INPUT, id, len, p_data);
|
||||
}
|
||||
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevVirtualCableUnplug
|
||||
*
|
||||
* Description Sends Virtual Cable Unplug
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevVirtualCableUnplug(void)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_CONTROL, HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG, 0, 0, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevPlugDevice
|
||||
*
|
||||
* Description Establishes virtual cable to given host
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevPlugDevice(BD_ADDR addr)
|
||||
{
|
||||
hd_cb.device.in_use = TRUE;
|
||||
memcpy(hd_cb.device.addr, addr, sizeof(BD_ADDR));
|
||||
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevUnplugDevice
|
||||
*
|
||||
* Description Unplugs virtual cable from given host
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr)
|
||||
{
|
||||
if (!memcmp(hd_cb.device.addr, addr, sizeof(BD_ADDR))) {
|
||||
hd_cb.device.in_use = FALSE;
|
||||
hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
|
||||
hd_cb.device.conn.ctrl_cid = 0;
|
||||
hd_cb.device.conn.intr_cid = 0;
|
||||
}
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevConnect
|
||||
*
|
||||
* Description Connects to device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevConnect(void)
|
||||
{
|
||||
if (!hd_cb.reg_flag) {
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
}
|
||||
if (!hd_cb.device.in_use) {
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (hd_cb.device.state != HIDD_DEV_NO_CONN) {
|
||||
return HID_ERR_ALREADY_CONN;
|
||||
}
|
||||
return hidd_conn_initiate();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevDisconnect
|
||||
*
|
||||
* Description Disconnects from device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevDisconnect(void)
|
||||
{
|
||||
if (!hd_cb.reg_flag) {
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
}
|
||||
if (!hd_cb.device.in_use) {
|
||||
return HID_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (hd_cb.device.state == HIDD_DEV_NO_CONN) {
|
||||
return HID_ERR_NO_CONNECTION;
|
||||
}
|
||||
return hidd_conn_disconnect();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetIncomingPolicy
|
||||
*
|
||||
* Description Sets policy for incoming connections (allowed/disallowed)
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevSetIncomingPolicy(bool allow)
|
||||
{
|
||||
hd_cb.allow_incoming = allow;
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevReportError
|
||||
*
|
||||
* Description Reports error for Set Report via HANDSHAKE
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevReportError(uint8_t error)
|
||||
{
|
||||
uint8_t handshake_param;
|
||||
|
||||
HIDD_TRACE_API("%s: error = %d", __func__, error);
|
||||
|
||||
switch (error) {
|
||||
case HID_PAR_HANDSHAKE_RSP_SUCCESS:
|
||||
case HID_PAR_HANDSHAKE_RSP_NOT_READY:
|
||||
case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID:
|
||||
case HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ:
|
||||
case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM:
|
||||
case HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN:
|
||||
case HID_PAR_HANDSHAKE_RSP_ERR_FATAL:
|
||||
handshake_param = error;
|
||||
break;
|
||||
default:
|
||||
handshake_param = HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, handshake_param, 0, 0, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevGetDevice
|
||||
*
|
||||
* Description Returns the BD Address of virtually cabled device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevGetDevice(BD_ADDR *addr)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
|
||||
if (hd_cb.device.in_use) {
|
||||
memcpy(addr, hd_cb.device.addr, sizeof(BD_ADDR));
|
||||
} else {
|
||||
return HID_ERR_NOT_REGISTERED;
|
||||
}
|
||||
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetIncomingQos
|
||||
*
|
||||
* Description Sets Incoming QoS values for Interrupt L2CAP Channel
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
hd_cb.use_in_qos = TRUE;
|
||||
hd_cb.in_qos.service_type = service_type;
|
||||
hd_cb.in_qos.token_rate = token_rate;
|
||||
hd_cb.in_qos.token_bucket_size = token_bucket_size;
|
||||
hd_cb.in_qos.peak_bandwidth = peak_bandwidth;
|
||||
hd_cb.in_qos.latency = latency;
|
||||
hd_cb.in_qos.delay_variation = delay_variation;
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetOutgoingQos
|
||||
*
|
||||
* Description Sets Outgoing QoS values for Interrupt L2CAP Channel
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS HID_DevSetOutgoingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
hd_cb.l2cap_intr_cfg.qos_present = TRUE;
|
||||
hd_cb.l2cap_intr_cfg.qos.service_type = service_type;
|
||||
hd_cb.l2cap_intr_cfg.qos.token_rate = token_rate;
|
||||
hd_cb.l2cap_intr_cfg.qos.token_bucket_size = token_bucket_size;
|
||||
hd_cb.l2cap_intr_cfg.qos.peak_bandwidth = peak_bandwidth;
|
||||
hd_cb.l2cap_intr_cfg.qos.latency = latency;
|
||||
hd_cb.l2cap_intr_cfg.qos.delay_variation = delay_variation;
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
#endif
|
780
components/bt/host/bluedroid/stack/hid/hidd_conn.c
Normal file
780
components/bt/host/bluedroid/stack/hid/hidd_conn.c
Normal file
@ -0,0 +1,780 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* this file contains the connection interface functions
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "btm_int.h"
|
||||
#include "hid_conn.h"
|
||||
#include "hid_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/osi.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "stack/btu.h"
|
||||
#include "stack/hidd_api.h"
|
||||
#include "stack/hiddefs.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#include "stack/l2cdefs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (HID_DEV_INCLUDED == TRUE)
|
||||
|
||||
static void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm, uint8_t id);
|
||||
static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result);
|
||||
static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg);
|
||||
static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg);
|
||||
static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed);
|
||||
static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result);
|
||||
static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR *p_msg);
|
||||
static void hidd_l2cif_cong_ind(uint16_t cid, bool congested);
|
||||
|
||||
static const tL2CAP_APPL_INFO dev_reg_info = {hidd_l2cif_connect_ind,
|
||||
hidd_l2cif_connect_cfm,
|
||||
NULL,
|
||||
hidd_l2cif_config_ind,
|
||||
hidd_l2cif_config_cfm,
|
||||
hidd_l2cif_disconnect_ind,
|
||||
hidd_l2cif_disconnect_cfm,
|
||||
NULL,
|
||||
hidd_l2cif_data_ind,
|
||||
hidd_l2cif_cong_ind,
|
||||
NULL};
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_check_config_done
|
||||
*
|
||||
* Description Checks if connection is configured and callback can be fired
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_check_config_done(void)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED) &&
|
||||
(p_hcon->conn_state == HID_CONN_STATE_CONFIG)) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_CONNECTED;
|
||||
hd_cb.device.state = HIDD_DEV_CONNECTED;
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_OPEN, 0, NULL);
|
||||
// send outstanding data on intr
|
||||
if (hd_cb.pending_data) {
|
||||
L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidh_sec_check_complete_term
|
||||
*
|
||||
* Description HID security check complete callback function.
|
||||
*
|
||||
* Returns Send L2CA_ConnectRsp OK if secutiry check succeed; otherwise
|
||||
* send security block L2C connection response.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr, UNUSED_ATTR tBT_TRANSPORT transport, void *p_ref_data,
|
||||
uint8_t res)
|
||||
{
|
||||
tHID_DEV_DEV_CTB *p_dev = (tHID_DEV_DEV_CTB *)p_ref_data;
|
||||
if (res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) {
|
||||
p_dev->conn.disc_reason = HID_SUCCESS;
|
||||
p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR;
|
||||
L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
|
||||
L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg);
|
||||
} else if (res != BTM_SUCCESS) {
|
||||
HIDD_TRACE_WARNING("%s: connection rejected by security", __func__);
|
||||
p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;
|
||||
p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
|
||||
L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_SECURITY_BLOCK,
|
||||
L2CAP_CONN_OK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_sec_check_complete_orig
|
||||
*
|
||||
* Description HID security check complete callback function (device
|
||||
*originated)
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void hidd_sec_check_complete_orig(UNUSED_ATTR BD_ADDR bd_addr, UNUSED_ATTR tBT_TRANSPORT transport, void *p_ref_data,
|
||||
uint8_t res)
|
||||
{
|
||||
tHID_DEV_DEV_CTB *p_dev = (tHID_DEV_DEV_CTB *)p_ref_data;
|
||||
if (p_dev->conn.conn_state != HID_CONN_STATE_SECURITY) {
|
||||
HIDD_TRACE_WARNING("%s: invalid state (%02x)", __func__, p_dev->conn.conn_state);
|
||||
return;
|
||||
}
|
||||
if (res == BTM_SUCCESS) {
|
||||
HIDD_TRACE_EVENT("%s: security ok", __func__);
|
||||
p_dev->conn.disc_reason = HID_SUCCESS;
|
||||
p_dev->conn.conn_state = HID_CONN_STATE_CONFIG;
|
||||
L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hd_cb.l2cap_cfg);
|
||||
} else {
|
||||
HIDD_TRACE_WARNING("%s: security check failed (%02x)", __func__, res);
|
||||
p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;
|
||||
hidd_conn_disconnect();
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_connect_ind
|
||||
*
|
||||
* Description Handles incoming L2CAP connection (we act as server)
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm, uint8_t id)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
tHID_DEV_DEV_CTB *p_dev;
|
||||
bool accept = TRUE; // accept by default
|
||||
HIDD_TRACE_EVENT("%s: psm=%04x cid=%04x id=%02x", __func__, psm, cid, id);
|
||||
p_dev = &hd_cb.device;
|
||||
if (!hd_cb.allow_incoming) {
|
||||
HIDD_TRACE_WARNING("%s: incoming connections not allowed, rejecting", __func__);
|
||||
L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
|
||||
return;
|
||||
}
|
||||
if (p_dev->in_use && memcmp(bd_addr, p_dev->addr, sizeof(BD_ADDR))) {
|
||||
HIDD_TRACE_WARNING("%s: incoming connections from different device, rejecting", __func__);
|
||||
L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
|
||||
return;
|
||||
} else if (!p_dev->in_use) {
|
||||
p_dev->in_use = TRUE;
|
||||
memcpy(p_dev->addr, bd_addr, sizeof(BD_ADDR));
|
||||
p_dev->state = HIDD_DEV_NO_CONN;
|
||||
}
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
switch (psm) {
|
||||
case HID_PSM_INTERRUPT:
|
||||
if (p_hcon->ctrl_cid == 0) {
|
||||
accept = FALSE;
|
||||
HIDD_TRACE_WARNING("%s: incoming INTR without CTRL, rejecting", __func__);
|
||||
}
|
||||
if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) {
|
||||
accept = FALSE;
|
||||
HIDD_TRACE_WARNING("%s: incoming INTR in invalid state (%d), rejecting", __func__, p_hcon->conn_state);
|
||||
}
|
||||
break;
|
||||
case HID_PSM_CONTROL:
|
||||
if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) {
|
||||
accept = FALSE;
|
||||
HIDD_TRACE_WARNING("%s: incoming CTRL in invalid state (%d), rejecting", __func__, p_hcon->conn_state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
accept = FALSE;
|
||||
HIDD_TRACE_ERROR("%s: received invalid PSM, rejecting", __func__);
|
||||
break;
|
||||
}
|
||||
if (!accept) {
|
||||
L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
|
||||
return;
|
||||
}
|
||||
// for CTRL we need to go through security and we reply in callback from there
|
||||
if (psm == HID_PSM_CONTROL) {
|
||||
p_hcon->conn_flags = 0;
|
||||
p_hcon->ctrl_cid = cid;
|
||||
p_hcon->ctrl_id = id;
|
||||
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
|
||||
p_hcon->conn_state = HID_CONN_STATE_SECURITY;
|
||||
if (btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, FALSE, BTM_SEC_PROTO_HID, HIDD_NOSEC_CHN,
|
||||
&hidd_sec_check_complete, p_dev) == BTM_CMD_STARTED) {
|
||||
L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_PENDING, L2CAP_CONN_OK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// for INTR we go directly to config state
|
||||
p_hcon->conn_state = HID_CONN_STATE_CONFIG;
|
||||
p_hcon->intr_cid = cid;
|
||||
L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
|
||||
L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg);
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_connect_cfm
|
||||
*
|
||||
* Description Handles L2CAP connection response (we act as client)
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result)
|
||||
{
|
||||
tHID_DEV_DEV_CTB *p_dev = &hd_cb.device;
|
||||
tHID_CONN *p_hcon = &hd_cb.device.conn;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x result=%d, conn_state=%d", __func__, cid, result, p_hcon->conn_state);
|
||||
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) ||
|
||||
((cid == p_hcon->ctrl_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL && (p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING_INTR))) ||
|
||||
((cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) && (p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING_CTRL))) {
|
||||
HIDD_TRACE_WARNING("%s: unexpected, cid:0x%04x, ctrl_cid:0x%04x, intr_cid:0x%04x, conn_state:%d", __func__, cid,
|
||||
p_hcon->ctrl_cid, p_hcon->intr_cid, p_hcon->conn_state);
|
||||
return;
|
||||
}
|
||||
if (result != L2CAP_CONN_OK) {
|
||||
HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__);
|
||||
if (cid == p_hcon->ctrl_cid)
|
||||
p_hcon->ctrl_cid = 0;
|
||||
else
|
||||
p_hcon->intr_cid = 0;
|
||||
hidd_conn_disconnect();
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL);
|
||||
return;
|
||||
}
|
||||
/* CTRL connect conf */
|
||||
if (cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_SECURITY;
|
||||
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* in case disconnected before sec completed */
|
||||
btm_sec_mx_access_request(p_dev->addr, HID_PSM_CONTROL, TRUE, BTM_SEC_PROTO_HID, HIDD_SEC_CHN,
|
||||
&hidd_sec_check_complete_orig, p_dev);
|
||||
} else {
|
||||
p_hcon->conn_state = HID_CONN_STATE_CONFIG;
|
||||
L2CA_ConfigReq(cid, &hd_cb.l2cap_intr_cfg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_config_ind
|
||||
*
|
||||
* Description Handles incoming L2CAP configuration request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE))
|
||||
p_hcon->rem_mtu_size = HID_DEV_MTU_SIZE;
|
||||
else
|
||||
p_hcon->rem_mtu_size = p_cfg->mtu;
|
||||
// accept without changes
|
||||
p_cfg->flush_to_present = FALSE;
|
||||
p_cfg->mtu_present = FALSE;
|
||||
p_cfg->result = L2CAP_CFG_OK;
|
||||
if (cid == p_hcon->intr_cid && hd_cb.use_in_qos && !p_cfg->qos_present) {
|
||||
p_cfg->qos_present = TRUE;
|
||||
memcpy(&p_cfg->qos, &hd_cb.in_qos, sizeof(FLOW_SPEC));
|
||||
}
|
||||
L2CA_ConfigRsp(cid, p_cfg);
|
||||
// update flags
|
||||
if (cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;
|
||||
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) {
|
||||
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
|
||||
if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
hidd_conn_disconnect();
|
||||
HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR", __func__);
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
|
||||
return;
|
||||
} else {
|
||||
p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE;
|
||||
}
|
||||
hidd_check_config_done();
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_config_cfm
|
||||
*
|
||||
* Description Handles incoming L2CAP configuration response
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
uint32_t reason;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid, p_cfg->result);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if (p_hcon->intr_cid == cid && p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) {
|
||||
tL2CAP_CFG_INFO new_qos;
|
||||
// QoS parameters not accepted for intr, try again with host proposal
|
||||
memcpy(&new_qos, &hd_cb.l2cap_intr_cfg, sizeof(new_qos));
|
||||
memcpy(&new_qos.qos, &p_cfg->qos, sizeof(FLOW_SPEC));
|
||||
new_qos.qos_present = TRUE;
|
||||
HIDD_TRACE_WARNING("%s: config failed, retry", __func__);
|
||||
L2CA_ConfigReq(cid, &new_qos);
|
||||
return;
|
||||
} else if (p_hcon->intr_cid == cid && p_cfg->result == L2CAP_CFG_UNKNOWN_OPTIONS) {
|
||||
// QoS not understood by remote device, try configuring without QoS
|
||||
HIDD_TRACE_WARNING("%s: config failed, retry without QoS", __func__);
|
||||
L2CA_ConfigReq(cid, &hd_cb.l2cap_cfg);
|
||||
return;
|
||||
} else if (p_cfg->result != L2CAP_CFG_OK) {
|
||||
HIDD_TRACE_WARNING("%s: config failed, disconnecting", __func__);
|
||||
hidd_conn_disconnect();
|
||||
reason = HID_L2CAP_CFG_FAIL | (uint32_t)p_cfg->result;
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, reason, NULL);
|
||||
return;
|
||||
}
|
||||
// update flags
|
||||
if (cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;
|
||||
if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) {
|
||||
p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;
|
||||
if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
hidd_conn_disconnect();
|
||||
HIDD_TRACE_WARNING("%s: could not start L2CAP connection for INTR", __func__);
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
|
||||
return;
|
||||
} else {
|
||||
p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE;
|
||||
}
|
||||
hidd_check_config_done();
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_disconnect_ind
|
||||
*
|
||||
* Description Handler incoming L2CAP disconnection request
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if (ack_needed)
|
||||
L2CA_DisconnectRsp(cid);
|
||||
if (cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->ctrl_cid = 0;
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL;
|
||||
} else {
|
||||
p_hcon->intr_cid = 0;
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_INTR;
|
||||
}
|
||||
if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
|
||||
HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);
|
||||
// clean any outstanding data on intr
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
hd_cb.device.state = HIDD_DEV_NO_CONN;
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, p_hcon->disc_reason, NULL);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_disconnect_cfm
|
||||
*
|
||||
* Description Handles L2CAP disconection response
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if (cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->ctrl_cid = 0;
|
||||
} else {
|
||||
p_hcon->intr_cid = 0;
|
||||
// now disconnect CTRL
|
||||
L2CA_DisconnectReq(p_hcon->ctrl_cid);
|
||||
}
|
||||
if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
|
||||
HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);
|
||||
hd_cb.device.state = HIDD_DEV_NO_CONN;
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
if (hd_cb.pending_vc_unplug) {
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_VC_UNPLUG, p_hcon->disc_reason, NULL);
|
||||
hd_cb.pending_vc_unplug = FALSE;
|
||||
} else {
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, p_hcon->disc_reason, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_cong_ind
|
||||
*
|
||||
* Description Handles L2CAP congestion status event
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_cong_ind(uint16_t cid, bool congested)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
return;
|
||||
}
|
||||
if (congested) {
|
||||
p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED;
|
||||
} else {
|
||||
p_hcon->conn_flags &= ~HID_CONN_FLAGS_CONGESTED;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_l2cif_data_ind
|
||||
*
|
||||
* Description Handler incoming data on L2CAP channel
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR *p_msg)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
uint8_t *p_data = (uint8_t *)(p_msg + 1) + p_msg->offset;
|
||||
uint8_t msg_type, param;
|
||||
bool err = FALSE;
|
||||
HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) {
|
||||
HIDD_TRACE_WARNING("%s: unknown cid", __func__);
|
||||
osi_free(p_msg);
|
||||
return;
|
||||
}
|
||||
msg_type = HID_GET_TRANS_FROM_HDR(*p_data);
|
||||
param = HID_GET_PARAM_FROM_HDR(*p_data);
|
||||
if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) {
|
||||
// skip HID header
|
||||
p_msg->offset++;
|
||||
p_msg->len--;
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_INTR_DATA, 0, p_msg);
|
||||
return;
|
||||
}
|
||||
switch (msg_type) {
|
||||
case HID_TRANS_GET_REPORT:
|
||||
// at this stage we don't know if Report Id shall be included in request
|
||||
// so we pass complete packet in callback and let other code analyze this
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_GET_REPORT, !!(param & HID_PAR_GET_REP_BUFSIZE_FOLLOWS), p_msg);
|
||||
break;
|
||||
case HID_TRANS_SET_REPORT:
|
||||
// as above
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_REPORT, 0, p_msg);
|
||||
break;
|
||||
case HID_TRANS_GET_IDLE:
|
||||
hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, HID_PAR_REP_TYPE_OTHER, hd_cb.device.idle_time, 0, NULL);
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
case HID_TRANS_SET_IDLE:
|
||||
if (p_msg->len != 2) {
|
||||
HIDD_TRACE_ERROR("%s: invalid len (%d) set idle request received", __func__, p_msg->len);
|
||||
err = TRUE;
|
||||
} else {
|
||||
hd_cb.device.idle_time = p_data[1];
|
||||
HIDD_TRACE_DEBUG("%s: idle_time = %d", __func__, hd_cb.device.idle_time);
|
||||
if (hd_cb.device.idle_time) {
|
||||
HIDD_TRACE_WARNING("%s: idle_time of %d ms not supported by HID Device", __func__,
|
||||
(hd_cb.device.idle_time * 4));
|
||||
err = TRUE;
|
||||
}
|
||||
}
|
||||
if (!err) {
|
||||
hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_SUCCESS, 0, 0, NULL);
|
||||
} else {
|
||||
hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM, 0, 0, NULL);
|
||||
}
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
case HID_TRANS_GET_PROTOCOL:
|
||||
hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, HID_PAR_REP_TYPE_OTHER, !hd_cb.device.boot_mode, 0, NULL);
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
case HID_TRANS_SET_PROTOCOL:
|
||||
hd_cb.device.boot_mode = !(param & HID_PAR_PROTOCOL_MASK);
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SET_PROTOCOL, param & HID_PAR_PROTOCOL_MASK, NULL);
|
||||
hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_SUCCESS, 0, 0, NULL);
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
case HID_TRANS_CONTROL:
|
||||
switch (param) {
|
||||
case HID_PAR_CONTROL_SUSPEND:
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_SUSPEND, 0, NULL);
|
||||
break;
|
||||
case HID_PAR_CONTROL_EXIT_SUSPEND:
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_EXIT_SUSPEND, 0, NULL);
|
||||
break;
|
||||
case HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG:
|
||||
hidd_conn_disconnect();
|
||||
// set flag so we can notify properly when disconnected
|
||||
hd_cb.pending_vc_unplug = TRUE;
|
||||
break;
|
||||
}
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
case HID_TRANS_DATA:
|
||||
default:
|
||||
HIDD_TRACE_WARNING("%s: got unsupported msg (%d)", __func__, msg_type);
|
||||
hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ, 0, 0, NULL);
|
||||
osi_free(p_msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_conn_reg
|
||||
*
|
||||
* Description Registers L2CAP channels
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS hidd_conn_reg(void)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
memset(&hd_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO));
|
||||
hd_cb.l2cap_cfg.mtu_present = TRUE;
|
||||
hd_cb.l2cap_cfg.mtu = HID_DEV_MTU_SIZE;
|
||||
hd_cb.l2cap_cfg.flush_to_present = TRUE;
|
||||
hd_cb.l2cap_cfg.flush_to = HID_DEV_FLUSH_TO;
|
||||
memset(&hd_cb.l2cap_intr_cfg, 0, sizeof(tL2CAP_CFG_INFO));
|
||||
hd_cb.l2cap_intr_cfg.mtu_present = TRUE;
|
||||
hd_cb.l2cap_intr_cfg.mtu = HID_DEV_MTU_SIZE;
|
||||
hd_cb.l2cap_intr_cfg.flush_to_present = TRUE;
|
||||
hd_cb.l2cap_intr_cfg.flush_to = HID_DEV_FLUSH_TO;
|
||||
if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO *)&dev_reg_info)) {
|
||||
HIDD_TRACE_ERROR("HID Control (device) registration failed");
|
||||
return (HID_ERR_L2CAP_FAILED);
|
||||
}
|
||||
if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO *)&dev_reg_info)) {
|
||||
L2CA_Deregister(HID_PSM_CONTROL);
|
||||
HIDD_TRACE_ERROR("HID Interrupt (device) registration failed");
|
||||
return (HID_ERR_L2CAP_FAILED);
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_conn_dereg
|
||||
*
|
||||
* Description Deregisters L2CAP channels
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
void hidd_conn_dereg(void)
|
||||
{
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
L2CA_Deregister(HID_PSM_CONTROL);
|
||||
L2CA_Deregister(HID_PSM_INTERRUPT);
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_conn_initiate
|
||||
*
|
||||
* Description Initiates HID connection to plugged device
|
||||
*
|
||||
* Returns HID_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS hidd_conn_initiate(void)
|
||||
{
|
||||
tHID_DEV_DEV_CTB *p_dev = &hd_cb.device;
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
if (!p_dev->in_use) {
|
||||
HIDD_TRACE_WARNING("%s: no virtual cable established", __func__);
|
||||
return (HID_ERR_NOT_REGISTERED);
|
||||
}
|
||||
if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) {
|
||||
HIDD_TRACE_WARNING("%s: connection already in progress", __func__);
|
||||
return (HID_ERR_CONN_IN_PROCESS);
|
||||
}
|
||||
p_dev->conn.ctrl_cid = 0;
|
||||
p_dev->conn.intr_cid = 0;
|
||||
p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL;
|
||||
p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG;
|
||||
BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN);
|
||||
/* Check if L2CAP started the connection process */
|
||||
if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) {
|
||||
HIDD_TRACE_WARNING("%s: could not start L2CAP connection", __func__);
|
||||
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
|
||||
} else {
|
||||
p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_conn_disconnect
|
||||
*
|
||||
* Description Disconnects existing HID connection
|
||||
*
|
||||
* Returns HID_SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS hidd_conn_disconnect(void)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
HIDD_TRACE_API("%s", __func__);
|
||||
// clean any outstanding data on intr
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
hd_cb.pending_data = NULL;
|
||||
}
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0)) {
|
||||
/* Set l2cap idle timeout to 0 (so ACL link is disconnected
|
||||
* immediately after last channel is closed) */
|
||||
L2CA_SetIdleTimeoutByBdAddr(hd_cb.device.addr, 0, BT_TRANSPORT_BR_EDR);
|
||||
if (p_hcon->intr_cid) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_INTR;
|
||||
L2CA_DisconnectReq(p_hcon->intr_cid);
|
||||
} else if (p_hcon->ctrl_cid) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL;
|
||||
L2CA_DisconnectReq(p_hcon->ctrl_cid);
|
||||
}
|
||||
} else {
|
||||
HIDD_TRACE_WARNING("%s: already disconnected", __func__);
|
||||
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function hidd_conn_send_data
|
||||
*
|
||||
* Description Sends data to host
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param, uint8_t data, uint16_t len,
|
||||
uint8_t *p_data)
|
||||
{
|
||||
tHID_CONN *p_hcon;
|
||||
BT_HDR *p_buf;
|
||||
uint8_t *p_out;
|
||||
uint16_t cid;
|
||||
uint16_t buf_size;
|
||||
HIDD_TRACE_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__, channel, msg_type, len);
|
||||
p_hcon = &hd_cb.device.conn;
|
||||
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
|
||||
return HID_ERR_CONGESTED;
|
||||
}
|
||||
switch (msg_type) {
|
||||
case HID_TRANS_HANDSHAKE:
|
||||
case HID_TRANS_CONTROL:
|
||||
cid = p_hcon->ctrl_cid;
|
||||
buf_size = HID_CONTROL_BUF_SIZE;
|
||||
break;
|
||||
case HID_TRANS_DATA:
|
||||
if (channel == HID_CHANNEL_CTRL) {
|
||||
cid = p_hcon->ctrl_cid;
|
||||
buf_size = HID_CONTROL_BUF_SIZE;
|
||||
} else {
|
||||
cid = p_hcon->intr_cid;
|
||||
buf_size = HID_INTERRUPT_BUF_SIZE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (HID_ERR_INVALID_PARAM);
|
||||
}
|
||||
p_buf = (BT_HDR *)osi_malloc(buf_size);
|
||||
if (p_buf == NULL)
|
||||
return (HID_ERR_NO_RESOURCES);
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
p_out = (uint8_t *)(p_buf + 1) + p_buf->offset;
|
||||
*p_out = HID_BUILD_HDR(msg_type, param);
|
||||
p_out++;
|
||||
p_buf->len = 1; // start with header only
|
||||
// add report id prefix only if non-zero (which is reserved)
|
||||
if (msg_type == HID_TRANS_DATA && (data || param == HID_PAR_REP_TYPE_OTHER)) {
|
||||
*p_out = data; // report_id
|
||||
p_out++;
|
||||
p_buf->len++;
|
||||
}
|
||||
if (len > 0 && p_data != NULL) {
|
||||
memcpy(p_out, p_data, len);
|
||||
p_buf->len += len;
|
||||
}
|
||||
// check if connected
|
||||
if (hd_cb.device.state != HIDD_DEV_CONNECTED) {
|
||||
// for DATA on intr we hold transfer and try to reconnect
|
||||
if (msg_type == HID_TRANS_DATA && cid == p_hcon->intr_cid) {
|
||||
// drop previous data, we do not queue it for now
|
||||
if (hd_cb.pending_data) {
|
||||
osi_free(hd_cb.pending_data);
|
||||
}
|
||||
hd_cb.pending_data = p_buf;
|
||||
if (hd_cb.device.conn.conn_state == HID_CONN_STATE_UNUSED) {
|
||||
hidd_conn_initiate();
|
||||
}
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
return HID_ERR_NO_CONNECTION;
|
||||
}
|
||||
#ifdef REPORT_TRANSFER_TIMESTAMP
|
||||
if (report_transfer) {
|
||||
HIDD_TRACE_ERROR("%s: report sent", __func__);
|
||||
}
|
||||
#endif
|
||||
HIDD_TRACE_VERBOSE("%s: report sent", __func__);
|
||||
if (!L2CA_DataWrite(cid, p_buf))
|
||||
return (HID_ERR_CONGESTED);
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
@ -31,7 +31,7 @@
|
||||
#include "stack/bt_types.h"
|
||||
#include "stack/hiddefs.h"
|
||||
#include "stack/hidh_api.h"
|
||||
#include "hidh_int.h"
|
||||
#include "hid_int.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "stack/btu.h"
|
||||
#include "btm_int.h"
|
||||
@ -39,7 +39,9 @@
|
||||
#if (HID_HOST_INCLUDED == TRUE)
|
||||
|
||||
#if HID_DYNAMIC_MEMORY == FALSE
|
||||
tHID_HOST_CTB hh_cb;
|
||||
tHID_HOST_CTB hh_cb;
|
||||
#else
|
||||
tHID_HOST_CTB *hidh_cb_ptr = NULL;
|
||||
#endif
|
||||
|
||||
static void hidh_search_callback (UINT16 sdp_result);
|
||||
@ -218,18 +220,46 @@ static void hidh_search_callback (UINT16 sdp_result)
|
||||
**
|
||||
** Description This function initializes the control block and trace variable
|
||||
**
|
||||
** Returns void
|
||||
** Returns tHID_STATUS
|
||||
**
|
||||
*******************************************************************************/
|
||||
void HID_HostInit (void)
|
||||
tHID_STATUS HID_HostInit (void)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (!hidh_cb_ptr) {
|
||||
hidh_cb_ptr = (tHID_HOST_CTB *)osi_malloc(sizeof(tHID_HOST_CTB));
|
||||
if (!hidh_cb_ptr) {
|
||||
return HID_ERR_NO_RESOURCES;
|
||||
}
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
memset(&hh_cb, 0, sizeof(tHID_HOST_CTB));
|
||||
|
||||
#if defined(HID_INITIAL_TRACE_LEVEL)
|
||||
hh_cb.trace_level = HID_INITIAL_TRACE_LEVEL;
|
||||
#if defined(HIDH_INITIAL_TRACE_LEVEL)
|
||||
hh_cb.trace_level = HIDH_INITIAL_TRACE_LEVEL;
|
||||
#else
|
||||
hh_cb.trace_level = BT_TRACE_LEVEL_NONE;
|
||||
#endif
|
||||
return HID_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function HID_HostInit
|
||||
**
|
||||
** Description This function deinitializes the control block
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void HID_HostDeinit (void)
|
||||
{
|
||||
#if (HID_DYNAMIC_MEMORY)
|
||||
if (hidh_cb_ptr) {
|
||||
osi_free(hidh_cb_ptr);
|
||||
hidh_cb_ptr = NULL;
|
||||
}
|
||||
#endif /* #if (HID_DYNAMIC_MEMORY) */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -362,6 +392,36 @@ tHID_STATUS HID_HostAddDev ( BD_ADDR addr, UINT16 attr_mask, UINT8 *handle )
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function HID_HostGetDev
|
||||
**
|
||||
** Description This is called so HID-host can find this device.
|
||||
**
|
||||
** Returns tHID_STATUS
|
||||
**
|
||||
*******************************************************************************/
|
||||
tHID_STATUS HID_HostGetDev(BD_ADDR addr, UINT8 *handle)
|
||||
{
|
||||
int i;
|
||||
/* Find an entry for this device in hh_cb.devices array */
|
||||
if (!hh_cb.reg_flag) {
|
||||
return (HID_ERR_NOT_REGISTERED);
|
||||
}
|
||||
|
||||
for (i = 0; i < HID_HOST_MAX_DEVICES; i++) {
|
||||
if ((hh_cb.devices[i].in_use) && (!memcmp(addr, hh_cb.devices[i].addr, BD_ADDR_LEN))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == HID_HOST_MAX_DEVICES) {
|
||||
*handle = 0xff;
|
||||
} else {
|
||||
*handle = i;
|
||||
}
|
||||
return (HID_SUCCESS);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
@ -41,7 +41,7 @@
|
||||
#include "stack/hiddefs.h"
|
||||
|
||||
#include "stack/hidh_api.h"
|
||||
#include "hidh_int.h"
|
||||
#include "hid_int.h"
|
||||
#include "osi/osi.h"
|
||||
|
||||
#if (HID_HOST_INCLUDED == TRUE)
|
||||
@ -132,15 +132,16 @@ tHID_STATUS hidh_conn_disconnect (UINT8 dhandle)
|
||||
HIDH_TRACE_EVENT ("HID-Host disconnect");
|
||||
|
||||
if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0)) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;
|
||||
|
||||
/* Set l2cap idle timeout to 0 (so ACL link is disconnected
|
||||
* immediately after last channel is closed) */
|
||||
L2CA_SetIdleTimeoutByBdAddr(hh_cb.devices[dhandle].addr, 0, BT_TRANSPORT_BR_EDR);
|
||||
/* Disconnect both interrupt and control channels */
|
||||
if (p_hcon->intr_cid) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_INTR;
|
||||
L2CA_DisconnectReq (p_hcon->intr_cid);
|
||||
} else if (p_hcon->ctrl_cid) {
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL;
|
||||
L2CA_DisconnectReq (p_hcon->ctrl_cid);
|
||||
}
|
||||
} else {
|
||||
@ -360,12 +361,12 @@ static void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result)
|
||||
p_hcon = &hh_cb.devices[dhandle].conn;
|
||||
}
|
||||
|
||||
if ((p_hcon == NULL)
|
||||
|| (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG))
|
||||
|| ((l2cap_cid == p_hcon->ctrl_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL))
|
||||
|| ((l2cap_cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)
|
||||
&& (p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING))) {
|
||||
HIDH_TRACE_WARNING ("HID-Host Rcvd unexpected conn cnf, CID 0x%x ", l2cap_cid);
|
||||
if ((p_hcon == NULL) || (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG)) ||
|
||||
((l2cap_cid == p_hcon->ctrl_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL) &&
|
||||
(p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING_INTR)) ||
|
||||
((l2cap_cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) &&
|
||||
(p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING_CTRL))) {
|
||||
HIDH_TRACE_WARNING("HID-Host Rcvd unexpected conn cnf, CID 0x%x ", l2cap_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -592,12 +593,12 @@ static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
|
||||
|
||||
HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
|
||||
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;
|
||||
|
||||
if (l2cap_cid == p_hcon->ctrl_cid) {
|
||||
p_hcon->ctrl_cid = 0;
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL;
|
||||
} else {
|
||||
p_hcon->intr_cid = 0;
|
||||
p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_INTR;
|
||||
}
|
||||
|
||||
if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
|
@ -26,18 +26,21 @@
|
||||
#define HID_CONN_H
|
||||
|
||||
#include "common/bt_defs.h"
|
||||
#if (HID_HOST_INCLUDED == TRUE)
|
||||
|
||||
#if (BT_HID_INCLUDED == TRUE)
|
||||
|
||||
/* Define the HID Connection Block
|
||||
*/
|
||||
typedef struct hid_conn {
|
||||
#define HID_CONN_STATE_UNUSED (0)
|
||||
#define HID_CONN_STATE_CONNECTING_CTRL (1)
|
||||
#define HID_CONN_STATE_CONNECTING_INTR (2)
|
||||
#define HID_CONN_STATE_CONFIG (3)
|
||||
#define HID_CONN_STATE_CONNECTED (4)
|
||||
#define HID_CONN_STATE_DISCONNECTING (5)
|
||||
#define HID_CONN_STATE_SECURITY (6)
|
||||
#define HID_CONN_STATE_UNUSED (0)
|
||||
#define HID_CONN_STATE_CONNECTING_CTRL (1)
|
||||
#define HID_CONN_STATE_CONNECTING_INTR (2)
|
||||
#define HID_CONN_STATE_CONFIG (3)
|
||||
#define HID_CONN_STATE_CONNECTED (4)
|
||||
#define HID_CONN_STATE_DISCONNECTING (5)
|
||||
#define HID_CONN_STATE_SECURITY (6)
|
||||
#define HID_CONN_STATE_DISCONNECTING_CTRL (7)
|
||||
#define HID_CONN_STATE_DISCONNECTING_INTR (8)
|
||||
|
||||
UINT8 conn_state;
|
||||
|
||||
@ -62,9 +65,8 @@ typedef struct hid_conn {
|
||||
|
||||
#define HID_SEC_CHN 1
|
||||
#define HID_NOSEC_CHN 2
|
||||
#define HIDD_SEC_CHN 3
|
||||
#define HIDD_NOSEC_CHN 4
|
||||
|
||||
#define HIDD_SEC_CHN 3
|
||||
#define HIDD_NOSEC_CHN 4
|
||||
|
||||
#endif ///HID_HOST_INCLUDED == TRUE
|
||||
#endif ///BT_HID_INCLUDED == TRUE
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -15,26 +16,21 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains HID HOST internal definitions
|
||||
* This file contains HID DEVICE internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef HID_INT_H
|
||||
#define HID_INT_H
|
||||
|
||||
#ifndef HIDH_INT_H
|
||||
#define HIDH_INT_H
|
||||
|
||||
#include "stack/hidh_api.h"
|
||||
#include "hid_conn.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#if (BT_HID_INCLUDED == TRUE)
|
||||
|
||||
#if (HID_HOST_INCLUDED == TRUE)
|
||||
|
||||
enum {
|
||||
HID_DEV_NO_CONN,
|
||||
HID_DEV_CONNECTED
|
||||
};
|
||||
#include "stack/hidh_api.h"
|
||||
enum { HID_DEV_NO_CONN, HID_DEV_CONNECTED };
|
||||
|
||||
typedef struct per_device_ctb {
|
||||
BOOLEAN in_use;
|
||||
@ -70,17 +66,16 @@ extern void hidh_conn_dereg( void );
|
||||
extern tHID_STATUS hidh_conn_disconnect (UINT8 dhandle);
|
||||
extern tHID_STATUS hidh_conn_initiate (UINT8 dhandle);
|
||||
extern void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** Main Control Block
|
||||
*******************************************************************************/
|
||||
* Main Control Block
|
||||
******************************************************************************/
|
||||
|
||||
#if HID_DYNAMIC_MEMORY == FALSE
|
||||
extern tHID_HOST_CTB hh_cb;
|
||||
extern tHID_HOST_CTB hh_cb;
|
||||
#else
|
||||
extern tHID_HOST_CTB *hidh_cb_ptr;
|
||||
#define hh_cb (*hidh_cb_ptr)
|
||||
@ -89,7 +84,60 @@ extern tHID_HOST_CTB *hidh_cb_ptr;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HID_HOST_INCLUDED == TRUE */
|
||||
|
||||
#endif ///HID_HOST_INCLUDED == TRUE
|
||||
#if (HID_DEV_INCLUDED == TRUE)
|
||||
#include "stack/hidd_api.h"
|
||||
enum { HIDD_DEV_NO_CONN, HIDD_DEV_CONNECTED };
|
||||
|
||||
typedef struct device_ctb {
|
||||
bool in_use;
|
||||
BD_ADDR addr;
|
||||
uint8_t state;
|
||||
tHID_CONN conn;
|
||||
bool boot_mode;
|
||||
uint8_t idle_time;
|
||||
} tHID_DEV_DEV_CTB;
|
||||
|
||||
typedef struct dev_ctb {
|
||||
tHID_DEV_DEV_CTB device;
|
||||
tHID_DEV_HOST_CALLBACK *callback;
|
||||
tL2CAP_CFG_INFO l2cap_cfg;
|
||||
tL2CAP_CFG_INFO l2cap_intr_cfg;
|
||||
bool use_in_qos;
|
||||
FLOW_SPEC in_qos;
|
||||
bool reg_flag;
|
||||
uint8_t trace_level;
|
||||
bool allow_incoming;
|
||||
BT_HDR *pending_data;
|
||||
bool pending_vc_unplug;
|
||||
} tHID_DEV_CTB;
|
||||
|
||||
extern tHID_STATUS hidd_conn_reg(void);
|
||||
extern void hidd_conn_dereg(void);
|
||||
extern tHID_STATUS hidd_conn_initiate(void);
|
||||
extern tHID_STATUS hidd_conn_disconnect(void);
|
||||
extern tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param, uint8_t data, uint16_t len,
|
||||
uint8_t *p_data);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Main Control Block
|
||||
******************************************************************************/
|
||||
|
||||
#if HID_DYNAMIC_MEMORY == FALSE
|
||||
extern tHID_DEV_CTB hd_cb;
|
||||
#else
|
||||
extern tHID_DEV_CTB *hidd_cb_ptr;
|
||||
#define hd_cb (*hidd_cb_ptr)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HID_DEV_INCLUDED == TRUE */
|
||||
|
||||
#endif /* BT_HID_INCLUDED == TRUE */
|
||||
#endif /* HID_INT_H */
|
@ -1252,9 +1252,12 @@ typedef UINT8 tBTM_LINK_KEY_TYPE;
|
||||
#define BTM_SEC_SERVICE_HDP_SNK 48
|
||||
#define BTM_SEC_SERVICE_HDP_SRC 49
|
||||
#define BTM_SEC_SERVICE_ATT 50
|
||||
#define BTM_SEC_SERVICE_HIDD_SEC_CTRL 51
|
||||
#define BTM_SEC_SERVICE_HIDD_NOSEC_CTRL 52
|
||||
#define BTM_SEC_SERVICE_HIDD_INTR 53
|
||||
|
||||
/* Update these as services are added */
|
||||
#define BTM_SEC_SERVICE_FIRST_EMPTY 51
|
||||
#define BTM_SEC_SERVICE_FIRST_EMPTY 54
|
||||
|
||||
#ifndef BTM_SEC_MAX_SERVICES
|
||||
#define BTM_SEC_MAX_SERVICES 65
|
||||
@ -1915,11 +1918,11 @@ typedef UINT8 tBTM_CONTRL_STATE;
|
||||
/*****************************************************************************
|
||||
** EXTERNAL FUNCTION DECLARATIONS
|
||||
*****************************************************************************/
|
||||
/*
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** DEVICE CONTROL and COMMON FUNCTIONS
|
||||
*****************************************************************************/
|
||||
@ -4141,10 +4144,8 @@ tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_chann
|
||||
*******************************************************************************/
|
||||
tBTM_STATUS BTM_BleSetChannels (BLE_CHANNELS channels, tBTM_CMPL_CB *p_ble_channels_cmpl_cback);
|
||||
|
||||
/*
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif /* BTM_API_H */
|
||||
|
273
components/bt/host/bluedroid/stack/include/stack/hidd_api.h
Normal file
273
components/bt/host/bluedroid/stack/include/stack/hidd_api.h
Normal file
@ -0,0 +1,273 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef HIDD_API_H
|
||||
#define HIDD_API_H
|
||||
#include "hiddefs.h"
|
||||
#include "sdp_api.h"
|
||||
|
||||
#if (HID_DEV_INCLUDED == TRUE)
|
||||
/*****************************************************************************
|
||||
* Type Definitions
|
||||
****************************************************************************/
|
||||
enum {
|
||||
HID_CHANNEL_INTR,
|
||||
HID_CHANNEL_CTRL
|
||||
};
|
||||
/*
|
||||
HID_DHOST_EVT_OPEN - connected to host device (CTRL and INTR), data = n/a
|
||||
HID_DHOST_EVT_CLOSE - disconnected from host device, data=reason
|
||||
HID_DHOST_EVT_GET_REPORT - got GET_REPORT from host
|
||||
HID_DHOST_EVT_SET_REPORT - got SET_REPORT from host
|
||||
HID_DHOST_EVT_SET_PROTOCOL - got SET_PROTOCOL from host
|
||||
*/
|
||||
|
||||
enum {
|
||||
HID_DHOST_EVT_OPEN,
|
||||
HID_DHOST_EVT_CLOSE,
|
||||
HID_DHOST_EVT_GET_REPORT,
|
||||
HID_DHOST_EVT_SET_REPORT,
|
||||
HID_DHOST_EVT_SET_PROTOCOL,
|
||||
HID_DHOST_EVT_INTR_DATA,
|
||||
HID_DHOST_EVT_VC_UNPLUG,
|
||||
HID_DHOST_EVT_SUSPEND,
|
||||
HID_DHOST_EVT_EXIT_SUSPEND,
|
||||
};
|
||||
|
||||
typedef void (tHID_DEV_HOST_CALLBACK)(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR* p_buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
* External Function Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevInit
|
||||
*
|
||||
* Description Initializes control block
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevInit(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevInit
|
||||
*
|
||||
* Description Deinitializes control block
|
||||
*
|
||||
* Returns void
|
||||
*
|
||||
******************************************************************************/
|
||||
extern void HID_DevDeinit(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevRegister
|
||||
*
|
||||
* Description Registers HID device with lower layers
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevDeregister
|
||||
*
|
||||
* Description Deregisters HID device with lower layers
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevDeregister(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetSecurityLevel
|
||||
*
|
||||
* Description Sets security level for HID device connections
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevAddRecord
|
||||
*
|
||||
* Description Creates SDP record for HID device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name,
|
||||
char* p_description, char* p_provider,
|
||||
uint16_t subclass, uint16_t desc_len,
|
||||
uint8_t* p_desc_data);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSendReport
|
||||
*
|
||||
* Description Sends report
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id,
|
||||
uint16_t len, uint8_t* p_data);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevVirtualCableUnplug
|
||||
*
|
||||
* Description Sends Virtual Cable Unplug
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevVirtualCableUnplug(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevPlugDevice
|
||||
*
|
||||
* Description Establishes virtual cable to given host
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevPlugDevice(BD_ADDR addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevUnplugDevice
|
||||
*
|
||||
* Description Unplugs virtual cable from given host
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevConnect
|
||||
*
|
||||
* Description Connects to device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevConnect(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevDisconnect
|
||||
*
|
||||
* Description Disconnects from device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevDisconnect(void);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetIncomingPolicy
|
||||
*
|
||||
* Description Sets policy for incoming connections (allowed/disallowed)
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSetIncomingPolicy(bool allow);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevReportError
|
||||
*
|
||||
* Description Reports error for Set Report via HANDSHAKE
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevReportError(uint8_t error);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevGetDevice
|
||||
*
|
||||
* Description Returns the BD Address of virtually cabled device
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevGetDevice(BD_ADDR* addr);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetIncomingQos
|
||||
*
|
||||
* Description Sets Incoming QoS values for Interrupt L2CAP Channel
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSetIncomingQos(
|
||||
uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetOutgoingQos
|
||||
*
|
||||
* Description Sets Outgoing QoS values for Interrupt L2CAP Channel
|
||||
*
|
||||
* Returns tHID_STATUS
|
||||
*
|
||||
******************************************************************************/
|
||||
extern tHID_STATUS HID_DevSetOutgoingQos(
|
||||
uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
|
||||
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Function HID_DevSetTraceLevel
|
||||
*
|
||||
* Description This function sets the trace level for HID Dev. If called
|
||||
* with a value of 0xFF, it simply reads the current trace level.
|
||||
*
|
||||
* Returns the new (current) trace level
|
||||
*
|
||||
******************************************************************************/
|
||||
extern uint8_t HID_DevSetTraceLevel(uint8_t new_level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* HIDD_API_H */
|
@ -25,7 +25,8 @@
|
||||
#ifndef HIDDEFS_H
|
||||
#define HIDDEFS_H
|
||||
#include "common/bt_target.h"
|
||||
#if (HID_HOST_INCLUDED == TRUE)
|
||||
|
||||
#if (HID_HOST_INCLUDED == TRUE || HID_DEV_INCLUDED == TRUE)
|
||||
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
#include "stack/sdp_api.h"
|
||||
|
@ -139,6 +139,17 @@ extern tHID_STATUS HID_HostDeregister(void);
|
||||
extern tHID_STATUS HID_HostAddDev (BD_ADDR addr, UINT16 attr_mask,
|
||||
UINT8 *handle );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function HID_HostGetDev
|
||||
**
|
||||
** Description This is called so HID-host can find this device.
|
||||
**
|
||||
** Returns tHID_STATUS
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tHID_STATUS HID_HostGetDev(BD_ADDR addr, UINT8 *handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function HID_HostRemoveDev
|
||||
@ -191,9 +202,18 @@ extern tHID_STATUS HID_HostCloseDev(UINT8 dev_handle );
|
||||
**
|
||||
** Description This function initializes the control block and trace variable
|
||||
**
|
||||
** Returns tHID_STATUS
|
||||
*******************************************************************************/
|
||||
extern tHID_STATUS HID_HostInit(void);
|
||||
|
||||
/*******************************************************************************
|
||||
** Function HID_HostDeinit
|
||||
**
|
||||
** Description This function deinitializes the control block
|
||||
**
|
||||
** Returns void
|
||||
*******************************************************************************/
|
||||
extern void HID_HostInit(void);
|
||||
extern void HID_HostDeinit(void);
|
||||
|
||||
/*******************************************************************************
|
||||
** Function HID_HostSetSecurityLevel
|
||||
|
@ -0,0 +1,7 @@
|
||||
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(bt_hid_mouse_device)
|
@ -0,0 +1,8 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := bt_hid_mouse_device
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
@ -0,0 +1,11 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
|
||||
# ESP-IDF HID Device over Bluetooth Classic Demo
|
||||
|
||||
Demo of HID Device over Bluetooth Classic.
|
||||
|
||||
This turns the device into a mouse, but can be altered to be any kind of HID device.
|
||||
|
||||
After loading the code, connect with a computer to a device broadcasting
|
||||
as "HID Mouse Example". The mouse should move left and right while they are connected.
|
@ -0,0 +1,7 @@
|
||||
#set(COMPONENT_SRCS "main.c")
|
||||
#set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||
|
||||
#register_component()
|
||||
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS ".")
|
@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
@ -0,0 +1,436 @@
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_hidd_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_err.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#define BOOT_PROTO_MOUSE_RPT_ID 0x02
|
||||
typedef struct
|
||||
{
|
||||
esp_hidd_app_param_t app_param;
|
||||
esp_hidd_qos_param_t both_qos;
|
||||
uint8_t protocol_mode;
|
||||
SemaphoreHandle_t mouse_mutex;
|
||||
xTaskHandle mouse_task_hdl;
|
||||
uint8_t buffer[4];
|
||||
int8_t x_dir;
|
||||
} local_param_t;
|
||||
|
||||
static local_param_t s_local_param = {0};
|
||||
|
||||
bool check_report_id_type(uint8_t report_id, uint8_t report_type)
|
||||
{
|
||||
bool ret = false;
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
do {
|
||||
if (report_type != ESP_HIDD_REPORT_TYPE_INPUT) {
|
||||
break;
|
||||
}
|
||||
if (s_local_param.protocol_mode == ESP_HIDD_BOOT_MODE) {
|
||||
if (report_id == BOOT_PROTO_MOUSE_RPT_ID) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (report_id == 0) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (!ret) {
|
||||
if (s_local_param.protocol_mode == ESP_HIDD_BOOT_MODE) {
|
||||
esp_bt_hid_device_report_error(ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID);
|
||||
} else {
|
||||
esp_bt_hid_device_report_error(ESP_HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID);
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send the buttons, change in x, and change in y
|
||||
void send_mouse(uint8_t buttons, char dx, char dy, char wheel)
|
||||
{
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
if (s_local_param.protocol_mode == ESP_HIDD_REPORT_MODE) {
|
||||
s_local_param.buffer[0] = buttons;
|
||||
s_local_param.buffer[1] = dx;
|
||||
s_local_param.buffer[2] = dy;
|
||||
s_local_param.buffer[3] = wheel;
|
||||
esp_bt_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, 0x00, 4, s_local_param.buffer);
|
||||
} else if (s_local_param.protocol_mode == ESP_HIDD_BOOT_MODE) {
|
||||
s_local_param.buffer[0] = buttons;
|
||||
s_local_param.buffer[1] = dx;
|
||||
s_local_param.buffer[2] = dy;
|
||||
esp_bt_hid_device_send_report(ESP_HIDD_REPORT_TYPE_INTRDATA, BOOT_PROTO_MOUSE_RPT_ID, 3, s_local_param.buffer);
|
||||
}
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
}
|
||||
|
||||
// move the mouse left and right
|
||||
void mouse_move_task(void* pvParameters) {
|
||||
const char* TAG = "mouse_move_task";
|
||||
|
||||
ESP_LOGI(TAG, "starting");
|
||||
for(;;) {
|
||||
s_local_param.x_dir = 1;
|
||||
int8_t step = 10;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
s_local_param.x_dir *= -1;
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
for (int j = 0; j < 100; j++) {
|
||||
send_mouse(0, s_local_param.x_dir * step, 0, 0);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_bt_address(void) {
|
||||
const char* TAG = "bt_address";
|
||||
const uint8_t* bd_addr;
|
||||
|
||||
bd_addr = esp_bt_dev_get_address();
|
||||
ESP_LOGI(TAG, "my bluetooth address is %02X:%02X:%02X:%02X:%02X:%02X",
|
||||
bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
|
||||
}
|
||||
|
||||
// a generic mouse descriptor
|
||||
uint8_t hid_descriptor_mouse_boot_mode[] = {
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x38, // USAGE (Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
int hid_descriptor_mouse_boot_mode_len = sizeof(hid_descriptor_mouse_boot_mode);
|
||||
|
||||
void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
|
||||
{
|
||||
const char* TAG = "esp_bt_gap_cb";
|
||||
switch (event) {
|
||||
case ESP_BT_GAP_AUTH_CMPL_EVT:{
|
||||
if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGI(TAG, "authentication success: %s", param->auth_cmpl.device_name);
|
||||
esp_log_buffer_hex(TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_PIN_REQ_EVT:{
|
||||
ESP_LOGI(TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
|
||||
if (param->pin_req.min_16_digit) {
|
||||
ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000");
|
||||
esp_bt_pin_code_t pin_code = {0};
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Input pin code: 1234");
|
||||
esp_bt_pin_code_t pin_code;
|
||||
pin_code[0] = '1';
|
||||
pin_code[1] = '2';
|
||||
pin_code[2] = '3';
|
||||
pin_code[3] = '4';
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if (CONFIG_BT_SSP_ENABLED == true)
|
||||
case ESP_BT_GAP_CFM_REQ_EVT:
|
||||
ESP_LOGI(TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
|
||||
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
|
||||
break;
|
||||
case ESP_BT_GAP_KEY_NOTIF_EVT:
|
||||
ESP_LOGI(TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
|
||||
break;
|
||||
case ESP_BT_GAP_KEY_REQ_EVT:
|
||||
ESP_LOGI(TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
|
||||
break;
|
||||
#endif
|
||||
case ESP_BT_GAP_MODE_CHG_EVT:
|
||||
ESP_LOGI(TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d", param->mode_chg.mode);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "event: %d", event);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bt_app_task_start_up(void)
|
||||
{
|
||||
s_local_param.mouse_mutex = xSemaphoreCreateMutex();
|
||||
memset(s_local_param.buffer, 0, 4);
|
||||
xTaskCreate(mouse_move_task, "mouse_move_task", 2 * 1024, NULL, configMAX_PRIORITIES - 3, &s_local_param.mouse_task_hdl);
|
||||
return;
|
||||
}
|
||||
|
||||
void bt_app_task_shut_down(void)
|
||||
{
|
||||
if (s_local_param.mouse_task_hdl) {
|
||||
vTaskDelete(s_local_param.mouse_task_hdl);
|
||||
s_local_param.mouse_task_hdl = NULL;
|
||||
}
|
||||
|
||||
if (s_local_param.mouse_mutex) {
|
||||
vSemaphoreDelete(s_local_param.mouse_mutex);
|
||||
s_local_param.mouse_mutex = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void esp_bt_hidd_cb(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param)
|
||||
{
|
||||
static const char* TAG = "esp_bt_hidd_cb";
|
||||
switch (event) {
|
||||
case ESP_HIDD_INIT_EVT:
|
||||
if (param->init.status == ESP_HIDD_SUCCESS) {
|
||||
ESP_LOGI(TAG, "setting hid parameters");
|
||||
esp_bt_hid_device_register_app(&s_local_param.app_param, &s_local_param.both_qos, &s_local_param.both_qos);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "init hidd failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_DEINIT_EVT:
|
||||
break;
|
||||
case ESP_HIDD_REGISTER_APP_EVT:
|
||||
if (param->register_app.status == ESP_HIDD_SUCCESS) {
|
||||
ESP_LOGI(TAG, "setting hid parameters success!");
|
||||
ESP_LOGI(TAG, "setting to connectable, discoverable");
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
if (param->register_app.in_use && param->register_app.bd_addr != NULL) {
|
||||
ESP_LOGI(TAG, "start virtual cable plug!");
|
||||
esp_bt_hid_device_connect(param->register_app.bd_addr);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "setting hid parameters failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_UNREGISTER_APP_EVT:
|
||||
if (param->unregister_app.status == ESP_HIDD_SUCCESS) {
|
||||
ESP_LOGI(TAG, "unregister app success!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unregister app failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_OPEN_EVT:
|
||||
if (param->open.status == ESP_HIDD_SUCCESS) {
|
||||
if (param->open.conn_status == ESP_HIDD_CONN_STATE_CONNECTING) {
|
||||
ESP_LOGI(TAG, "connecting...");
|
||||
} else if (param->open.conn_status == ESP_HIDD_CONN_STATE_CONNECTED) {
|
||||
ESP_LOGI(TAG, "connected to %02x:%02x:%02x:%02x:%02x:%02x", param->open.bd_addr[0],
|
||||
param->open.bd_addr[1], param->open.bd_addr[2], param->open.bd_addr[3], param->open.bd_addr[4],
|
||||
param->open.bd_addr[5]);
|
||||
bt_app_task_start_up();
|
||||
ESP_LOGI(TAG, "making self non-discoverable and non-connectable.");
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unknown connection status");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "open failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_CLOSE_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_CLOSE_EVT");
|
||||
if (param->close.status == ESP_HIDD_SUCCESS) {
|
||||
if (param->close.conn_status == ESP_HIDD_CONN_STATE_DISCONNECTING) {
|
||||
ESP_LOGI(TAG, "disconnecting...");
|
||||
} else if (param->close.conn_status == ESP_HIDD_CONN_STATE_DISCONNECTED) {
|
||||
ESP_LOGI(TAG, "disconnected!");
|
||||
bt_app_task_shut_down();
|
||||
ESP_LOGI(TAG, "making self discoverable and connectable again.");
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unknown connection status");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "close failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_SEND_REPORT_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_SEND_REPORT_EVT id:0x%02x, type:%d", param->send_report.report_id,
|
||||
param->send_report.report_type);
|
||||
break;
|
||||
case ESP_HIDD_REPORT_ERR_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_REPORT_ERR_EVT");
|
||||
break;
|
||||
case ESP_HIDD_GET_REPORT_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_GET_REPORT_EVT id:0x%02x, type:%d, size:%d", param->get_report.report_id,
|
||||
param->get_report.report_type, param->get_report.buffer_size);
|
||||
if (check_report_id_type(param->get_report.report_id, param->get_report.report_type)) {
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
if (s_local_param.protocol_mode == ESP_HIDD_REPORT_MODE) {
|
||||
esp_bt_hid_device_send_report(param->get_report.report_type, 0x00, 4, s_local_param.buffer);
|
||||
} else if (s_local_param.protocol_mode == ESP_HIDD_BOOT_MODE) {
|
||||
esp_bt_hid_device_send_report(param->get_report.report_type, 0x02, 3, s_local_param.buffer);
|
||||
}
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "check_report_id failed!");
|
||||
}
|
||||
break;
|
||||
case ESP_HIDD_SET_REPORT_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_SET_REPORT_EVT");
|
||||
break;
|
||||
case ESP_HIDD_SET_PROTOCOL_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_SET_PROTOCOL_EVT");
|
||||
if (param->set_protocol.protocol_mode == ESP_HIDD_BOOT_MODE) {
|
||||
ESP_LOGI(TAG, " - boot protocol");
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
s_local_param.x_dir = -1;
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
} else if (param->set_protocol.protocol_mode == ESP_HIDD_REPORT_MODE) {
|
||||
ESP_LOGI(TAG, " - report protocol");
|
||||
}
|
||||
xSemaphoreTake(s_local_param.mouse_mutex, portMAX_DELAY);
|
||||
s_local_param.protocol_mode = param->set_protocol.protocol_mode;
|
||||
xSemaphoreGive(s_local_param.mouse_mutex);
|
||||
break;
|
||||
case ESP_HIDD_INTR_DATA_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_INTR_DATA_EVT");
|
||||
break;
|
||||
case ESP_HIDD_VC_UNPLUG_EVT:
|
||||
ESP_LOGI(TAG, "ESP_HIDD_VC_UNPLUG_EVT");
|
||||
if (param->vc_unplug.status == ESP_HIDD_SUCCESS) {
|
||||
if (param->close.conn_status == ESP_HIDD_CONN_STATE_DISCONNECTED) {
|
||||
ESP_LOGI(TAG, "disconnected!");
|
||||
bt_app_task_shut_down();
|
||||
ESP_LOGI(TAG, "making self discoverable and connectable again.");
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unknown connection status");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "close failed!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
const char* TAG = "app_main";
|
||||
esp_err_t ret;
|
||||
|
||||
s_local_param.app_param.name = "Mouse";
|
||||
s_local_param.app_param.description = "Mouse Example";
|
||||
s_local_param.app_param.provider = "ESP32";
|
||||
s_local_param.app_param.subclass = ESP_HID_CLASS_MIC;
|
||||
s_local_param.app_param.desc_list = hid_descriptor_mouse_boot_mode;
|
||||
s_local_param.app_param.desc_list_len = hid_descriptor_mouse_boot_mode_len;
|
||||
memset(&s_local_param.both_qos, 0, sizeof(esp_hidd_qos_param_t)); // don't set the qos parameters
|
||||
s_local_param.protocol_mode = ESP_HIDD_REPORT_MODE;
|
||||
|
||||
ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( ret );
|
||||
|
||||
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "initialize controller failed: %s\n", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "enable controller failed: %s\n", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bluedroid_init()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "initialize bluedroid failed: %s\n", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bluedroid_enable()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "enable bluedroid failed: %s\n", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bt_gap_register_callback(esp_bt_gap_cb)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "gap register failed: %s\n", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ESP_LOGI(TAG, "setting device name");
|
||||
esp_bt_dev_set_device_name("HID Mouse Example");
|
||||
|
||||
ESP_LOGI(TAG, "setting cod major, peripheral");
|
||||
esp_bt_cod_t cod;
|
||||
cod.major = ESP_BT_COD_MAJOR_DEV_PERIPHERAL;
|
||||
esp_bt_gap_set_cod(cod ,ESP_BT_SET_COD_MAJOR_MINOR);
|
||||
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
|
||||
ESP_LOGI(TAG, "register hid device callback");
|
||||
esp_bt_hid_device_register_callback(esp_bt_hidd_cb);
|
||||
|
||||
ESP_LOGI(TAG, "starting hid device");
|
||||
esp_bt_hid_device_init();
|
||||
|
||||
#if (CONFIG_BT_SSP_ENABLED == true)
|
||||
/* Set default parameters for Secure Simple Pairing */
|
||||
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
|
||||
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE;
|
||||
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set default parameters for Legacy Pairing
|
||||
* Use variable pin, input pin code when pairing
|
||||
*/
|
||||
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE;
|
||||
esp_bt_pin_code_t pin_code;
|
||||
esp_bt_gap_set_pin(pin_type, 0, pin_code);
|
||||
|
||||
print_bt_address();
|
||||
ESP_LOGI(TAG, "exiting");
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||
CONFIG_BT_CLASSIC_ENABLED=y
|
||||
CONFIG_BT_HID_ENABLED=y
|
||||
CONFIG_BT_HID_DEVICE_ENABLED=y
|
Loading…
x
Reference in New Issue
Block a user