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