• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2005-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the HID host action functions.
22  *
23  ******************************************************************************/
24 
25 #include "bt_target.h"
26 
27 #if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
28 
29 #include <string.h>
30 
31 #include "bta_sys.h"
32 #include "btm_api.h"
33 #include "l2c_api.h"
34 #include "bta_hh_int.h"
35 #include "bta_hh_co.h"
36 
37 /*****************************************************************************
38 **  Constants
39 *****************************************************************************/
40 
41 
42 /*****************************************************************************
43 **  Local Function prototypes
44 *****************************************************************************/
45 static void bta_hh_cback (UINT8 dev_handle, UINT8 event, UINT32 data,
46                           BT_HDR *pdata);
47 static tBTA_HH_STATUS bta_hh_get_trans_status(UINT32 result);
48 
49 #if BTA_HH_DEBUG
50 static char* bta_hh_get_w4_event(UINT16 event);
51 static char * bta_hh_hid_event_name(UINT16 event);
52 #endif
53 
54 /*****************************************************************************
55 **  Action Functions
56 *****************************************************************************/
57 /*******************************************************************************
58 **
59 ** Function         bta_hh_api_enable
60 **
61 ** Description      Perform necessary operations to enable HID host.
62 **
63 **
64 ** Returns          void
65 **
66 *******************************************************************************/
bta_hh_api_enable(tBTA_HH_DATA * p_data)67 void bta_hh_api_enable(tBTA_HH_DATA *p_data)
68 {
69     tBTA_HH_STATUS      status = BTA_HH_ERR;
70     UINT8               xx;
71 
72     /* initialize BTE HID */
73     HID_HostInit();
74 
75     memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
76 
77     HID_HostSetSecurityLevel("", p_data->api_enable.sec_mask);
78 
79     /* Register with L2CAP */
80     if ( HID_HostRegister (bta_hh_cback) == HID_SUCCESS)
81     {
82         /* store parameters */
83         bta_hh_cb.p_cback = p_data->api_enable.p_cback;
84 
85         status = BTA_HH_OK;
86         /* initialize device CB */
87         for (xx = 0; xx < BTA_HH_MAX_KNOWN; xx ++)
88         {
89             bta_hh_cb.kdev[xx].state        = BTA_HH_IDLE_ST;
90             bta_hh_cb.kdev[xx].hid_handle   = BTA_HH_INVALID_HANDLE;
91             bta_hh_cb.kdev[xx].index        = xx;
92             /* initialize control block map */
93             bta_hh_cb.cb_index[xx]          = BTA_HH_MAX_KNOWN;
94         }
95     }
96 
97     /* signal BTA call back event */
98     (* bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH *)&status);
99 }
100 /*******************************************************************************
101 **
102 ** Function         bta_hh_api_disable
103 **
104 ** Description      Perform necessary operations to disable HID host.
105 **
106 **
107 ** Returns          void
108 **
109 *******************************************************************************/
bta_hh_api_disable(void)110 void bta_hh_api_disable(void)
111 {
112     UINT8 xx;
113 
114     /* service is not enabled */
115     if (bta_hh_cb.p_cback == NULL)
116         return;
117 
118     /* no live connection, signal DISC_CMPL_EVT directly */
119     if (!bta_hh_cb.cnt_num)
120     {
121         bta_hh_disc_cmpl();
122     }
123     else /* otherwise, disconnect all live connections */
124     {
125         bta_hh_cb.w4_disable = TRUE;
126 
127         for(xx = 0; xx < BTA_HH_MAX_KNOWN; xx ++)
128         {
129             /* send API_CLOSE event to every connected device */
130             if ( bta_hh_cb.kdev[xx].state == BTA_HH_CONN_ST )
131             {
132                 /* disconnect all connected devices */
133                 bta_hh_sm_execute(&bta_hh_cb.kdev[xx],
134                                 BTA_HH_API_CLOSE_EVT,
135                                 NULL);
136             }
137         }
138     }
139 
140     return;
141 }
142 
143 /*******************************************************************************
144 **
145 ** Function         bta_hh_disc_cmpl
146 **
147 ** Description      All connections have been closed, disable service.
148 **
149 **
150 ** Returns          void
151 **
152 *******************************************************************************/
bta_hh_disc_cmpl(void)153 void bta_hh_disc_cmpl(void)
154 {
155     UINT8   xx;
156     tBTA_HH_STATUS  status = BTA_HH_OK;
157 
158     /* Deregister with lower layer */
159     if (HID_HostDeregister()!= HID_SUCCESS)
160         status = BTA_HH_ERR;
161 
162     /* free buffer in CB holding report descriptors */
163     for(xx = 0; xx < BTA_HH_MAX_KNOWN; xx ++)
164     {
165         utl_freebuf((void **)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
166     }
167     utl_freebuf((void **)&bta_hh_cb.p_disc_db);
168 
169     (* bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH *)&status);
170     /* all connections are down, no waiting for diconnect */
171     memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
172 }
173 /*******************************************************************************
174 **
175 ** Function         bta_hh_sdp_cback
176 **
177 ** Description      SDP callback function.
178 **
179 ** Returns          void
180 **
181 *******************************************************************************/
bta_hh_sdp_cback(UINT16 result,UINT16 attr_mask,tHID_DEV_SDP_INFO * sdp_rec)182 static void bta_hh_sdp_cback(UINT16 result, UINT16 attr_mask,
183                                   tHID_DEV_SDP_INFO *sdp_rec )
184 {
185     tBTA_HH_DEV_CB     *p_cb = bta_hh_cb.p_cur;
186     UINT8              hdl;
187     tBTA_HH_STATUS    status = BTA_HH_ERR_SDP;
188 
189     if (result == SDP_SUCCESS)
190     {
191         /* security is required for the connection, add attr_mask bit*/
192         if (p_cb->sec_mask)
193             attr_mask |= HID_SEC_REQUIRED;
194 
195 #if BTA_HH_DEBUG
196         APPL_TRACE_EVENT3("bta_hh_sdp_cback: p_cb: %d result 0x%02x, \
197                             attr_mask 0x%02x", \
198                             p_cb, result, attr_mask);
199 #endif
200 
201         /* check to see type of device is supported , and should not been added before */
202         if (bta_hh_tod_spt(p_cb, sdp_rec->sub_class))
203         {
204             /* if not added before */
205             if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
206             {
207                 /*  add device/update attr_mask information */
208                 if(HID_HostAddDev (p_cb->addr, attr_mask, &hdl) == HID_SUCCESS)
209                 {
210                     status = BTA_HH_OK;
211                     /* update cb_index[] map */
212                     bta_hh_cb.cb_index[hdl] = p_cb->index;
213                 }
214                 else
215                 {
216                     p_cb->app_id = 0;
217                 }
218             }
219             /* else : incoming connection after SDP should update the SDP information as well */
220 
221             if (p_cb->app_id != 0)
222             {
223                 /* update cb information with attr_mask, dscp_info etc. */
224                 bta_hh_add_device_to_list(p_cb,  hdl, attr_mask,
225                                             &sdp_rec->dscp_info,
226                                             sdp_rec->sub_class,
227                                             sdp_rec->ssr_max_latency,
228                                             sdp_rec->ssr_min_tout,
229                                             p_cb->app_id);
230 
231                 p_cb->dscp_info.ctry_code = sdp_rec->ctry_code;
232 
233                 status = BTA_HH_OK;
234             }
235 
236         }
237         else /* type of device is not supported */
238             status = BTA_HH_ERR_TOD_UNSPT;
239     }
240 
241     /* free disc_db when SDP is completed */
242     utl_freebuf((void **)&bta_hh_cb.p_disc_db);
243 
244 
245     /* send SDP_CMPL_EVT into state machine */
246     bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
247 
248     return;
249 }
250 /*******************************************************************************
251 **
252 ** Function         bta_hh_di_sdp_cback
253 **
254 ** Description      SDP DI callback function.
255 **
256 ** Returns          void
257 **
258 *******************************************************************************/
bta_hh_di_sdp_cback(UINT16 result)259 static void bta_hh_di_sdp_cback(UINT16 result)
260 {
261     tBTA_HH_DEV_CB     *p_cb = bta_hh_cb.p_cur;
262     tBTA_HH_STATUS         status = BTA_HH_ERR_SDP;
263     tSDP_DI_GET_RECORD  di_rec;
264     tHID_STATUS ret;
265 #if BTA_HH_DEBUG
266     APPL_TRACE_EVENT2("bta_hh_di_sdp_cback: p_cb: %d result 0x%02x", p_cb, result);
267 #endif
268     /* if DI record does not exist on remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be
269          * set to 0xffff and we will allow the connection to go through. Spec mandates that DI
270          * record be set, but many HID devices do not set this. So for IOP purposes, we allow the
271          * connection to go through and update the DI record to invalid DI entry.*/
272     if ((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH))
273     {
274         if(result == SDP_SUCCESS && SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0)
275         {
276             /* always update information with primary DI record */
277             if (SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS)
278             {
279                 bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version);
280             }
281 
282         }
283         else /* no DI recrod available */
284         {
285             bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0);
286         }
287 
288         if ((ret = HID_HostGetSDPRecord(p_cb->addr,
289                                  bta_hh_cb.p_disc_db,
290                                  p_bta_hh_cfg->sdp_db_size,
291                                  bta_hh_sdp_cback)) == HID_SUCCESS)
292         {
293             status = BTA_HH_OK;
294         }
295         else
296         {
297 #if BTA_HH_DEBUG
298             APPL_TRACE_DEBUG1 ("bta_hh_di_sdp_cback:  HID_HostGetSDPRecord failed: Status 0x%2x",
299                                ret);
300 #endif
301         }
302     }
303 
304 
305     if (status != BTA_HH_OK)
306     {
307         utl_freebuf((void **)&bta_hh_cb.p_disc_db);
308         /* send SDP_CMPL_EVT into state machine */
309         bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
310     }
311     return;
312 
313 }
314 
315 
316 /*******************************************************************************
317 **
318 ** Function         bta_hh_start_sdp
319 **
320 ** Description      Start SDP service search, and obtain necessary SDP records.
321 **                  Only one SDP service search request is allowed at the same
322 **                  time. For every BTA_HhOpen API call, do SDP first unless SDP
323 **                  has been done previously.
324 **
325 ** Returns          void
326 **
327 *******************************************************************************/
bta_hh_start_sdp(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)328 void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
329 {
330     tBTA_HH_STATUS          status = BTA_HH_ERR_SDP;
331     UINT8                   hdl;
332 
333     p_cb->sec_mask  = p_data->api_conn.sec_mask;
334     p_cb->mode      = p_data->api_conn.mode;
335 
336     /* if previously virtually cabled device, skip SDP */
337     if (p_cb->app_id)
338     {
339         status = BTA_HH_OK;
340 #if BTA_HH_DEBUG
341         APPL_TRACE_DEBUG0("bta_hh_start_sdp:: skip SDP for known devices");
342 #endif
343         if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
344         {
345             if ((HID_HostAddDev (p_cb->addr, p_cb->attr_mask, &hdl)) \
346                 == HID_SUCCESS)
347             {
348                 /* update device CB with newly register device handle */
349                 bta_hh_add_device_to_list(p_cb,  hdl, p_cb->attr_mask, NULL,
350                                           p_cb->sub_class,
351                                           p_cb->dscp_info.ssr_max_latency,
352                                           p_cb->dscp_info.ssr_min_tout,
353                                           p_cb->app_id);
354                 /* update cb_index[] map */
355                 bta_hh_cb.cb_index[hdl] = p_cb->index;
356             }
357             else
358             {
359                 status = BTA_HH_ERR_SDP;
360             }
361         }
362         bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
363 
364         return;
365     }
366     /* GetSDPRecord. at one time only one SDP precedure can be active */
367     else if (!bta_hh_cb.p_disc_db)
368     {
369         bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(p_bta_hh_cfg->sdp_db_size);
370 
371         if (bta_hh_cb.p_disc_db == NULL)
372         {
373             status = BTA_HH_ERR_NO_RES;
374         }
375         else
376         {
377             bta_hh_cb.p_cur = p_cb;
378             /* do DI discovery first */
379             if (SDP_DiDiscover(p_data->api_conn.bd_addr,
380                                          bta_hh_cb.p_disc_db,
381                                          p_bta_hh_cfg->sdp_db_size,
382                                          bta_hh_di_sdp_cback) != SDP_SUCCESS)
383             {
384 #if BTA_HH_DEBUG
385                 APPL_TRACE_DEBUG1 ("bta_hh_start_sdp:  SDP_DiDiscover failed: \
386                     Status 0x%2X",status);
387 #endif
388                 status = BTA_HH_ERR_SDP;
389                 utl_freebuf((void **)&bta_hh_cb.p_disc_db);
390             }
391             else
392                 status = BTA_HH_OK;
393         }
394     }
395 
396     if (status != BTA_HH_OK)
397         bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
398 
399     return;
400 
401 }
402 /*******************************************************************************
403 **
404 ** Function         bta_hh_sdp_cmpl
405 **
406 ** Description      When SDP completed, initiate a connection or report error depend
407 **                  on SDP result.
408 **
409 **
410 ** Returns          void
411 **
412 *******************************************************************************/
bta_hh_sdp_cmpl(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)413 void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
414 {
415     tBTA_HH_CONN            conn_dat;
416     tBTA_HH_STATUS          status = p_data->status;
417 
418 #if BTA_HH_DEBUG
419     APPL_TRACE_DEBUG1 ("bta_hh_sdp_cmpl:  status 0x%2X",p_data->status);
420 #endif
421 
422     /* initialize call back data */
423     memset((void *)&conn_dat, 0, sizeof(tBTA_HH_CONN));
424     conn_dat.handle = p_cb->hid_handle;
425     bdcpy(conn_dat.bda, p_cb->addr);
426 
427     /* if SDP compl success */
428     if ( status == BTA_HH_OK)
429     {
430         /* not incoming connection doing SDP, initiate a HID connection */
431         if (!p_cb->incoming_conn)
432         {
433             tHID_STATUS ret;
434             /* set security level */
435             HID_HostSetSecurityLevel("", p_cb->sec_mask);
436 
437             /* open HID connection */
438             if ((ret = HID_HostOpenDev (p_cb->hid_handle)) != HID_SUCCESS)
439             {
440 #if BTA_HH_DEBUG
441                 APPL_TRACE_DEBUG1 ("bta_hh_sdp_cmpl:  HID_HostOpenDev failed: \
442                     Status 0x%2X",ret);
443 #endif
444                 /* open fail, remove device from management device list */
445                 HID_HostRemoveDev( p_cb->hid_handle);
446                 status = BTA_HH_ERR;
447             }
448             else
449             {
450                 status = BTA_HH_OK;
451             }
452         }
453         else /* incoming connection SDP finish */
454         {
455             bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL);
456         }
457     }
458 
459     if (status != BTA_HH_OK)
460     {
461         conn_dat.status = status;
462 
463         (* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat);
464 
465         /* move state machine W4_CONN ->IDLE */
466         bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
467 
468         /* if this is an outgoing connection to an unknown device, clean up cb */
469         if (p_cb->app_id == 0 && !p_cb->incoming_conn)
470         {
471             /* clean up device control block */
472             bta_hh_clean_up_kdev(p_cb);
473         }
474 
475 #if BTA_HH_DEBUG
476         bta_hh_trace_dev_db();
477 #endif
478     }
479 
480     return;
481 }
482 
483 /*******************************************************************************
484 **
485 ** Function         bta_hh_api_disc_act
486 **
487 ** Description      HID Host initiate a disconnection.
488 **
489 **
490 ** Returns          void
491 **
492 *******************************************************************************/
bta_hh_api_disc_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)493 void bta_hh_api_disc_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
494 {
495     tBTA_HH_CBDATA    disc_dat;
496     tHID_STATUS     status;
497 
498     /* found an active connection */
499     disc_dat.handle = p_data ?(UINT8)p_data->hdr.layer_specific :p_cb->hid_handle;
500     disc_dat.status = BTA_HH_ERR;
501 
502     status = HID_HostCloseDev(disc_dat.handle);
503 
504     if (status)
505         (* bta_hh_cb.p_cback)(BTA_HH_CLOSE_EVT, (tBTA_HH *)&disc_dat);
506 
507     return;
508 }
509 /*******************************************************************************
510 **
511 ** Function         bta_hh_open_cmpl_act
512 **
513 ** Description      HID host connection completed
514 **
515 **
516 ** Returns          void
517 **
518 *******************************************************************************/
bta_hh_open_cmpl_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)519 void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
520 {
521     tBTA_HH_CONN        conn ;
522     UINT8   dev_handle = p_data ? (UINT8)p_data->hid_cback.hdr.layer_specific : \
523                         p_cb->hid_handle;
524 
525     memset((void *)&conn, 0, sizeof (tBTA_HH_CONN));
526     conn.handle = dev_handle;
527     bdcpy(conn.bda, p_cb->addr);
528 
529     /* increase connection number */
530     bta_hh_cb.cnt_num ++;
531 
532     /* initialize device driver */
533     bta_hh_co_open(p_cb->hid_handle, p_cb->sub_class,
534                    p_cb->attr_mask,  p_cb->app_id);
535 
536     /* update SSR settings */
537     bta_sys_chg_ssr_config(BTA_ID_HH ,p_cb->app_id, p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout);
538     /* inform role manager */
539     bta_sys_conn_open( BTA_ID_HH ,p_cb->app_id, p_cb->addr);
540 
541     /* set protocol mode when not default report mode */
542     if (p_cb->mode != BTA_HH_PROTO_RPT_MODE)
543     {
544         if ((HID_HostWriteDev(dev_handle,
545                               HID_TRANS_SET_PROTOCOL, HID_PAR_PROTOCOL_BOOT_MODE,
546                               0,
547                               0, NULL)) != HID_SUCCESS)
548         {
549             /* HID connection is up, while SET_PROTO fail */
550             conn.status = BTA_HH_ERR_PROTO;
551             (* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn);
552         }
553         else
554         {
555             conn.status = BTA_HH_OK;
556             p_cb->w4_evt = BTA_HH_OPEN_EVT;
557         }
558     }
559     else
560         (* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn);
561 
562     p_cb->incoming_conn = FALSE;
563 
564 }
565 /*******************************************************************************
566 **
567 ** Function         bta_hh_open_act
568 **
569 ** Description      HID host receive HID_OPEN_EVT .
570 **
571 **
572 ** Returns          void
573 **
574 *******************************************************************************/
bta_hh_open_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)575 void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
576 {
577     tBTA_HH_API_CONN    conn_data;
578 
579 #if BTA_HH_DEBUG
580     UINT8   dev_handle = p_data ? (UINT8)p_data->hid_cback.hdr.layer_specific : \
581                         p_cb->hid_handle;
582 
583     APPL_TRACE_EVENT1 ("bta_hh_open_act:  Device[%d] connected", dev_handle);
584 #endif
585 
586     /* SDP has been done */
587     if (p_cb->app_id != 0)
588     {
589         bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
590     }
591     else
592     /*  app_id == 0 indicates an incoming conenction request arrives without SDP
593         performed, do it first */
594     {
595         p_cb->incoming_conn = TRUE;
596 
597         memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN));
598         bdcpy(conn_data.bd_addr, p_cb->addr);
599         bta_hh_start_sdp(p_cb, (tBTA_HH_DATA *)&conn_data);
600     }
601 
602     return;
603 }
604 
605 
606 /*******************************************************************************
607 **
608 ** Function         bta_hh_data_act
609 **
610 ** Description      HID Host process a data report
611 **
612 **
613 ** Returns          void
614 **
615 *******************************************************************************/
bta_hh_data_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)616 void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA * p_data)
617 {
618     BT_HDR  *pdata = p_data->hid_cback.p_data;
619     UINT8   *p_rpt = (UINT8 *)(pdata + 1) + pdata->offset;
620 
621     bta_hh_co_data((UINT8)p_data->hid_cback.hdr.layer_specific, p_rpt, pdata->len,
622                     p_cb->mode, p_cb->sub_class, p_cb->dscp_info.ctry_code, p_cb->addr, p_cb->app_id);
623 
624     utl_freebuf((void **)&pdata);
625 }
626 
627 
628 /*******************************************************************************
629 **
630 ** Function         bta_hh_handsk_act
631 **
632 ** Description      HID Host process a handshake acknoledgement.
633 **
634 **
635 ** Returns          void
636 **
637 *******************************************************************************/
bta_hh_handsk_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)638 void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA * p_data)
639 {
640     tBTA_HH_CBDATA  cback_data ;
641     tBTA_HH_HSDATA  hs_data;
642     tBTA_HH_CONN    conn ;
643 
644 #if BTA_HH_DEBUG
645     APPL_TRACE_DEBUG2("HANDSHAKE received for: event = %s data= %d",
646         bta_hh_get_w4_event(p_cb->w4_evt), p_data->hid_cback.data);
647 #endif
648 
649     memset(&hs_data, 0, sizeof(tBTA_HH_HSDATA));
650 
651     switch (p_cb->w4_evt)
652     {
653         /* GET_ transsaction, handshake indicate unsupported request */
654         case BTA_HH_GET_PROTO_EVT:
655             hs_data.rsp_data.proto_mode = BTA_HH_PROTO_UNKNOWN;
656             /* fall through */
657         case BTA_HH_GET_RPT_EVT:
658         case BTA_HH_GET_IDLE_EVT :
659             hs_data.handle = p_cb->hid_handle;
660             /* if handshake gives an OK code for these transaction, fill in UNSUPT */
661             if ((hs_data.status = bta_hh_get_trans_status(p_data->hid_cback.data)) == BTA_HH_OK)
662                  hs_data.status = BTA_HH_HS_TRANS_NOT_SPT;
663 
664             (* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&hs_data);
665             p_cb->w4_evt = 0;
666             break;
667 
668         /* acknoledgement from HID device for SET_ transaction */
669         case BTA_HH_SET_RPT_EVT:
670         case BTA_HH_SET_PROTO_EVT:
671         case BTA_HH_SET_IDLE_EVT :
672             cback_data.handle  = p_cb->hid_handle;
673             cback_data.status = bta_hh_get_trans_status(p_data->hid_cback.data);
674             (* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&cback_data);
675             p_cb->w4_evt = 0;
676             break;
677 
678         /* SET_PROTOCOL when open connection */
679         case BTA_HH_OPEN_EVT:
680             conn.status =p_data->hid_cback.data ? BTA_HH_ERR_PROTO: BTA_HH_OK;
681             conn.handle = p_cb->hid_handle;
682             bdcpy(conn.bda, p_cb->addr);
683             (* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&conn);
684 #if BTA_HH_DEBUG
685             bta_hh_trace_dev_db();
686 #endif
687             p_cb->w4_evt = 0;
688             break;
689 
690         default:
691             /* unknow transaction handshake response */
692             APPL_TRACE_DEBUG0("unknown transaction type");
693             break;
694     }
695 
696     /* transaction achknoledgement received, inform PM for mode change */
697     bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr);
698     return;
699 }
700 /*******************************************************************************
701 **
702 ** Function         bta_hh_ctrl_dat_act
703 **
704 ** Description      HID Host process a data report from control channel.
705 **
706 **
707 ** Returns          void
708 **
709 *******************************************************************************/
bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)710 void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA * p_data)
711 {
712     BT_HDR          *pdata = p_data->hid_cback.p_data;
713     UINT8           *data = (UINT8 *)(pdata + 1) + pdata->offset;
714     tBTA_HH_HSDATA    hs_data;
715 
716 #if BTA_HH_DEBUG
717     APPL_TRACE_DEBUG1("Ctrl DATA received w4: event[%s]",
718                         bta_hh_get_w4_event(p_cb->w4_evt));
719 #endif
720     hs_data.status  = BTA_HH_OK;
721     hs_data.handle  = p_cb->hid_handle;
722 
723     switch (p_cb->w4_evt)
724     {
725     case BTA_HH_GET_IDLE_EVT:
726         hs_data.rsp_data.idle_rate = *data;
727         break;
728     case BTA_HH_GET_RPT_EVT:
729         hs_data.rsp_data.p_rpt_data = pdata;
730         break;
731     case BTA_HH_GET_PROTO_EVT:
732         /* match up BTE/BTA report/boot mode def*/
733         hs_data.rsp_data.proto_mode = ((*data) == HID_PAR_PROTOCOL_REPORT)? \
734                     BTA_HH_PROTO_RPT_MODE : BTA_HH_PROTO_BOOT_MODE;
735 #if BTA_HH_DEBUG
736         APPL_TRACE_DEBUG1("GET_PROTOCOL Mode = [%s]",
737             (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)? "Report" : "Boot");
738 #endif
739         break;
740     /* should not expect control DATA for SET_ transaction */
741     case BTA_HH_SET_PROTO_EVT:
742         /* fall through */
743     case BTA_HH_SET_RPT_EVT:
744         /* fall through */
745     case BTA_HH_SET_IDLE_EVT :
746         /* fall through */
747     default:
748 #if BTA_HH_DEBUG
749         APPL_TRACE_DEBUG1("invalid  transaction type for DATA payload: 4_evt[%s]",
750                         bta_hh_get_w4_event(p_cb->w4_evt));
751 #endif
752         break;
753     }
754 
755     /* inform PM for mode change */
756     bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
757     bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr);
758 
759     (* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&hs_data);
760 
761     p_cb->w4_evt = 0;
762     utl_freebuf((void **)&pdata);
763 
764 }
765 
766 /*******************************************************************************
767 **
768 ** Function         bta_hh_close_act
769 **
770 ** Description      HID Host process a close event
771 **
772 **
773 ** Returns          void
774 **
775 *******************************************************************************/
bta_hh_close_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)776 void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
777 {
778     tBTA_HH_CONN            conn_dat ;
779     tBTA_HH_CBDATA          disc_dat = {BTA_HH_OK, 0};
780     UINT32                  reason = p_data->hid_cback.data;    /* Reason for closing (32-bit) */
781 
782     /* if HID_HDEV_EVT_VC_UNPLUG was received, report BTA_HH_VC_UNPLUG_EVT */
783     UINT16     event = p_cb->vp ? BTA_HH_VC_UNPLUG_EVT : BTA_HH_CLOSE_EVT;
784 
785     disc_dat.handle = p_cb->hid_handle;
786     disc_dat.status = p_data->hid_cback.data;
787 
788     /* Check reason for closing */
789     if ((reason & (HID_L2CAP_CONN_FAIL|HID_L2CAP_REQ_FAIL)) ||  /* Failure to initialize connection (page timeout or l2cap error) */
790         (reason == HID_ERR_AUTH_FAILED) ||                      /* Authenication error (while initiating) */
791         (reason == HID_ERR_L2CAP_FAILED))                       /* Failure creating l2cap connection */
792     {
793         /* Failure in opening connection */
794         conn_dat.handle = p_cb->hid_handle;
795         conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
796         bdcpy(conn_dat.bda, p_cb->addr);
797         HID_HostCloseDev(p_cb->hid_handle);
798 
799         /* Report OPEN fail event */
800         (*bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat);
801 
802 #if BTA_HH_DEBUG
803         bta_hh_trace_dev_db();
804 #endif
805         return;
806     }
807     /* otherwise report CLOSE/VC_UNPLUG event */
808     else
809     {
810         /* finaliza device driver */
811         bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
812         /* inform role manager */
813         bta_sys_conn_close( BTA_ID_HH ,p_cb->app_id, p_cb->addr);
814         /* update total conn number */
815         bta_hh_cb.cnt_num --;
816 
817         if (disc_dat.status)
818             disc_dat.status = BTA_HH_ERR;
819 
820         (*bta_hh_cb.p_cback)(event, (tBTA_HH *)&disc_dat);
821 
822         /* if virtually unplug, remove device */
823         if (p_cb->vp )
824         {
825             HID_HostRemoveDev( p_cb->hid_handle);
826             bta_hh_clean_up_kdev(p_cb);
827         }
828 
829 #if BTA_HH_DEBUG
830         bta_hh_trace_dev_db();
831 #endif
832     }
833 
834     /* clean up control block, but retain SDP info and device handle */
835     p_cb->vp            = FALSE;
836     p_cb->w4_evt        = 0;
837 
838     /* if no connection is active and HH disable is signaled, disable service */
839     if (bta_hh_cb.cnt_num == 0 && bta_hh_cb.w4_disable)
840     {
841         bta_hh_disc_cmpl();
842     }
843 
844     return;
845 }
846 
847 /*******************************************************************************
848 **
849 ** Function         bta_hh_get_dscp_act
850 **
851 ** Description      Get device report descriptor
852 **
853 **
854 ** Returns          void
855 **
856 *******************************************************************************/
bta_hh_get_dscp_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)857 void bta_hh_get_dscp_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
858 {
859     (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH *)&p_cb->dscp_info);
860 }
861 
862 /*******************************************************************************
863 **
864 ** Function         bta_hh_maint_dev_act
865 **
866 ** Description      HID Host maintain device list.
867 **
868 **
869 ** Returns          void
870 **
871 *******************************************************************************/
bta_hh_maint_dev_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)872 void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
873 {
874     tBTA_HH_MAINT_DEV       *p_dev_info = &p_data->api_maintdev;
875     tBTA_HH_DEV_INFO        dev_info ;
876     UINT8                   dev_handle;
877 
878     dev_info.status = BTA_HH_ERR;
879     dev_info.handle = BTA_HH_INVALID_HANDLE;
880 
881     switch (p_dev_info->sub_event)
882     {
883     case BTA_HH_ADD_DEV_EVT:    /* add a device */
884         bdcpy(dev_info.bda, p_dev_info->bda);
885         /* initialize callback data */
886         if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
887         {
888             if (HID_HostAddDev(p_dev_info->bda, p_dev_info->attr_mask, &dev_handle)\
889                             == HID_SUCCESS)
890             {
891                 dev_info.handle   = dev_handle;
892                 dev_info.status   = BTA_HH_OK;
893 
894                 /* update DI information */
895                 bta_hh_update_di_info(p_cb,
896                                       p_dev_info->dscp_info.vendor_id,
897                                       p_dev_info->dscp_info.product_id,
898                                       p_dev_info->dscp_info.version);
899 
900                 /* add to BTA device list */
901                 bta_hh_add_device_to_list(p_cb, dev_handle,
902                                           p_dev_info->attr_mask,
903                                           &p_dev_info->dscp_info.descriptor,
904                                           p_dev_info->sub_class,
905                                           p_dev_info->dscp_info.ssr_max_latency,
906                                           p_dev_info->dscp_info.ssr_min_tout,
907                                           p_dev_info->app_id);
908                 /* update cb_index[] map */
909                 bta_hh_cb.cb_index[dev_handle] = p_cb->index;
910             }
911         }
912         else    /* device already been added */
913         {
914             dev_info.handle = p_cb->hid_handle;
915             dev_info.status = BTA_HH_OK;
916         }
917 #if BTA_HH_DEBUG
918         bta_hh_trace_dev_db();
919 #endif
920         break;
921 
922     case BTA_HH_RMV_DEV_EVT:    /* remove device */
923         dev_info.handle = (UINT8)p_dev_info->hdr.layer_specific;
924 
925         bdcpy(dev_info.bda, p_cb->addr);
926         if (p_cb->state != BTA_HH_CONN_ST )
927         {
928             if(HID_HostRemoveDev( dev_info.handle ) == HID_SUCCESS)
929             {
930                 dev_info.status  = BTA_HH_OK;
931 
932                 /* remove from known device list in BTA */
933                 bta_hh_clean_up_kdev(p_cb);
934             }
935         }
936         break;
937 
938     default:
939         APPL_TRACE_DEBUG0("invalid command");
940         break;
941     }
942 
943     (* bta_hh_cb.p_cback)(p_dev_info->sub_event, (tBTA_HH *)&dev_info);
944 }
945 /*******************************************************************************
946 **
947 ** Function         bta_hh_write_dev_act
948 **
949 ** Description      Write device action. can be SET/GET/DATA transaction.
950 **
951 ** Returns          void
952 **
953 *******************************************************************************/
bta_hh_write_dev_act(tBTA_HH_DEV_CB * p_cb,tBTA_HH_DATA * p_data)954 void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
955 {
956     tBTA_HH_CBDATA     cbdata = {BTA_HH_OK, 0};
957     UINT16  event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
958                         BTA_HH_FST_TRANS_CB_EVT;
959 
960     cbdata.handle = p_cb->hid_handle;
961 
962     /* match up BTE/BTA report/boot mode def */
963     if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL)
964     {
965         p_data->api_sndcmd.param = ( p_data->api_sndcmd.param == BTA_HH_PROTO_RPT_MODE) ?\
966                         HID_PAR_PROTOCOL_REPORT :HID_PAR_PROTOCOL_BOOT_MODE;
967     }
968 
969     if (HID_HostWriteDev (p_cb->hid_handle,
970                        p_data->api_sndcmd.t_type,
971                        p_data->api_sndcmd.param,
972                        p_data->api_sndcmd.data,
973                        p_data->api_sndcmd.rpt_id,
974                        p_data->api_sndcmd.p_data) != HID_SUCCESS)
975     {
976         APPL_TRACE_ERROR0("HID_HostWriteDev Error ");
977         cbdata.status = BTA_HH_ERR;
978 
979         if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL &&
980             p_data->api_sndcmd.t_type != HID_TRANS_DATA)
981             (* bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
982         else if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
983             (* bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, (tBTA_HH *)&cbdata);
984     }
985     else
986     {
987 
988         switch(p_data->api_sndcmd.t_type)
989         {
990         case HID_TRANS_SET_PROTOCOL:
991             /* fall through */
992         case HID_TRANS_GET_REPORT:
993             /* fall through */
994         case HID_TRANS_SET_REPORT:
995             /* fall through */
996         case HID_TRANS_GET_PROTOCOL:
997             /* fall through */
998         case HID_TRANS_GET_IDLE:
999             /* fall through */
1000         case HID_TRANS_SET_IDLE:/* set w4_handsk event name for callback function use */
1001             p_cb->w4_evt = event;
1002             break;
1003         case HID_TRANS_DATA:  /* output report */
1004             /* fall through */
1005         case HID_TRANS_CONTROL:
1006             /* no handshake event will be generated */
1007             /* if VC_UNPLUG is issued, set flag */
1008             if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
1009                 p_cb->vp = TRUE;
1010 
1011             break;
1012         /* currently not expected */
1013         case HID_TRANS_DATAC:
1014         default:
1015             APPL_TRACE_DEBUG1("bta_hh_write_dev_act:: cmd type = %d",
1016                             p_data->api_sndcmd.t_type);
1017             break;
1018         }
1019 
1020         /* if not control type transaction, notify PM for energy control */
1021         if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
1022         {
1023             /* inform PM for mode change */
1024             bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
1025             bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr);
1026         }
1027         else if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND)
1028         {
1029 			bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->addr);
1030         }
1031         else if (p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND)
1032         {
1033             bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
1034         }
1035     }
1036 
1037 
1038     return;
1039 }
1040 
1041 /*****************************************************************************
1042 **  Static Function
1043 *****************************************************************************/
1044 /*******************************************************************************
1045 **
1046 ** Function         bta_hh_cback
1047 **
1048 ** Description      BTA HH callback function.
1049 **
1050 **
1051 ** Returns          void
1052 **
1053 *******************************************************************************/
bta_hh_cback(UINT8 dev_handle,UINT8 event,UINT32 data,BT_HDR * pdata)1054 static void bta_hh_cback (UINT8 dev_handle, UINT8 event, UINT32 data,
1055                           BT_HDR *pdata)
1056 {
1057     tBTA_HH_CBACK_DATA    *p_buf = NULL;
1058     UINT16  sm_event = BTA_HH_INVALID_EVT;
1059     UINT8   xx = 0;
1060 
1061 #if BTA_HH_DEBUG
1062     APPL_TRACE_DEBUG1("bta_hh_cback::HID_event [%s]", bta_hh_hid_event_name(event));
1063 #endif
1064 
1065     switch (event)
1066     {
1067     case HID_HDEV_EVT_OPEN:
1068         sm_event = BTA_HH_INT_OPEN_EVT;
1069         break;
1070     case HID_HDEV_EVT_CLOSE:
1071         sm_event = BTA_HH_INT_CLOSE_EVT;
1072         break;
1073     case HID_HDEV_EVT_INTR_DATA:
1074         sm_event = BTA_HH_INT_DATA_EVT;
1075         break;
1076     case HID_HDEV_EVT_HANDSHAKE:
1077         sm_event = BTA_HH_INT_HANDSK_EVT;
1078         break;
1079     case HID_HDEV_EVT_CTRL_DATA:
1080         sm_event = BTA_HH_INT_CTRL_DATA;
1081         break;
1082     case HID_HDEV_EVT_RETRYING:
1083         break;
1084     case HID_HDEV_EVT_INTR_DATC:
1085     case HID_HDEV_EVT_CTRL_DATC:
1086         /* Unhandled events: Free buffer for DATAC */
1087         utl_freebuf((void **)&pdata);
1088         break;
1089     case HID_HDEV_EVT_VC_UNPLUG:
1090         for (xx = 0; xx < BTA_HH_MAX_KNOWN; xx++)
1091         {
1092             if (bta_hh_cb.kdev[xx].hid_handle == dev_handle)
1093             {
1094                bta_hh_cb.kdev[xx].vp = TRUE;
1095                break;
1096             }
1097         }
1098         break;
1099     }
1100 
1101     if (sm_event != BTA_HH_INVALID_EVT &&
1102         (p_buf = (tBTA_HH_CBACK_DATA *)GKI_getbuf(sizeof(tBTA_HH_CBACK_DATA) +
1103                     sizeof(BT_HDR))) != NULL)
1104     {
1105         p_buf->hdr.event  = sm_event;
1106         p_buf->hdr.layer_specific = (UINT16)dev_handle;
1107         p_buf->data       = data;
1108         p_buf->p_data     = pdata;
1109 
1110         bta_sys_sendmsg(p_buf);
1111     }
1112 
1113 }
1114 /*******************************************************************************
1115 **
1116 ** Function         bta_hh_get_trans_status
1117 **
1118 ** Description      translate a handshake result code into BTA HH
1119 **                  status code
1120 **
1121 *******************************************************************************/
bta_hh_get_trans_status(UINT32 result)1122 static tBTA_HH_STATUS bta_hh_get_trans_status(UINT32 result)
1123 {
1124     switch(result)
1125     {
1126     case HID_PAR_HANDSHAKE_RSP_SUCCESS :                /*   (0) */
1127         return BTA_HH_OK;
1128     case HID_PAR_HANDSHAKE_RSP_NOT_READY :              /*   (1) */
1129     case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID:      /*   (2) */
1130     case HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ :    /*   (3) */
1131     case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM :      /*   (4) */
1132         return (tBTA_HH_STATUS)result;
1133     case HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN :            /*   (14) */
1134     case HID_PAR_HANDSHAKE_RSP_ERR_FATAL  :             /*   (15) */
1135     default:
1136         return BTA_HH_HS_ERROR;
1137         break;
1138     }
1139 }
1140 /*****************************************************************************
1141 **  Debug Functions
1142 *****************************************************************************/
1143 
1144 #if (defined BTA_HH_DEBUG && BTA_HH_DEBUG == TRUE)
bta_hh_get_w4_event(UINT16 event)1145 static char* bta_hh_get_w4_event(UINT16 event)
1146 {
1147     switch (event)
1148     {
1149     case BTA_HH_GET_RPT_EVT:
1150         return "BTA_HH_GET_RPT_EVT";
1151     case BTA_HH_SET_RPT_EVT:
1152         return "BTA_HH_SET_RPT_EVT";
1153     case BTA_HH_GET_PROTO_EVT:
1154         return "BTA_HH_GET_PROTO_EVT";
1155     case BTA_HH_SET_PROTO_EVT:
1156         return "BTA_HH_SET_PROTO_EVT";
1157     case BTA_HH_GET_IDLE_EVT:
1158         return "BTA_HH_GET_IDLE_EVT";
1159     case BTA_HH_SET_IDLE_EVT:
1160         return "BTA_HH_SET_IDLE_EVT";
1161     case BTA_HH_OPEN_EVT:
1162         return "BTA_HH_OPEN_EVT";
1163     default:
1164         return "Unknown event";
1165     }
1166 
1167 }
1168 
bta_hh_hid_event_name(UINT16 event)1169 static char * bta_hh_hid_event_name(UINT16 event)
1170 {
1171     switch (event)
1172     {
1173     case HID_HDEV_EVT_OPEN:
1174         return "HID_HDEV_EVT_OPEN";
1175     case HID_HDEV_EVT_CLOSE:
1176         return "HID_HDEV_EVT_CLOSE";
1177     case HID_HDEV_EVT_RETRYING:
1178         return "HID_HDEV_EVT_RETRYING";
1179     case HID_HDEV_EVT_INTR_DATA:
1180         return "HID_HDEV_EVT_INTR_DATA";
1181     case HID_HDEV_EVT_INTR_DATC:
1182         return "HID_HDEV_EVT_INTR_DATC";
1183     case HID_HDEV_EVT_CTRL_DATA:
1184         return "HID_HDEV_EVT_CTRL_DATA";
1185     case HID_HDEV_EVT_CTRL_DATC:
1186         return "HID_HDEV_EVT_CTRL_DATC";
1187     case HID_HDEV_EVT_HANDSHAKE:
1188         return "HID_HDEV_EVT_HANDSHAKE";
1189     case HID_HDEV_EVT_VC_UNPLUG:
1190         return "HID_HDEV_EVT_VC_UNPLUG";
1191     default:
1192         return "Unknown HID event";
1193     }
1194 }
1195 #endif
1196 #endif /* BTA_HH_INCLUDED */
1197 
1198