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 tBTA_HD cback_data = {0};
426 BD_ADDR plugged_addr = {0};
427
428 APPL_TRACE_API("%s", __func__);
429
430 bta_hd_cb.vc_unplug = TRUE;
431 ret = HID_DevVirtualCableUnplug();
432
433 if (ret == HID_ERR_NO_CONNECTION) {
434 /* This is a local VUP without connection, set the vc_unplug to FALSE */
435 bta_hd_cb.vc_unplug = FALSE;
436 APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret);
437 if (HID_DevGetDevice(&plugged_addr) == HID_SUCCESS) {
438 HID_DevUnplugDevice(plugged_addr);
439 }
440 APPL_TRACE_DEBUG("%s local VUP, remove bda: %02x:%02x:%02x:%02x:%02x:%02x", __func__, plugged_addr[0],
441 plugged_addr[1], plugged_addr[2], plugged_addr[3], plugged_addr[4], plugged_addr[5]);
442 cback_data.conn.status = BTA_HD_OK;
443 cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
444 bta_hd_cb.p_cback(BTA_HD_VC_UNPLUG_EVT, &cback_data);
445 return;
446 } else if (ret != HID_SUCCESS) {
447 APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret);
448 }
449
450 /* trigger PM */
451 bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
452 bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
453 }
454
455 /*******************************************************************************
456 *
457 * Function bta_hd_open_act
458 *
459 * Description
460 *
461 * Returns void
462 *
463 ******************************************************************************/
bta_hd_open_act(tBTA_HD_DATA * p_data)464 extern void bta_hd_open_act(tBTA_HD_DATA *p_data)
465 {
466 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
467 tBTA_HD cback_data;
468
469 APPL_TRACE_API("%s", __func__);
470
471 HID_DevPlugDevice(p_cback->addr);
472 bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
473
474 bdcpy(cback_data.conn.bda, p_cback->addr);
475 bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
476 cback_data.conn.status = BTA_HD_OK;
477 cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTED;
478 bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
479 }
480
481 /*******************************************************************************
482 *
483 * Function bta_hd_close_act
484 *
485 * Description
486 *
487 * Returns void
488 *
489 ******************************************************************************/
bta_hd_close_act(tBTA_HD_DATA * p_data)490 extern void bta_hd_close_act(tBTA_HD_DATA *p_data)
491 {
492 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
493 tBTA_HD cback_data;
494 tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT;
495
496 APPL_TRACE_API("%s", __func__);
497
498 bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
499
500 if (bta_hd_cb.vc_unplug) {
501 bta_hd_cb.vc_unplug = FALSE;
502 HID_DevUnplugDevice(p_cback->addr);
503 cback_event = BTA_HD_VC_UNPLUG_EVT;
504 }
505
506 bdcpy(cback_data.conn.bda, p_cback->addr);
507 memset(bta_hd_cb.bd_addr, 0, sizeof(BD_ADDR));
508 cback_data.conn.status = BTA_HD_OK;
509 cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
510 bta_hd_cb.p_cback(cback_event, &cback_data);
511 }
512
513 /*******************************************************************************
514 *
515 * Function bta_hd_intr_data_act
516 *
517 * Description Handles incoming DATA request on intr
518 *
519 * Returns void
520 *
521 ******************************************************************************/
bta_hd_intr_data_act(tBTA_HD_DATA * p_data)522 extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data)
523 {
524 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
525 BT_HDR *p_msg = p_cback->p_data;
526 uint16_t len = p_msg->len;
527 uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
528 tBTA_HD_INTR_DATA ret;
529
530 APPL_TRACE_API("%s", __func__);
531
532 if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
533 ret.report_id = *p_buf;
534 len--;
535 p_buf++;
536 } else {
537 ret.report_id = 0;
538 }
539
540 ret.len = len;
541 ret.p_data = p_buf;
542 (*bta_hd_cb.p_cback)(BTA_HD_INTR_DATA_EVT, (tBTA_HD *)&ret);
543 if (p_msg) {
544 osi_free(p_msg);
545 }
546 }
547
548 /*******************************************************************************
549 *
550 * Function bta_hd_get_report_act
551 *
552 * Description Handles incoming GET_REPORT request
553 *
554 * Returns void
555 *
556 ******************************************************************************/
bta_hd_get_report_act(tBTA_HD_DATA * p_data)557 extern void bta_hd_get_report_act(tBTA_HD_DATA *p_data)
558 {
559 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
560 bool rep_size_follows = p_cback->data;
561 BT_HDR *p_msg = p_cback->p_data;
562 uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
563 tBTA_HD_GET_REPORT ret = {0, 0, 0};
564 uint16_t remaining_len = p_msg->len;
565
566 APPL_TRACE_API("%s", __func__);
567 if (remaining_len < 1) {
568 APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
569 return;
570 }
571
572 ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
573 p_buf++;
574 remaining_len--;
575
576 if (bta_hd_cb.use_report_id) {
577 if (remaining_len < 1) {
578 APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
579 return;
580 }
581 ret.report_id = *p_buf;
582 p_buf++;
583 remaining_len--;
584 }
585
586 if (rep_size_follows) {
587 if (remaining_len < 2) {
588 APPL_TRACE_ERROR("%s invalid data, remaining_len:%d", __func__, remaining_len);
589 return;
590 }
591 ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
592 }
593
594 (*bta_hd_cb.p_cback)(BTA_HD_GET_REPORT_EVT, (tBTA_HD *)&ret);
595 if (p_msg) {
596 osi_free(p_msg);
597 }
598 }
599
600 /*******************************************************************************
601 *
602 * Function bta_hd_set_report_act
603 *
604 * Description Handles incoming SET_REPORT request
605 *
606 * Returns void
607 *
608 ******************************************************************************/
bta_hd_set_report_act(tBTA_HD_DATA * p_data)609 extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
610 {
611 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
612 BT_HDR *p_msg = p_cback->p_data;
613 uint16_t len = p_msg->len;
614 uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
615 tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
616
617 APPL_TRACE_API("%s", __func__);
618
619 ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
620 p_buf++;
621 len--;
622
623 if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
624 ret.report_id = *p_buf;
625 len--;
626 p_buf++;
627 } else {
628 ret.report_id = 0;
629 }
630
631 ret.len = len;
632 ret.p_data = p_buf;
633 (*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, (tBTA_HD *)&ret);
634 if (p_msg) {
635 osi_free(p_msg);
636 }
637 }
638
639 /*******************************************************************************
640 *
641 * Function bta_hd_set_protocol_act
642 *
643 * Description
644 *
645 * Returns void
646 *
647 ******************************************************************************/
bta_hd_set_protocol_act(tBTA_HD_DATA * p_data)648 extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data)
649 {
650 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
651 tBTA_HD cback_data;
652
653 APPL_TRACE_API("%s", __func__);
654
655 bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE);
656 cback_data.set_protocol = p_cback->data;
657
658 (*bta_hd_cb.p_cback)(BTA_HD_SET_PROTOCOL_EVT, &cback_data);
659 }
660
661 /*******************************************************************************
662 *
663 * Function bta_hd_vc_unplug_done_act
664 *
665 * Description
666 *
667 * Returns void
668 *
669 ******************************************************************************/
bta_hd_vc_unplug_done_act(tBTA_HD_DATA * p_data)670 extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data)
671 {
672 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
673 tBTA_HD cback_data;
674
675 APPL_TRACE_API("%s", __func__);
676
677 bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
678
679 HID_DevUnplugDevice(p_cback->addr);
680
681 bdcpy(cback_data.conn.bda, p_cback->addr);
682 bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
683 cback_data.conn.status = BTA_HD_OK;
684 cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
685 (*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
686 }
687
688 /*******************************************************************************
689 *
690 * Function bta_hd_suspend_act
691 *
692 * Description
693 *
694 * Returns void
695 *
696 ******************************************************************************/
bta_hd_suspend_act(tBTA_HD_DATA * p_data)697 extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data)
698 {
699 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
700
701 APPL_TRACE_API("%s", __func__);
702
703 bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
704 }
705
706 /*******************************************************************************
707 *
708 * Function bta_hd_exit_suspend_act
709 *
710 * Description
711 *
712 * Returns void
713 *
714 ******************************************************************************/
bta_hd_exit_suspend_act(tBTA_HD_DATA * p_data)715 extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data)
716 {
717 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
718
719 APPL_TRACE_API("%s", __func__);
720
721 bta_sys_busy(BTA_ID_HD, 1, p_cback->addr);
722 bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
723 }
724
725 /*******************************************************************************
726 *
727 * Function bta_hd_open_failure
728 *
729 * Description
730 *
731 * Returns void
732 *
733 ******************************************************************************/
bta_hd_open_failure(tBTA_HD_DATA * p_data)734 extern void bta_hd_open_failure(tBTA_HD_DATA *p_data)
735 {
736 tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data;
737 tBTA_HD cback_data = {0};
738
739 bdcpy(cback_data.conn.bda, p_cback->addr);
740 cback_data.conn.status = BTA_HD_ERROR;
741 cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
742 bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
743 }
744
745 /*******************************************************************************
746 *
747 * Function bta_hd_cback
748 *
749 * Description BTA HD callback function
750 *
751 * Returns void
752 *
753 ******************************************************************************/
bta_hd_cback(BD_ADDR bd_addr,uint8_t event,uint32_t data,BT_HDR * pdata)754 static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data, BT_HDR *pdata)
755 {
756 tBTA_HD_CBACK_DATA *p_buf = NULL;
757 uint16_t sm_event = BTA_HD_INVALID_EVT;
758
759 APPL_TRACE_API("%s: event=%d", __func__, event);
760
761 switch (event) {
762 case HID_DHOST_EVT_OPEN:
763 sm_event = BTA_HD_INT_OPEN_EVT;
764 break;
765
766 case HID_DHOST_EVT_CLOSE:
767 sm_event = BTA_HD_INT_CLOSE_EVT;
768 break;
769
770 case HID_DHOST_EVT_GET_REPORT:
771 sm_event = BTA_HD_INT_GET_REPORT_EVT;
772 break;
773
774 case HID_DHOST_EVT_SET_REPORT:
775 sm_event = BTA_HD_INT_SET_REPORT_EVT;
776 break;
777
778 case HID_DHOST_EVT_SET_PROTOCOL:
779 sm_event = BTA_HD_INT_SET_PROTOCOL_EVT;
780 break;
781
782 case HID_DHOST_EVT_INTR_DATA:
783 sm_event = BTA_HD_INT_INTR_DATA_EVT;
784 break;
785
786 case HID_DHOST_EVT_VC_UNPLUG:
787 sm_event = BTA_HD_INT_VC_UNPLUG_EVT;
788 break;
789
790 case HID_DHOST_EVT_SUSPEND:
791 sm_event = BTA_HD_INT_SUSPEND_EVT;
792 break;
793
794 case HID_DHOST_EVT_EXIT_SUSPEND:
795 sm_event = BTA_HD_INT_EXIT_SUSPEND_EVT;
796 break;
797 }
798
799 if (sm_event != BTA_HD_INVALID_EVT &&
800 (p_buf = (tBTA_HD_CBACK_DATA *)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) + sizeof(BT_HDR))) != NULL) {
801 p_buf->hdr.event = sm_event;
802 bdcpy(p_buf->addr, bd_addr);
803 p_buf->data = data;
804 p_buf->p_data = pdata;
805
806 bta_sys_sendmsg(p_buf);
807 }
808 }
809 #endif /* BTA_HD_INCLUDED */
810