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