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