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