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