| /****************************************************************************** |
| * |
| * Copyright (C) 2016 The Android Open Source Project |
| * Copyright (C) 2009-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. |
| * |
| ******************************************************************************/ |
| |
| /************************************************************************************ |
| * |
| * Filename: btif_hd.c |
| * |
| * Description: HID Device Profile Bluetooth Interface |
| * |
| * |
| ***********************************************************************************/ |
| #include <errno.h> |
| #include <hardware/bluetooth.h> |
| #include <hardware/bt_hd.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #define LOG_TAG "BTIF_HD" |
| |
| #include "bta_api.h" |
| #include "bta_hd_api.h" |
| #include "bta_hh_api.h" |
| |
| #include "btif_common.h" |
| #include "btif_hd.h" |
| #include "btif_storage.h" |
| #include "btif_util.h" |
| |
| #define BTIF_HD_APP_NAME_LEN 50 |
| #define BTIF_HD_APP_DESCRIPTION_LEN 50 |
| #define BTIF_HD_APP_PROVIDER_LEN 50 |
| #define BTIF_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 |
| |
| extern bool bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr); |
| extern bool check_cod_hid(const bt_bdaddr_t* remote_bdaddr); |
| extern void btif_hh_service_registration(bool enable); |
| |
| /* HD request events */ |
| typedef enum { BTIF_HD_DUMMY_REQ_EVT = 0 } btif_hd_req_evt_t; |
| |
| btif_hd_cb_t btif_hd_cb; |
| |
| static bthd_callbacks_t* bt_hd_callbacks = NULL; |
| static tBTA_HD_APP_INFO app_info; |
| static tBTA_HD_QOS_INFO in_qos; |
| static tBTA_HD_QOS_INFO out_qos; |
| |
| static void intr_data_copy_cb(uint16_t event, char* p_dst, char* p_src) { |
| tBTA_HD_INTR_DATA* p_dst_data = (tBTA_HD_INTR_DATA*)p_dst; |
| tBTA_HD_INTR_DATA* p_src_data = (tBTA_HD_INTR_DATA*)p_src; |
| uint8_t* p_data; |
| |
| if (!p_src) return; |
| |
| if (event != BTA_HD_INTR_DATA_EVT) return; |
| |
| memcpy(p_dst, p_src, sizeof(tBTA_HD_INTR_DATA)); |
| |
| p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_INTR_DATA); |
| |
| memcpy(p_data, p_src_data->p_data, p_src_data->len); |
| |
| p_dst_data->p_data = p_data; |
| } |
| |
| static void set_report_copy_cb(uint16_t event, char* p_dst, char* p_src) { |
| tBTA_HD_SET_REPORT* p_dst_data = (tBTA_HD_SET_REPORT*)p_dst; |
| tBTA_HD_SET_REPORT* p_src_data = (tBTA_HD_SET_REPORT*)p_src; |
| uint8_t* p_data; |
| |
| if (!p_src) return; |
| |
| if (event != BTA_HD_SET_REPORT_EVT) return; |
| |
| memcpy(p_dst, p_src, sizeof(tBTA_HD_SET_REPORT)); |
| |
| p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_SET_REPORT); |
| |
| memcpy(p_data, p_src_data->p_data, p_src_data->len); |
| |
| p_dst_data->p_data = p_data; |
| } |
| |
| static void btif_hd_free_buf() { |
| if (app_info.descriptor.dsc_list) osi_free(app_info.descriptor.dsc_list); |
| if (app_info.p_description) osi_free(app_info.p_description); |
| if (app_info.p_name) osi_free(app_info.p_name); |
| if (app_info.p_provider) osi_free(app_info.p_provider); |
| app_info.descriptor.dsc_list = NULL; |
| app_info.p_description = NULL; |
| app_info.p_name = NULL; |
| app_info.p_provider = NULL; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function btif_hd_remove_device |
| * |
| * Description Removes plugged device |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| void btif_hd_remove_device(bt_bdaddr_t bd_addr) { |
| BTA_HdRemoveDevice((uint8_t*)&bd_addr); |
| btif_storage_remove_hidd(&bd_addr); |
| } |
| |
| /******************************************************************************* |
| * |
| * Function btif_hd_upstreams_evt |
| * |
| * Description Executes events in btif context |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { |
| tBTA_HD* p_data = (tBTA_HD*)p_param; |
| |
| BTIF_TRACE_API("%s: event=%s", __func__, dump_hd_event(event)); |
| |
| switch (event) { |
| case BTA_HD_ENABLE_EVT: |
| BTIF_TRACE_DEBUG("%s: status=%d", __func__, p_data->status); |
| if (p_data->status == BTA_HD_OK) { |
| btif_storage_load_hidd(); |
| btif_hd_cb.status = BTIF_HD_ENABLED; |
| /* Register the app if not yet registered */ |
| if (!btif_hd_cb.app_registered) { |
| BTA_HdRegisterApp(&app_info, &in_qos, &out_qos); |
| btif_hd_free_buf(); |
| } |
| } else { |
| btif_hd_cb.status = BTIF_HD_DISABLED; |
| BTIF_TRACE_WARNING("Failed to enable BT-HD, status=%d", p_data->status); |
| } |
| break; |
| |
| case BTA_HD_DISABLE_EVT: |
| BTIF_TRACE_DEBUG("%s: status=%d", __func__, p_data->status); |
| btif_hd_cb.status = BTIF_HD_DISABLED; |
| if (btif_hd_cb.service_dereg_active) { |
| BTIF_TRACE_WARNING("registering hid host now"); |
| btif_hh_service_registration(TRUE); |
| btif_hd_cb.service_dereg_active = FALSE; |
| } |
| btif_hd_free_buf(); |
| if (p_data->status == BTA_HD_OK) |
| memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); |
| else |
| BTIF_TRACE_WARNING("Failed to disable BT-HD, status=%d", |
| p_data->status); |
| break; |
| |
| case BTA_HD_REGISTER_APP_EVT: { |
| bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->reg_status.bda; |
| |
| if (!p_data->reg_status.in_use) { |
| addr = NULL; |
| } |
| |
| btif_hd_cb.app_registered = TRUE; |
| HAL_CBACK(bt_hd_callbacks, application_state_cb, addr, |
| BTHD_APP_STATE_REGISTERED); |
| } break; |
| |
| case BTA_HD_UNREGISTER_APP_EVT: |
| btif_hd_cb.app_registered = FALSE; |
| HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL, |
| BTHD_APP_STATE_NOT_REGISTERED); |
| if (btif_hd_cb.service_dereg_active) { |
| BTIF_TRACE_WARNING("disabling hid device service now"); |
| btif_hd_free_buf(); |
| BTA_HdDisable(); |
| } |
| break; |
| |
| case BTA_HD_OPEN_EVT: { |
| bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda; |
| BTIF_TRACE_WARNING( |
| "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]); |
| /* Check if the connection is from hid host and not hid device */ |
| if (check_cod_hid(addr)) { |
| /* Incoming connection from hid device, reject it */ |
| BTIF_TRACE_WARNING("remote device is not hid host, disconnecting"); |
| btif_hd_cb.forced_disc = TRUE; |
| BTA_HdDisconnect(); |
| break; |
| } |
| btif_storage_set_hidd((bt_bdaddr_t*)&p_data->conn.bda); |
| |
| HAL_CBACK(bt_hd_callbacks, connection_state_cb, |
| (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_CONNECTED); |
| } break; |
| |
| case BTA_HD_CLOSE_EVT: |
| if (btif_hd_cb.forced_disc) { |
| bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda; |
| BTIF_TRACE_WARNING("remote device was forcefully disconnected"); |
| btif_hd_remove_device(*addr); |
| btif_hd_cb.forced_disc = FALSE; |
| break; |
| } |
| HAL_CBACK(bt_hd_callbacks, connection_state_cb, |
| (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); |
| break; |
| |
| case BTA_HD_GET_REPORT_EVT: |
| HAL_CBACK(bt_hd_callbacks, get_report_cb, p_data->get_report.report_type, |
| p_data->get_report.report_id, p_data->get_report.buffer_size); |
| break; |
| |
| case BTA_HD_SET_REPORT_EVT: |
| HAL_CBACK(bt_hd_callbacks, set_report_cb, p_data->set_report.report_type, |
| p_data->set_report.report_id, p_data->set_report.len, |
| p_data->set_report.p_data); |
| break; |
| |
| case BTA_HD_SET_PROTOCOL_EVT: |
| HAL_CBACK(bt_hd_callbacks, set_protocol_cb, p_data->set_protocol); |
| break; |
| |
| case BTA_HD_INTR_DATA_EVT: |
| HAL_CBACK(bt_hd_callbacks, intr_data_cb, p_data->intr_data.report_id, |
| p_data->intr_data.len, p_data->intr_data.p_data); |
| break; |
| |
| case BTA_HD_VC_UNPLUG_EVT: |
| HAL_CBACK(bt_hd_callbacks, connection_state_cb, |
| (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); |
| if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) { |
| BTIF_TRACE_DEBUG("%s: Removing bonding as only HID profile connected", |
| __func__); |
| BTA_DmRemoveDevice((uint8_t*)&p_data->conn.bda); |
| } else { |
| bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)&p_data->conn.bda; |
| BTIF_TRACE_DEBUG( |
| "%s: Only removing HID data as some other profiles " |
| "connected", |
| __func__); |
| btif_hd_remove_device(*bd_addr); |
| } |
| HAL_CBACK(bt_hd_callbacks, vc_unplug_cb); |
| break; |
| |
| default: |
| BTIF_TRACE_WARNING("%s: unknown event (%d)", __func__, event); |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| * |
| * Function bte_hd_evt |
| * |
| * Description Switches context from BTE to BTIF 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; |
| tBTIF_COPY_CBACK* p_copy_cback = NULL; |
| |
| BTIF_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) + p_data->set_report.len; |
| p_copy_cback = set_report_copy_cb; |
| 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) + p_data->intr_data.len; |
| p_copy_cback = intr_data_copy_cb; |
| break; |
| } |
| |
| status = btif_transfer_context(btif_hd_upstreams_evt, (uint16_t)event, |
| (char*)p_data, param_len, p_copy_cback); |
| |
| ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); |
| } |
| |
| /******************************************************************************* |
| * |
| * Function init |
| * |
| * Description Initializes BT-HD interface |
| * |
| * Returns BT_STATUS_SUCCESS |
| * |
| ******************************************************************************/ |
| static bt_status_t init(bthd_callbacks_t* callbacks) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| bt_hd_callbacks = callbacks; |
| memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); |
| |
| btif_enable_service(BTA_HIDD_SERVICE_ID); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function cleanup |
| * |
| * Description Cleans up BT-HD interface |
| * |
| * Returns none |
| * |
| ******************************************************************************/ |
| static void cleanup(void) { |
| BTIF_TRACE_API("hd:%s", __func__); |
| |
| if (bt_hd_callbacks) { |
| /* update flag, not to enable hid host service now as BT is switching off */ |
| btif_hd_cb.service_dereg_active = FALSE; |
| btif_disable_service(BTA_HIDD_SERVICE_ID); |
| bt_hd_callbacks = NULL; |
| } |
| } |
| |
| /******************************************************************************* |
| * |
| * Function register_app |
| * |
| * Description Registers HID Device application |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t register_app(bthd_app_param_t* p_app_param, |
| bthd_qos_param_t* p_in_qos, |
| bthd_qos_param_t* p_out_qos) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application already registered", __func__); |
| return BT_STATUS_BUSY; |
| } |
| |
| app_info.p_name = (char*)osi_malloc(BTIF_HD_APP_NAME_LEN); |
| memcpy(app_info.p_name, p_app_param->name, BTIF_HD_APP_NAME_LEN); |
| app_info.p_description = (char*)osi_malloc(BTIF_HD_APP_DESCRIPTION_LEN); |
| memcpy(app_info.p_description, p_app_param->description, |
| BTIF_HD_APP_DESCRIPTION_LEN); |
| app_info.p_provider = (char*)osi_malloc(BTIF_HD_APP_PROVIDER_LEN); |
| memcpy(app_info.p_provider, p_app_param->provider, BTIF_HD_APP_PROVIDER_LEN); |
| app_info.subclass = p_app_param->subclass; |
| app_info.descriptor.dl_len = p_app_param->desc_list_len; |
| app_info.descriptor.dsc_list = |
| (uint8_t*)osi_malloc(app_info.descriptor.dl_len); |
| memcpy(app_info.descriptor.dsc_list, p_app_param->desc_list, |
| p_app_param->desc_list_len); |
| |
| in_qos.service_type = p_in_qos->service_type; |
| in_qos.token_rate = p_in_qos->token_rate; |
| in_qos.token_bucket_size = p_in_qos->token_bucket_size; |
| in_qos.peak_bandwidth = p_in_qos->peak_bandwidth; |
| in_qos.access_latency = p_in_qos->access_latency; |
| in_qos.delay_variation = p_in_qos->delay_variation; |
| |
| out_qos.service_type = p_out_qos->service_type; |
| out_qos.token_rate = p_out_qos->token_rate; |
| out_qos.token_bucket_size = p_out_qos->token_bucket_size; |
| out_qos.peak_bandwidth = p_out_qos->peak_bandwidth; |
| out_qos.access_latency = p_out_qos->access_latency; |
| out_qos.delay_variation = p_out_qos->delay_variation; |
| |
| /* register HID Device with L2CAP and unregister HID Host with L2CAP */ |
| /* Disable HH */ |
| btif_hh_service_registration(FALSE); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function unregister_app |
| * |
| * Description Unregisters HID Device application |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t unregister_app(void) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.service_dereg_active) { |
| BTIF_TRACE_WARNING("%s: BT-HD deregistering in progress", __func__); |
| return BT_STATUS_BUSY; |
| } |
| |
| btif_hd_cb.service_dereg_active = TRUE; |
| BTA_HdUnregisterApp(); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function connect |
| * |
| * Description Connects to host |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t connect(void) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| BTA_HdConnect(); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function disconnect |
| * |
| * Description Disconnects from host |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t disconnect(void) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| BTA_HdDisconnect(); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function send_report |
| * |
| * Description Sends Reports to hid host |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t send_report(bthd_report_type_t type, uint8_t id, |
| uint16_t len, uint8_t* p_data) { |
| tBTA_HD_REPORT report; |
| |
| APPL_TRACE_VERBOSE("%s: type=%d id=%d len=%d", __func__, type, id, len); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (type == BTHD_REPORT_TYPE_INTRDATA) { |
| report.type = BTHD_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); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function report_error |
| * |
| * Description Sends HANDSHAKE with error info for invalid SET_REPORT |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t report_error(uint8_t error) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| BTA_HdReportError(error); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function virtual_cable_unplug |
| * |
| * Description Sends Virtual Cable Unplug to host |
| * |
| * Returns bt_status_t |
| * |
| ******************************************************************************/ |
| static bt_status_t virtual_cable_unplug(void) { |
| BTIF_TRACE_API("%s", __func__); |
| |
| if (!btif_hd_cb.app_registered) { |
| BTIF_TRACE_WARNING("%s: application not yet registered", __func__); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| if (btif_hd_cb.status != BTIF_HD_ENABLED) { |
| BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __func__, |
| btif_hd_cb.status); |
| return BT_STATUS_NOT_READY; |
| } |
| |
| BTA_HdVirtualCableUnplug(); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| static const bthd_interface_t bthdInterface = { |
| sizeof(bthdInterface), |
| init, |
| cleanup, |
| register_app, |
| unregister_app, |
| connect, |
| disconnect, |
| send_report, |
| report_error, |
| virtual_cable_unplug, |
| }; |
| |
| /******************************************************************************* |
| * |
| * Function btif_hd_execute_service |
| * |
| * Description Enabled/disables BT-HD service |
| * |
| * Returns BT_STATUS_SUCCESS |
| * |
| ******************************************************************************/ |
| bt_status_t btif_hd_execute_service(bool b_enable) { |
| BTIF_TRACE_API("%s: b_enable=%d", __func__, b_enable); |
| |
| if (!b_enable) BTA_HdDisable(); |
| |
| return BT_STATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function btif_hd_get_interface |
| * |
| * Description Gets BT-HD interface |
| * |
| * Returns bthd_interface_t |
| * |
| ******************************************************************************/ |
| const bthd_interface_t* btif_hd_get_interface() { |
| BTIF_TRACE_API("%s", __func__); |
| return &bthdInterface; |
| } |
| |
| /******************************************************************************* |
| * |
| * Function btif_hd_service_registration |
| * |
| * Description Registers hid device service |
| * |
| * Returns none |
| * |
| ******************************************************************************/ |
| void btif_hd_service_registration() { |
| BTIF_TRACE_API("%s", __func__); |
| /* enable HD */ |
| BTA_HdEnable(bte_hd_evt); |
| } |