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