Home | History | Annotate | Download | only in hd
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2016 The Android Open Source Project
      4  *  Copyright (C) 2005-2012 Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 /******************************************************************************
     21  *
     22  *  This file contains the HID device action functions.
     23  *
     24  ******************************************************************************/
     25 
     26 #include "bt_target.h"
     27 
     28 #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
     29 
     30 #include <hardware/bluetooth.h>
     31 #include <hardware/bt_hd.h>
     32 #include <string.h>
     33 
     34 #include "bt_utils.h"
     35 #include "bta_hd_int.h"
     36 #include "bta_sys.h"
     37 #include "btm_api.h"
     38 
     39 #include "osi/include/osi.h"
     40 
     41 static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
     42                          uint32_t data, BT_HDR* pdata);
     43 
     44 static bool check_descriptor(uint8_t* data, uint16_t length,
     45                              bool* has_report_id) {
     46   uint8_t* ptr = data;
     47 
     48   *has_report_id = FALSE;
     49 
     50   while (ptr < data + length) {
     51     uint8_t item = *ptr++;
     52 
     53     switch (item) {
     54       case 0xfe:  // long item indicator
     55         if (ptr < data + length) {
     56           ptr += ((*ptr) + 2);
     57         } else {
     58           return false;
     59         }
     60         break;
     61 
     62       case 0x85:  // Report ID
     63         *has_report_id = TRUE;
     64 
     65       default:
     66         ptr += (item & 0x03);
     67         break;
     68     }
     69   }
     70 
     71   return (ptr == data + length);
     72 }
     73 
     74 /*******************************************************************************
     75  *
     76  * Function         bta_hd_api_enable
     77  *
     78  * Description      Enables HID device
     79  *
     80  * Returns          void
     81  *
     82  ******************************************************************************/
     83 void bta_hd_api_enable(tBTA_HD_DATA* p_data) {
     84   tBTA_HD_STATUS status = BTA_HD_ERROR;
     85   tHID_STATUS ret;
     86 
     87   APPL_TRACE_API("%s", __func__);
     88 
     89   HID_DevInit();
     90 
     91   memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
     92 
     93   HID_DevSetSecurityLevel(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
     94 
     95   /* store parameters */
     96   bta_hd_cb.p_cback = p_data->api_enable.p_cback;
     97 
     98   ret = HID_DevRegister(bta_hd_cback);
     99   if (ret == HID_SUCCESS) {
    100     status = BTA_HD_OK;
    101   } else {
    102     APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
    103   }
    104 
    105   /* signal BTA call back event */
    106   (*bta_hd_cb.p_cback)(BTA_HD_ENABLE_EVT, (tBTA_HD*)&status);
    107 }
    108 
    109 /*******************************************************************************
    110  *
    111  * Function         bta_hd_api_disable
    112  *
    113  * Description      Disables HID device
    114  *
    115  * Returns          void
    116  *
    117  ******************************************************************************/
    118 void bta_hd_api_disable(void) {
    119   tBTA_HD_STATUS status = BTA_HD_ERROR;
    120   tHID_STATUS ret;
    121 
    122   APPL_TRACE_API("%s", __func__);
    123 
    124   /* service is not enabled */
    125   if (bta_hd_cb.p_cback == NULL) return;
    126 
    127   /* Remove service record */
    128   if (bta_hd_cb.sdp_handle != 0) {
    129     SDP_DeleteRecord(bta_hd_cb.sdp_handle);
    130     bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
    131   }
    132 
    133   /* Deregister with lower layer */
    134   ret = HID_DevDeregister();
    135   if (ret == HID_SUCCESS) {
    136     status = BTA_HD_OK;
    137   } else {
    138     APPL_TRACE_ERROR("%s: Failed to deregister HID device (%s)", __func__, ret);
    139   }
    140 
    141   (*bta_hd_cb.p_cback)(BTA_HD_DISABLE_EVT, (tBTA_HD*)&status);
    142 
    143   memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
    144 }
    145 
    146 /*******************************************************************************
    147  *
    148  * Function         bta_hd_register_act
    149  *
    150  * Description      Registers SDP record
    151  *
    152  * Returns          void
    153  *
    154  ******************************************************************************/
    155 void bta_hd_register_act(tBTA_HD_DATA* p_data) {
    156   tBTA_HD ret;
    157   tBTA_HD_REGISTER_APP* p_app_data = (tBTA_HD_REGISTER_APP*)p_data;
    158   bool use_report_id = FALSE;
    159 
    160   APPL_TRACE_API("%s", __func__);
    161 
    162   ret.reg_status.in_use = FALSE;
    163 
    164   /* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
    165    * itself is well-formed. Also check if descriptor has Report Id item so we
    166    * know if report will have prefix or not. */
    167   if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
    168       !check_descriptor(p_app_data->d_data, p_app_data->d_len,
    169                         &use_report_id)) {
    170     APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
    171     ret.reg_status.status = BTA_HD_ERROR;
    172     (*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
    173     return;
    174   }
    175 
    176   ret.reg_status.status = BTA_HD_OK;
    177 
    178   /* Remove old record if for some reason it's already registered */
    179   if (bta_hd_cb.sdp_handle != 0) {
    180     SDP_DeleteRecord(bta_hd_cb.sdp_handle);
    181   }
    182 
    183   bta_hd_cb.use_report_id = use_report_id;
    184   bta_hd_cb.sdp_handle = SDP_CreateRecord();
    185   HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name,
    186                    p_app_data->description, p_app_data->provider,
    187                    p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
    188   bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
    189 
    190   HID_DevSetIncomingQos(
    191       p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
    192       p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
    193       p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
    194 
    195   HID_DevSetOutgoingQos(
    196       p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
    197       p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
    198       p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
    199 
    200   // application is registered so we can accept incoming connections
    201   HID_DevSetIncomingPolicy(TRUE);
    202 
    203   if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
    204     ret.reg_status.in_use = TRUE;
    205   }
    206 
    207   (*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
    208 }
    209 
    210 /*******************************************************************************
    211  *
    212  * Function         bta_hd_unregister_act
    213  *
    214  * Description      Unregisters SDP record
    215  *
    216  * Returns          void
    217  *
    218  ******************************************************************************/
    219 void bta_hd_unregister_act(UNUSED_ATTR tBTA_HD_DATA* p_data) {
    220   tBTA_HD_STATUS status = BTA_HD_OK;
    221 
    222   APPL_TRACE_API("%s", __func__);
    223 
    224   // application is no longer registered so we do not want incoming connections
    225   HID_DevSetIncomingPolicy(FALSE);
    226 
    227   if (bta_hd_cb.sdp_handle != 0) {
    228     SDP_DeleteRecord(bta_hd_cb.sdp_handle);
    229   }
    230 
    231   bta_hd_cb.sdp_handle = 0;
    232   bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
    233 
    234   (*bta_hd_cb.p_cback)(BTA_HD_UNREGISTER_APP_EVT, (tBTA_HD*)&status);
    235 }
    236 
    237 /*******************************************************************************
    238  *
    239  * Function         bta_hd_unregister2_act
    240  *
    241  * Description
    242  *
    243  * Returns          void
    244  *
    245  ******************************************************************************/
    246 void bta_hd_unregister2_act(tBTA_HD_DATA* p_data) {
    247   APPL_TRACE_API("%s", __func__);
    248 
    249   // close first
    250   bta_hd_close_act(p_data);
    251 
    252   // then unregister
    253   bta_hd_unregister_act(p_data);
    254 
    255   if (bta_hd_cb.disable_w4_close) {
    256     bta_hd_api_disable();
    257   }
    258 }
    259 
    260 /*******************************************************************************
    261  *
    262  * Function         bta_hd_connect_act
    263  *
    264  * Description      Connect to device (must be virtually plugged)
    265  *
    266  * Returns          void
    267  *
    268  ******************************************************************************/
    269 extern void bta_hd_connect_act(tBTA_HD_DATA* p_data) {
    270   tHID_STATUS ret;
    271   tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
    272   tBTA_HD cback_data;
    273 
    274   APPL_TRACE_API("%s", __func__);
    275 
    276   ret = HID_DevPlugDevice(p_ctrl->addr);
    277   if (ret != HID_SUCCESS) {
    278     APPL_TRACE_WARNING("%s: HID_DevPlugDevice returned %d", __func__, ret);
    279     return;
    280   }
    281 
    282   ret = HID_DevConnect();
    283   if (ret != HID_SUCCESS) {
    284     APPL_TRACE_WARNING("%s: HID_DevConnect returned %d", __func__, ret);
    285     return;
    286   }
    287 
    288   cback_data.conn.bda = p_ctrl->addr;
    289   cback_data.conn.status = BTHD_CONN_STATE_CONNECTING;
    290 
    291   bta_hd_cb.p_cback(BTA_HD_CONN_STATE_EVT, &cback_data);
    292 }
    293 
    294 /*******************************************************************************
    295  *
    296  * Function         bta_hd_disconnect_act
    297  *
    298  * Description      Disconnect from device
    299  *
    300  * Returns          void
    301  *
    302  ******************************************************************************/
    303 extern void bta_hd_disconnect_act(UNUSED_ATTR tBTA_HD_DATA* p_data) {
    304   tHID_STATUS ret;
    305   tBTA_HD cback_data;
    306 
    307   APPL_TRACE_API("%s", __func__);
    308 
    309   ret = HID_DevDisconnect();
    310 
    311   if (ret != HID_SUCCESS) {
    312     APPL_TRACE_WARNING("%s: HID_DevDisconnect returned %d", __func__, ret);
    313     return;
    314   }
    315 
    316   if (HID_DevGetDevice(&cback_data.conn.bda) == HID_SUCCESS) {
    317     cback_data.conn.status = BTHD_CONN_STATE_DISCONNECTING;
    318     bta_hd_cb.p_cback(BTA_HD_CONN_STATE_EVT, &cback_data);
    319   }
    320 }
    321 
    322 /*******************************************************************************
    323  *
    324  * Function         bta_hd_add_device_act
    325  *
    326  * Description
    327  *
    328  * Returns          void
    329  *
    330  ******************************************************************************/
    331 extern void bta_hd_add_device_act(tBTA_HD_DATA* p_data) {
    332   tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
    333 
    334   APPL_TRACE_API("%s", __func__);
    335 
    336   HID_DevPlugDevice(p_ctrl->addr);
    337 }
    338 
    339 /*******************************************************************************
    340  *
    341  * Function         bta_hd_remove_device_act
    342  *
    343  * Description
    344  *
    345  * Returns          void
    346  *
    347  ******************************************************************************/
    348 extern void bta_hd_remove_device_act(tBTA_HD_DATA* p_data) {
    349   tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
    350 
    351   APPL_TRACE_API("%s", __func__);
    352 
    353   HID_DevUnplugDevice(p_ctrl->addr);
    354 }
    355 
    356 /*******************************************************************************
    357  *
    358  * Function         bta_hd_send_report_act
    359  *
    360  * Description      Sends report
    361  *
    362  * Returns          void
    363  *
    364  ******************************************************************************/
    365 extern void bta_hd_send_report_act(tBTA_HD_DATA* p_data) {
    366   tBTA_HD_SEND_REPORT* p_report = (tBTA_HD_SEND_REPORT*)p_data;
    367   uint8_t channel;
    368   uint8_t report_id;
    369 
    370   APPL_TRACE_VERBOSE("%s", __func__);
    371 
    372   channel = p_report->use_intr ? HID_CHANNEL_INTR : HID_CHANNEL_CTRL;
    373   report_id =
    374       (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) ? p_report->id : 0x00;
    375 
    376   HID_DevSendReport(channel, p_report->type, report_id, p_report->len,
    377                     p_report->data);
    378 
    379   /* trigger PM */
    380   bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
    381   bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
    382 }
    383 
    384 /*******************************************************************************
    385  *
    386  * Function         bta_hd_report_error_act
    387  *
    388  * Description
    389  *
    390  * Returns          void
    391  *
    392  ******************************************************************************/
    393 extern void bta_hd_report_error_act(tBTA_HD_DATA* p_data) {
    394   tBTA_HD_REPORT_ERR* p_report = (tBTA_HD_REPORT_ERR*)p_data;
    395   tHID_STATUS ret;
    396 
    397   APPL_TRACE_API("%s: error = %d", __func__, p_report->error);
    398 
    399   ret = HID_DevReportError(p_report->error);
    400 
    401   if (ret != HID_SUCCESS) {
    402     APPL_TRACE_WARNING("%s: HID_DevReportError returned %d", __func__, ret);
    403   }
    404 }
    405 
    406 /*******************************************************************************
    407  *
    408  * Function         bta_hd_vc_unplug_act
    409  *
    410  * Description      Sends Virtual Cable Unplug
    411  *
    412  * Returns          void
    413  *
    414  ******************************************************************************/
    415 extern void bta_hd_vc_unplug_act(UNUSED_ATTR tBTA_HD_DATA* p_data) {
    416   tHID_STATUS ret;
    417 
    418   APPL_TRACE_API("%s", __func__);
    419 
    420   bta_hd_cb.vc_unplug = TRUE;
    421 
    422   ret = HID_DevVirtualCableUnplug();
    423 
    424   if (ret != HID_SUCCESS) {
    425     APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__,
    426                        ret);
    427   }
    428 
    429   /* trigger PM */
    430   bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
    431   bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
    432 }
    433 
    434 /*******************************************************************************
    435  *
    436  * Function         bta_hd_open_act
    437  *
    438  * Description
    439  *
    440  * Returns          void
    441  *
    442  ******************************************************************************/
    443 extern void bta_hd_open_act(tBTA_HD_DATA* p_data) {
    444   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    445   tBTA_HD cback_data;
    446 
    447   APPL_TRACE_API("%s", __func__);
    448 
    449   HID_DevPlugDevice(p_cback->addr);
    450   bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
    451 
    452   cback_data.conn.bda = p_cback->addr;
    453   bta_hd_cb.bd_addr = p_cback->addr;
    454 
    455   bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
    456 }
    457 
    458 /*******************************************************************************
    459  *
    460  * Function         bta_hd_close_act
    461  *
    462  * Description
    463  *
    464  * Returns          void
    465  *
    466  ******************************************************************************/
    467 extern void bta_hd_close_act(tBTA_HD_DATA* p_data) {
    468   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    469   tBTA_HD cback_data;
    470   tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT;
    471 
    472   APPL_TRACE_API("%s", __func__);
    473 
    474   bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
    475 
    476   if (bta_hd_cb.vc_unplug) {
    477     bta_hd_cb.vc_unplug = FALSE;
    478     HID_DevUnplugDevice(p_cback->addr);
    479     cback_event = BTA_HD_VC_UNPLUG_EVT;
    480   }
    481 
    482   cback_data.conn.bda = p_cback->addr;
    483   bta_hd_cb.bd_addr = RawAddress::kEmpty;
    484 
    485   bta_hd_cb.p_cback(cback_event, &cback_data);
    486 }
    487 
    488 /*******************************************************************************
    489  *
    490  * Function         bta_hd_intr_data_act
    491  *
    492  * Description      Handles incoming DATA request on intr
    493  *
    494  * Returns          void
    495  *
    496  ******************************************************************************/
    497 extern void bta_hd_intr_data_act(tBTA_HD_DATA* p_data) {
    498   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    499   BT_HDR* p_msg = p_cback->p_data;
    500   uint16_t len = p_msg->len;
    501   uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
    502   tBTA_HD_INTR_DATA ret;
    503 
    504   APPL_TRACE_API("%s", __func__);
    505 
    506   if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
    507     ret.report_id = *p_buf;
    508 
    509     len--;
    510     p_buf++;
    511   } else {
    512     ret.report_id = 0;
    513   }
    514 
    515   ret.len = len;
    516   ret.p_data = p_buf;
    517 
    518   (*bta_hd_cb.p_cback)(BTA_HD_INTR_DATA_EVT, (tBTA_HD*)&ret);
    519 }
    520 
    521 /*******************************************************************************
    522  *
    523  * Function         bta_hd_get_report_act
    524  *
    525  * Description      Handles incoming GET_REPORT request
    526  *
    527  * Returns          void
    528  *
    529  ******************************************************************************/
    530 extern void bta_hd_get_report_act(tBTA_HD_DATA* p_data) {
    531   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    532   bool rep_size_follows = p_cback->data;
    533   BT_HDR* p_msg = p_cback->p_data;
    534   uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
    535   tBTA_HD_GET_REPORT ret = {0, 0, 0};
    536 
    537   APPL_TRACE_API("%s", __func__);
    538 
    539   ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
    540   p_buf++;
    541 
    542   if (bta_hd_cb.use_report_id) {
    543     ret.report_id = *p_buf;
    544     p_buf++;
    545   }
    546 
    547   if (rep_size_follows) {
    548     ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
    549   }
    550 
    551   (*bta_hd_cb.p_cback)(BTA_HD_GET_REPORT_EVT, (tBTA_HD*)&ret);
    552 }
    553 
    554 /*******************************************************************************
    555  *
    556  * Function         bta_hd_set_report_act
    557  *
    558  * Description      Handles incoming SET_REPORT request
    559  *
    560  * Returns          void
    561  *
    562  ******************************************************************************/
    563 extern void bta_hd_set_report_act(tBTA_HD_DATA* p_data) {
    564   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    565   BT_HDR* p_msg = p_cback->p_data;
    566   uint16_t len = p_msg->len;
    567   uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
    568   tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
    569 
    570   APPL_TRACE_API("%s", __func__);
    571 
    572   ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
    573   p_buf++;
    574   len--;
    575 
    576   if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
    577     ret.report_id = *p_buf;
    578 
    579     len--;
    580     p_buf++;
    581   } else {
    582     ret.report_id = 0;
    583   }
    584 
    585   ret.len = len;
    586   ret.p_data = p_buf;
    587 
    588   (*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, (tBTA_HD*)&ret);
    589 }
    590 
    591 /*******************************************************************************
    592  *
    593  * Function         bta_hd_set_protocol_act
    594  *
    595  * Description
    596  *
    597  * Returns          void
    598  *
    599  ******************************************************************************/
    600 extern void bta_hd_set_protocol_act(tBTA_HD_DATA* p_data) {
    601   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    602   tBTA_HD cback_data;
    603 
    604   APPL_TRACE_API("%s", __func__);
    605 
    606   bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE);
    607   cback_data.set_protocol = p_cback->data;
    608 
    609   (*bta_hd_cb.p_cback)(BTA_HD_SET_PROTOCOL_EVT, &cback_data);
    610 }
    611 
    612 /*******************************************************************************
    613  *
    614  * Function         bta_hd_vc_unplug_done_act
    615  *
    616  * Description
    617  *
    618  * Returns          void
    619  *
    620  ******************************************************************************/
    621 extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA* p_data) {
    622   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    623   tBTA_HD cback_data;
    624 
    625   APPL_TRACE_API("%s", __func__);
    626 
    627   bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
    628 
    629   HID_DevUnplugDevice(p_cback->addr);
    630 
    631   cback_data.conn.bda = p_cback->addr;
    632   bta_hd_cb.bd_addr = p_cback->addr;
    633 
    634   (*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
    635 }
    636 
    637 /*******************************************************************************
    638  *
    639  * Function         bta_hd_suspend_act
    640  *
    641  * Description
    642  *
    643  * Returns          void
    644  *
    645  ******************************************************************************/
    646 extern void bta_hd_suspend_act(tBTA_HD_DATA* p_data) {
    647   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    648 
    649   APPL_TRACE_API("%s", __func__);
    650 
    651   bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
    652 }
    653 
    654 /*******************************************************************************
    655  *
    656  * Function         bta_hd_exit_suspend_act
    657  *
    658  * Description
    659  *
    660  * Returns          void
    661  *
    662  ******************************************************************************/
    663 extern void bta_hd_exit_suspend_act(tBTA_HD_DATA* p_data) {
    664   tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
    665 
    666   APPL_TRACE_API("%s", __func__);
    667 
    668   bta_sys_busy(BTA_ID_HD, 1, p_cback->addr);
    669   bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
    670 }
    671 
    672 /*******************************************************************************
    673  *
    674  * Function         bta_hd_cback
    675  *
    676  * Description      BTA HD callback function
    677  *
    678  * Returns          void
    679  *
    680  ******************************************************************************/
    681 static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
    682                          uint32_t data, BT_HDR* pdata) {
    683   tBTA_HD_CBACK_DATA* p_buf = NULL;
    684   uint16_t sm_event = BTA_HD_INVALID_EVT;
    685 
    686   APPL_TRACE_API("%s: event=%d", __func__, event);
    687 
    688   switch (event) {
    689     case HID_DHOST_EVT_OPEN:
    690       sm_event = BTA_HD_INT_OPEN_EVT;
    691       break;
    692 
    693     case HID_DHOST_EVT_CLOSE:
    694       sm_event = BTA_HD_INT_CLOSE_EVT;
    695       break;
    696 
    697     case HID_DHOST_EVT_GET_REPORT:
    698       sm_event = BTA_HD_INT_GET_REPORT_EVT;
    699       break;
    700 
    701     case HID_DHOST_EVT_SET_REPORT:
    702       sm_event = BTA_HD_INT_SET_REPORT_EVT;
    703       break;
    704 
    705     case HID_DHOST_EVT_SET_PROTOCOL:
    706       sm_event = BTA_HD_INT_SET_PROTOCOL_EVT;
    707       break;
    708 
    709     case HID_DHOST_EVT_INTR_DATA:
    710       sm_event = BTA_HD_INT_INTR_DATA_EVT;
    711       break;
    712 
    713     case HID_DHOST_EVT_VC_UNPLUG:
    714       sm_event = BTA_HD_INT_VC_UNPLUG_EVT;
    715       break;
    716 
    717     case HID_DHOST_EVT_SUSPEND:
    718       sm_event = BTA_HD_INT_SUSPEND_EVT;
    719       break;
    720 
    721     case HID_DHOST_EVT_EXIT_SUSPEND:
    722       sm_event = BTA_HD_INT_EXIT_SUSPEND_EVT;
    723       break;
    724   }
    725 
    726   if (sm_event != BTA_HD_INVALID_EVT &&
    727       (p_buf = (tBTA_HD_CBACK_DATA*)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) +
    728                                                sizeof(BT_HDR))) != NULL) {
    729     p_buf->hdr.event = sm_event;
    730     p_buf->addr = bd_addr;
    731     p_buf->data = data;
    732     p_buf->p_data = pdata;
    733 
    734     bta_sys_sendmsg(p_buf);
    735   }
    736 }
    737 
    738 #endif /* BTA_HD_INCLUDED */
    739