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