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