1 /******************************************************************************
2  *
3  *  Copyright 2016 The Android Open Source Project
4  *  Copyright 2009-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  *  Filename:      btif_hd.c
23  *
24  *  Description:   HID Device Profile Bluetooth Interface
25  *
26  *
27  ***********************************************************************************/
28 #define LOG_TAG "BTIF_HD"
29 
30 #include "btif/include/btif_hd.h"
31 
32 #include <bluetooth/log.h>
33 
34 #include <cstdint>
35 
36 #include "bta/include/bta_hd_api.h"
37 #include "bta/sys/bta_sys.h"
38 #include "bta_sec_api.h"
39 #include "btif/include/btif_common.h"
40 #include "btif/include/btif_profile_storage.h"
41 #include "btif/include/btif_util.h"
42 #include "include/hardware/bt_hd.h"
43 #include "internal_include/bt_target.h"
44 #include "osi/include/allocator.h"
45 #include "osi/include/compat.h"
46 #include "types/raw_address.h"
47 
48 #define BTIF_HD_APP_NAME_LEN 50
49 #define BTIF_HD_APP_DESCRIPTION_LEN 50
50 #define BTIF_HD_APP_PROVIDER_LEN 50
51 #define BTIF_HD_APP_DESCRIPTOR_LEN 2048
52 
53 #define COD_HID_KEYBOARD 0x0540
54 #define COD_HID_POINTING 0x0580
55 #define COD_HID_COMBO 0x05C0
56 #define COD_HID_MAJOR 0x0500
57 
58 using namespace bluetooth;
59 
60 bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr);
61 bool check_cod_hid(const RawAddress* remote_bdaddr);
62 bool check_cod_hid(const RawAddress& bd_addr);
63 void btif_hh_service_registration(bool enable);
64 
65 /* HD request events */
66 typedef enum { BTIF_HD_DUMMY_REQ_EVT = 0 } btif_hd_req_evt_t;
67 
68 btif_hd_cb_t btif_hd_cb;
69 
70 static bthd_callbacks_t* bt_hd_callbacks = NULL;
71 static tBTA_HD_APP_INFO app_info;
72 static tBTA_HD_QOS_INFO in_qos;
73 static tBTA_HD_QOS_INFO out_qos;
74 
intr_data_copy_cb(uint16_t event,char * p_dst,const char * p_src)75 static void intr_data_copy_cb(uint16_t event, char* p_dst, const char* p_src) {
76   tBTA_HD_INTR_DATA* p_dst_data = (tBTA_HD_INTR_DATA*)p_dst;
77   tBTA_HD_INTR_DATA* p_src_data = (tBTA_HD_INTR_DATA*)p_src;
78   uint8_t* p_data;
79 
80   if (!p_src) return;
81 
82   if (event != BTA_HD_INTR_DATA_EVT) return;
83 
84   memcpy(p_dst, p_src, sizeof(tBTA_HD_INTR_DATA));
85 
86   p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_INTR_DATA);
87 
88   memcpy(p_data, p_src_data->p_data, p_src_data->len);
89 
90   p_dst_data->p_data = p_data;
91 }
92 
set_report_copy_cb(uint16_t event,char * p_dst,const char * p_src)93 static void set_report_copy_cb(uint16_t event, char* p_dst, const char* p_src) {
94   tBTA_HD_SET_REPORT* p_dst_data = (tBTA_HD_SET_REPORT*)p_dst;
95   tBTA_HD_SET_REPORT* p_src_data = (tBTA_HD_SET_REPORT*)p_src;
96   uint8_t* p_data;
97 
98   if (!p_src) return;
99 
100   if (event != BTA_HD_SET_REPORT_EVT) return;
101 
102   memcpy(p_dst, p_src, sizeof(tBTA_HD_SET_REPORT));
103 
104   p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HD_SET_REPORT);
105 
106   memcpy(p_data, p_src_data->p_data, p_src_data->len);
107 
108   p_dst_data->p_data = p_data;
109 }
110 
btif_hd_free_buf()111 static void btif_hd_free_buf() {
112   if (app_info.descriptor.dsc_list) osi_free(app_info.descriptor.dsc_list);
113   if (app_info.p_description) osi_free(app_info.p_description);
114   if (app_info.p_name) osi_free(app_info.p_name);
115   if (app_info.p_provider) osi_free(app_info.p_provider);
116   app_info.descriptor.dsc_list = NULL;
117   app_info.p_description = NULL;
118   app_info.p_name = NULL;
119   app_info.p_provider = NULL;
120 }
121 
122 /*******************************************************************************
123  *
124  * Function         btif_hd_remove_device
125  *
126  * Description      Removes plugged device
127  *
128  * Returns          void
129  *
130  ******************************************************************************/
btif_hd_remove_device(RawAddress bd_addr)131 void btif_hd_remove_device(RawAddress bd_addr) {
132   BTA_HdRemoveDevice(bd_addr);
133   btif_storage_remove_hidd(&bd_addr);
134 }
135 
136 /*******************************************************************************
137  *
138  * Function         btif_hd_upstreams_evt
139  *
140  * Description      Executes events in btif context
141  *
142  * Returns          void
143  *
144  ******************************************************************************/
btif_hd_upstreams_evt(uint16_t event,char * p_param)145 static void btif_hd_upstreams_evt(uint16_t event, char* p_param) {
146   tBTA_HD* p_data = (tBTA_HD*)p_param;
147 
148   log::verbose("event={}", dump_hd_event(event));
149 
150   switch (event) {
151     case BTA_HD_ENABLE_EVT:
152       log::verbose("status={}", p_data->status);
153       if (p_data->status == BTA_HD_OK) {
154         btif_storage_load_hidd();
155         btif_hd_cb.status = BTIF_HD_ENABLED;
156         /* Register the app if not yet registered */
157         if (!btif_hd_cb.app_registered) {
158           BTA_HdRegisterApp(&app_info, &in_qos, &out_qos);
159           btif_hd_free_buf();
160         }
161       } else {
162         btif_hd_cb.status = BTIF_HD_DISABLED;
163         log::warn("Failed to enable BT-HD, status={}", p_data->status);
164       }
165       break;
166 
167     case BTA_HD_DISABLE_EVT:
168       log::verbose("status={}", p_data->status);
169       btif_hd_cb.status = BTIF_HD_DISABLED;
170       if (btif_hd_cb.service_dereg_active) {
171         bta_sys_deregister(BTA_ID_HD);
172         log::warn("registering hid host now");
173         btif_hh_service_registration(TRUE);
174         btif_hd_cb.service_dereg_active = FALSE;
175       }
176       btif_hd_free_buf();
177       if (p_data->status == BTA_HD_OK)
178         memset(&btif_hd_cb, 0, sizeof(btif_hd_cb));
179       else
180         log::warn("Failed to disable BT-HD, status={}", p_data->status);
181       break;
182 
183     case BTA_HD_REGISTER_APP_EVT: {
184       RawAddress* addr = (RawAddress*)&p_data->reg_status.bda;
185 
186       if (!p_data->reg_status.in_use) {
187         addr = NULL;
188       }
189 
190       log::info("Registering HID device app");
191       btif_hd_cb.app_registered = TRUE;
192       HAL_CBACK(bt_hd_callbacks, application_state_cb, addr,
193                 BTHD_APP_STATE_REGISTERED);
194     } break;
195 
196     case BTA_HD_UNREGISTER_APP_EVT:
197       btif_hd_cb.app_registered = FALSE;
198       HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL,
199                 BTHD_APP_STATE_NOT_REGISTERED);
200       if (btif_hd_cb.service_dereg_active) {
201         log::warn("disabling hid device service now");
202         BTA_HdDisable();
203       }
204       break;
205 
206     case BTA_HD_OPEN_EVT: {
207       RawAddress* addr = (RawAddress*)&p_data->conn.bda;
208       log::warn("BTA_HD_OPEN_EVT, address={}", *addr);
209       /* Check if the connection is from hid host and not hid device */
210       if (check_cod_hid(addr)) {
211         /* Incoming connection from hid device, reject it */
212         log::warn("remote device is not hid host, disconnecting");
213         btif_hd_cb.forced_disc = TRUE;
214         BTA_HdDisconnect();
215         break;
216       }
217       btif_storage_set_hidd(p_data->conn.bda);
218 
219       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
220                 (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_CONNECTED);
221     } break;
222 
223     case BTA_HD_CLOSE_EVT:
224       if (btif_hd_cb.forced_disc) {
225         RawAddress* addr = (RawAddress*)&p_data->conn.bda;
226         log::warn("remote device was forcefully disconnected");
227         btif_hd_remove_device(*addr);
228         btif_hd_cb.forced_disc = FALSE;
229         break;
230       }
231       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
232                 (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
233       break;
234 
235     case BTA_HD_GET_REPORT_EVT:
236       HAL_CBACK(bt_hd_callbacks, get_report_cb, p_data->get_report.report_type,
237                 p_data->get_report.report_id, p_data->get_report.buffer_size);
238       break;
239 
240     case BTA_HD_SET_REPORT_EVT:
241       HAL_CBACK(bt_hd_callbacks, set_report_cb, p_data->set_report.report_type,
242                 p_data->set_report.report_id, p_data->set_report.len,
243                 p_data->set_report.p_data);
244       break;
245 
246     case BTA_HD_SET_PROTOCOL_EVT:
247       HAL_CBACK(bt_hd_callbacks, set_protocol_cb, p_data->set_protocol);
248       break;
249 
250     case BTA_HD_INTR_DATA_EVT:
251       HAL_CBACK(bt_hd_callbacks, intr_data_cb, p_data->intr_data.report_id,
252                 p_data->intr_data.len, p_data->intr_data.p_data);
253       break;
254 
255     case BTA_HD_VC_UNPLUG_EVT:
256       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
257                 (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
258       if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) {
259         log::verbose("Removing bonding as only HID profile connected");
260         BTA_DmRemoveDevice(p_data->conn.bda);
261       } else {
262         RawAddress* bd_addr = (RawAddress*)&p_data->conn.bda;
263         log::verbose("Only removing HID data as some other profiles connected");
264         btif_hd_remove_device(*bd_addr);
265       }
266       HAL_CBACK(bt_hd_callbacks, vc_unplug_cb);
267       break;
268 
269     case BTA_HD_CONN_STATE_EVT:
270       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
271                 (RawAddress*)&p_data->conn.bda,
272                 (bthd_connection_state_t)p_data->conn.status);
273       break;
274 
275     default:
276       log::warn("unknown event ({})", event);
277       break;
278   }
279 }
280 
281 /*******************************************************************************
282  *
283  * Function         bte_hd_evt
284  *
285  * Description      Switches context from BTE to BTIF for all BT-HD events
286  *
287  * Returns          void
288  *
289  ******************************************************************************/
290 
bte_hd_evt(tBTA_HD_EVT event,tBTA_HD * p_data)291 static void bte_hd_evt(tBTA_HD_EVT event, tBTA_HD* p_data) {
292   bt_status_t status;
293   int param_len = 0;
294   tBTIF_COPY_CBACK* p_copy_cback = NULL;
295 
296   log::verbose("event={}", event);
297 
298   switch (event) {
299     case BTA_HD_ENABLE_EVT:
300     case BTA_HD_DISABLE_EVT:
301     case BTA_HD_UNREGISTER_APP_EVT:
302       param_len = sizeof(tBTA_HD_STATUS);
303       break;
304 
305     case BTA_HD_REGISTER_APP_EVT:
306       param_len = sizeof(tBTA_HD_REG_STATUS);
307       break;
308 
309     case BTA_HD_OPEN_EVT:
310     case BTA_HD_CLOSE_EVT:
311     case BTA_HD_VC_UNPLUG_EVT:
312     case BTA_HD_CONN_STATE_EVT:
313       param_len = sizeof(tBTA_HD_CONN);
314       break;
315 
316     case BTA_HD_GET_REPORT_EVT:
317       param_len += sizeof(tBTA_HD_GET_REPORT);
318       break;
319 
320     case BTA_HD_SET_REPORT_EVT:
321       param_len = sizeof(tBTA_HD_SET_REPORT) + p_data->set_report.len;
322       p_copy_cback = set_report_copy_cb;
323       break;
324 
325     case BTA_HD_SET_PROTOCOL_EVT:
326       param_len += sizeof(p_data->set_protocol);
327       break;
328 
329     case BTA_HD_INTR_DATA_EVT:
330       param_len = sizeof(tBTA_HD_INTR_DATA) + p_data->intr_data.len;
331       p_copy_cback = intr_data_copy_cb;
332       break;
333   }
334 
335   status = btif_transfer_context(btif_hd_upstreams_evt, (uint16_t)event,
336                                  (char*)p_data, param_len, p_copy_cback);
337 
338   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
339 }
340 
341 /*******************************************************************************
342  *
343  * Function        init
344  *
345  * Description     Initializes BT-HD interface
346  *
347  * Returns         BT_STATUS_SUCCESS
348  *
349  ******************************************************************************/
init(bthd_callbacks_t * callbacks)350 static bt_status_t init(bthd_callbacks_t* callbacks) {
351   log::verbose("");
352 
353   bt_hd_callbacks = callbacks;
354   memset(&btif_hd_cb, 0, sizeof(btif_hd_cb));
355 
356   btif_enable_service(BTA_HIDD_SERVICE_ID);
357 
358   return BT_STATUS_SUCCESS;
359 }
360 
361 /*******************************************************************************
362  *
363  * Function         cleanup
364  *
365  * Description      Cleans up BT-HD interface
366  *
367  * Returns          none
368  *
369  ******************************************************************************/
cleanup(void)370 static void cleanup(void) {
371   log::verbose("");
372 
373   if (bt_hd_callbacks) {
374     /* update flag, not to enable hid host service now as BT is switching off */
375     btif_hd_cb.service_dereg_active = FALSE;
376     btif_disable_service(BTA_HIDD_SERVICE_ID);
377     bt_hd_callbacks = NULL;
378   }
379 }
380 
381 /*******************************************************************************
382  *
383  * Function         register_app
384  *
385  * Description      Registers HID Device application
386  *
387  * Returns          bt_status_t
388  *
389  ******************************************************************************/
register_app(bthd_app_param_t * p_app_param,bthd_qos_param_t * p_in_qos,bthd_qos_param_t * p_out_qos)390 static bt_status_t register_app(bthd_app_param_t* p_app_param,
391                                 bthd_qos_param_t* p_in_qos,
392                                 bthd_qos_param_t* p_out_qos) {
393   log::verbose("");
394 
395   if (btif_hd_cb.app_registered) {
396     log::warn("application already registered");
397     return BT_STATUS_DONE;
398   }
399 
400   app_info.p_name = (char*)osi_calloc(BTIF_HD_APP_NAME_LEN);
401   strlcpy(app_info.p_name, p_app_param->name, BTIF_HD_APP_NAME_LEN);
402   app_info.p_description = (char*)osi_calloc(BTIF_HD_APP_DESCRIPTION_LEN);
403   strlcpy(app_info.p_description, p_app_param->description,
404           BTIF_HD_APP_DESCRIPTION_LEN);
405   app_info.p_provider = (char*)osi_calloc(BTIF_HD_APP_PROVIDER_LEN);
406   strlcpy(app_info.p_provider, p_app_param->provider, BTIF_HD_APP_PROVIDER_LEN);
407   app_info.subclass = p_app_param->subclass;
408   app_info.descriptor.dl_len = p_app_param->desc_list_len;
409   app_info.descriptor.dsc_list =
410       (uint8_t*)osi_malloc(app_info.descriptor.dl_len);
411   memcpy(app_info.descriptor.dsc_list, p_app_param->desc_list,
412          p_app_param->desc_list_len);
413 
414   in_qos.service_type = p_in_qos->service_type;
415   in_qos.token_rate = p_in_qos->token_rate;
416   in_qos.token_bucket_size = p_in_qos->token_bucket_size;
417   in_qos.peak_bandwidth = p_in_qos->peak_bandwidth;
418   in_qos.access_latency = p_in_qos->access_latency;
419   in_qos.delay_variation = p_in_qos->delay_variation;
420 
421   out_qos.service_type = p_out_qos->service_type;
422   out_qos.token_rate = p_out_qos->token_rate;
423   out_qos.token_bucket_size = p_out_qos->token_bucket_size;
424   out_qos.peak_bandwidth = p_out_qos->peak_bandwidth;
425   out_qos.access_latency = p_out_qos->access_latency;
426   out_qos.delay_variation = p_out_qos->delay_variation;
427 
428   /* register HID Device with L2CAP and unregister HID Host with L2CAP */
429   /* Disable HH */
430   btif_hh_service_registration(FALSE);
431 
432   return BT_STATUS_SUCCESS;
433 }
434 
435 /*******************************************************************************
436  *
437  * Function         unregister_app
438  *
439  * Description      Unregisters HID Device application
440  *
441  * Returns          bt_status_t
442  *
443  ******************************************************************************/
unregister_app(void)444 static bt_status_t unregister_app(void) {
445   log::verbose("");
446 
447   if (!btif_hd_cb.app_registered) {
448     log::warn("application not yet registered");
449     return BT_STATUS_NOT_READY;
450   }
451 
452   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
453     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
454     return BT_STATUS_NOT_READY;
455   }
456 
457   if (btif_hd_cb.service_dereg_active) {
458     log::warn("BT-HD deregistering in progress");
459     return BT_STATUS_BUSY;
460   }
461 
462   btif_hd_cb.service_dereg_active = TRUE;
463   BTA_HdUnregisterApp();
464 
465   return BT_STATUS_SUCCESS;
466 }
467 
468 /*******************************************************************************
469  *
470  * Function         connect
471  *
472  * Description      Connects to host
473  *
474  * Returns          bt_status_t
475  *
476  ******************************************************************************/
connect(RawAddress * bd_addr)477 static bt_status_t connect(RawAddress* bd_addr) {
478   log::verbose("");
479 
480   if (!btif_hd_cb.app_registered) {
481     log::warn("application not yet registered");
482     return BT_STATUS_NOT_READY;
483   }
484 
485   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
486     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
487     return BT_STATUS_NOT_READY;
488   }
489 
490   BTA_HdConnect(*bd_addr);
491 
492   return BT_STATUS_SUCCESS;
493 }
494 
495 /*******************************************************************************
496  *
497  * Function         disconnect
498  *
499  * Description      Disconnects from host
500  *
501  * Returns          bt_status_t
502  *
503  ******************************************************************************/
disconnect(void)504 static bt_status_t disconnect(void) {
505   log::verbose("");
506 
507   if (!btif_hd_cb.app_registered) {
508     log::warn("application not yet registered");
509     return BT_STATUS_NOT_READY;
510   }
511 
512   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
513     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
514     return BT_STATUS_NOT_READY;
515   }
516 
517   BTA_HdDisconnect();
518 
519   return BT_STATUS_SUCCESS;
520 }
521 
522 /*******************************************************************************
523  *
524  * Function         send_report
525  *
526  * Description      Sends Reports to hid host
527  *
528  * Returns          bt_status_t
529  *
530  ******************************************************************************/
send_report(bthd_report_type_t type,uint8_t id,uint16_t len,uint8_t * p_data)531 static bt_status_t send_report(bthd_report_type_t type, uint8_t id,
532                                uint16_t len, uint8_t* p_data) {
533   tBTA_HD_REPORT report;
534 
535   log::verbose("type={} id={} len={}", type, id, len);
536 
537   if (!btif_hd_cb.app_registered) {
538     log::warn("application not yet registered");
539     return BT_STATUS_NOT_READY;
540   }
541 
542   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
543     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
544     return BT_STATUS_NOT_READY;
545   }
546 
547   if (type == BTHD_REPORT_TYPE_INTRDATA) {
548     report.type = BTHD_REPORT_TYPE_INPUT;
549     report.use_intr = TRUE;
550   } else {
551     report.type = (type & 0x03);
552     report.use_intr = FALSE;
553   }
554 
555   report.id = id;
556   report.len = len;
557   report.p_data = p_data;
558 
559   BTA_HdSendReport(&report);
560 
561   return BT_STATUS_SUCCESS;
562 }
563 
564 /*******************************************************************************
565  *
566  * Function         report_error
567  *
568  * Description      Sends HANDSHAKE with error info for invalid SET_REPORT
569  *
570  * Returns          bt_status_t
571  *
572  ******************************************************************************/
report_error(uint8_t error)573 static bt_status_t report_error(uint8_t error) {
574   log::verbose("");
575 
576   if (!btif_hd_cb.app_registered) {
577     log::warn("application not yet registered");
578     return BT_STATUS_NOT_READY;
579   }
580 
581   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
582     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
583     return BT_STATUS_NOT_READY;
584   }
585 
586   BTA_HdReportError(error);
587 
588   return BT_STATUS_SUCCESS;
589 }
590 
591 /*******************************************************************************
592  *
593  * Function         virtual_cable_unplug
594  *
595  * Description      Sends Virtual Cable Unplug to host
596  *
597  * Returns          bt_status_t
598  *
599  ******************************************************************************/
virtual_cable_unplug(void)600 static bt_status_t virtual_cable_unplug(void) {
601   log::verbose("");
602 
603   if (!btif_hd_cb.app_registered) {
604     log::warn("application not yet registered");
605     return BT_STATUS_NOT_READY;
606   }
607 
608   if (btif_hd_cb.status != BTIF_HD_ENABLED) {
609     log::warn("BT-HD not enabled, status={}", btif_hd_cb.status);
610     return BT_STATUS_NOT_READY;
611   }
612 
613   BTA_HdVirtualCableUnplug();
614 
615   return BT_STATUS_SUCCESS;
616 }
617 
618 static const bthd_interface_t bthdInterface = {
619     sizeof(bthdInterface),
620     init,
621     cleanup,
622     register_app,
623     unregister_app,
624     connect,
625     disconnect,
626     send_report,
627     report_error,
628     virtual_cable_unplug,
629 };
630 
631 /*******************************************************************************
632  *
633  * Function         btif_hd_execute_service
634  *
635  * Description      Enabled/disables BT-HD service
636  *
637  * Returns          BT_STATUS_SUCCESS
638  *
639  ******************************************************************************/
btif_hd_execute_service(bool b_enable)640 bt_status_t btif_hd_execute_service(bool b_enable) {
641   log::verbose("b_enable={}", b_enable);
642 
643   if (!b_enable) BTA_HdDisable();
644 
645   return BT_STATUS_SUCCESS;
646 }
647 
648 /*******************************************************************************
649  *
650  * Function         btif_hd_get_interface
651  *
652  * Description      Gets BT-HD interface
653  *
654  * Returns          bthd_interface_t
655  *
656  ******************************************************************************/
btif_hd_get_interface()657 const bthd_interface_t* btif_hd_get_interface() {
658   log::verbose("");
659   return &bthdInterface;
660 }
661 
662 /*******************************************************************************
663  *
664  * Function         btif_hd_service_registration
665  *
666  * Description      Registers hid device service
667  *
668  * Returns          none
669  *
670  ******************************************************************************/
btif_hd_service_registration()671 void btif_hd_service_registration() {
672   log::verbose("");
673   /* enable HD */
674   if (bt_hd_callbacks != NULL) {
675     BTA_HdEnable(bte_hd_evt);
676   }
677 }
678