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