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