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