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