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