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