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 main functions and state machine.
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_hh_api.h"
32#include "bta_hh_int.h"
33#include "gki.h"
34
35/*****************************************************************************
36** Constants and types
37*****************************************************************************/
38
39/* state machine action enumeration list */
40enum
41{
42    BTA_HH_API_DISC_ACT,        /* HID host process API close action    */
43    BTA_HH_OPEN_ACT,            /* HID host process BTA_HH_EVT_OPEN     */
44    BTA_HH_CLOSE_ACT,           /* HID host process BTA_HH_EVT_CLOSE    */
45    BTA_HH_DATA_ACT,            /* HID host receive data report         */
46    BTA_HH_CTRL_DAT_ACT,
47    BTA_HH_HANDSK_ACT,
48    BTA_HH_START_SDP,           /* HID host inquery                     */
49    BTA_HH_SDP_CMPL,
50    BTA_HH_WRITE_DEV_ACT,
51    BTA_HH_GET_DSCP_ACT,
52    BTA_HH_MAINT_DEV_ACT,
53    BTA_HH_OPEN_CMPL_ACT,
54    BTA_HH_OPEN_FAILURE,
55#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
56    BTA_HH_GATT_CLOSE,
57    BTA_HH_LE_OPEN_FAIL,
58    BTA_HH_GATT_OPEN,
59    BTA_HH_W4_LE_READ_CHAR,
60    BTA_HH_LE_READ_CHAR,
61    BTA_HH_W4_LE_READ_DESCR,
62    BTA_HH_LE_READ_DESCR,
63    BTA_HH_W4_LE_WRITE,
64    BTA_HH_LE_WRITE,
65    BTA_HH_WRITE_DESCR,
66    BTA_HH_START_SEC,
67    BTA_HH_SEC_CMPL,
68    BTA_HH_LE_UPDATE_SCPP,
69    BTA_HH_GATT_ENC_CMPL,
70#endif
71    BTA_HH_NUM_ACTIONS
72};
73
74#define BTA_HH_IGNORE       BTA_HH_NUM_ACTIONS
75
76/* type for action functions */
77typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
78
79/* action functions */
80const tBTA_HH_ACTION bta_hh_action[] =
81{
82    bta_hh_api_disc_act,
83    bta_hh_open_act,
84    bta_hh_close_act,
85    bta_hh_data_act,
86    bta_hh_ctrl_dat_act,
87    bta_hh_handsk_act,
88    bta_hh_start_sdp,
89    bta_hh_sdp_cmpl,
90    bta_hh_write_dev_act,
91    bta_hh_get_dscp_act,
92    bta_hh_maint_dev_act,
93    bta_hh_open_cmpl_act,
94    bta_hh_open_failure
95#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
96    ,bta_hh_gatt_close
97    ,bta_hh_le_open_fail
98    ,bta_hh_gatt_open
99    ,bta_hh_w4_le_read_char_cmpl
100    ,bta_hh_le_read_char_cmpl
101    ,bta_hh_w4_le_read_descr_cmpl
102    ,bta_hh_le_read_descr_cmpl
103    ,bta_hh_w4_le_write_cmpl
104    ,bta_hh_le_write_cmpl
105    ,bta_hh_le_write_char_descr_cmpl
106    ,bta_hh_start_security
107    ,bta_hh_security_cmpl
108    ,bta_hh_le_update_scpp
109    ,bta_hh_le_notify_enc_cmpl
110#endif
111};
112
113/* state table information */
114#define BTA_HH_ACTION                   0       /* position of action */
115#define BTA_HH_NEXT_STATE               1       /* position of next state */
116#define BTA_HH_NUM_COLS                 2       /* number of columns */
117
118/* state table for idle state */
119const UINT8 bta_hh_st_idle[][BTA_HH_NUM_COLS] =
120{
121/* Event                          Action                    Next state */
122/* BTA_HH_API_OPEN_EVT      */    {BTA_HH_START_SDP,     BTA_HH_W4_CONN_ST },
123/* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
124/* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_W4_CONN_ST },
125/* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_CLOSE_ACT,     BTA_HH_IDLE_ST    },
126/* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
127/* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
128/* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
129/* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
130/* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
131/* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
132/* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST    },
133/* BTA_HH_OPEN_CMPL_EVT        */  {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST    }
134#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
135/* BTA_HH_GATT_CLOSE_EVT    */   ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
136/* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_GATT_OPEN,      BTA_HH_W4_CONN_ST }
137/* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
138/* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
139/* READ_CHAR_CMPL_EVT */         ,{BTA_HH_IGNORE,       BTA_HH_IDLE_ST  }
140/* BTA_HH_GATT_WRITE_CMPL_EVT*/    ,{BTA_HH_IGNORE,       BTA_HH_IDLE_ST  }
141/* READ_DESCR_CMPL_EVT */        ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST  }
142/* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
143/* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
144/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
145#endif
146
147};
148
149
150const UINT8 bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] =
151{
152/* Event                          Action                 Next state */
153/* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
154/* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
155/* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_W4_CONN_ST },
156/* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_OPEN_FAILURE,  BTA_HH_IDLE_ST    },
157/* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
158/* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
159/* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
160/* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_SDP_CMPL,      BTA_HH_W4_CONN_ST },
161/* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
162/* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
163/* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST    },
164/* BTA_HH_OPEN_CMPL_EVT     */    {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST    }
165#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
166/* BTA_HH_GATT_CLOSE_EVT    */   ,{BTA_HH_LE_OPEN_FAIL,  BTA_HH_IDLE_ST    }
167/* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_GATT_OPEN,     BTA_HH_W4_CONN_ST }
168/* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_START_SEC,     BTA_HH_W4_SEC     }
169/* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST }
170/* READ_CHAR_CMPL_EVT */        ,{BTA_HH_W4_LE_READ_CHAR,    BTA_HH_W4_CONN_ST  }
171/* BTA_HH_GATT_WRITE_CMPL_EVT*/  ,{BTA_HH_W4_LE_WRITE,    BTA_HH_W4_CONN_ST  }
172/* READ_DESCR_CMPL_EVT */        ,{BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST  }
173/* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_W4_CONN_ST   }
174/* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_W4_CONN_ST   }
175/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST }
176#endif
177};
178
179
180const UINT8 bta_hh_st_connected[][BTA_HH_NUM_COLS] =
181{
182/* Event                          Action                 Next state */
183/* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_CONN_ST    },
184/* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_API_DISC_ACT,  BTA_HH_CONN_ST    },
185/* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_CONN_ST    },
186/* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_CLOSE_ACT,     BTA_HH_IDLE_ST    },
187/* BTA_HH_INT_DATA_EVT      */    {BTA_HH_DATA_ACT,      BTA_HH_CONN_ST    },
188/* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_CTRL_DAT_ACT,  BTA_HH_CONN_ST    },
189/* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_HANDSK_ACT,    BTA_HH_CONN_ST    },
190/* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,         BTA_HH_CONN_ST       },
191/* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST    },
192/* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_GET_DSCP_ACT,  BTA_HH_CONN_ST    },
193/* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST    },
194/* BTA_HH_OPEN_CMPL_EVT        */    {BTA_HH_IGNORE,         BTA_HH_CONN_ST    }
195#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
196/* BTA_HH_GATT_CLOSE_EVT    */    ,{BTA_HH_GATT_CLOSE,    BTA_HH_IDLE_ST    }
197/* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST    }
198/* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
199/* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
200/* READ_CHAR_CMPL_EVT */         ,{BTA_HH_LE_READ_CHAR,  BTA_HH_CONN_ST     }
201/* WRITE_CHAR_CMPL_EVT*/         ,{BTA_HH_LE_WRITE,      BTA_HH_CONN_ST     }
202/* READ_DESCR_CMPL_EVT */        ,{BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST     }   /* do not currently read any descr when connection up */
203/* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_CONN_ST     }   /* do not currently write any descr when connection up */
204/* SCPP_UPDATE_EVT */            ,{BTA_HH_LE_UPDATE_SCPP,  BTA_HH_CONN_ST   }
205/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
206#endif
207};
208#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
209const UINT8 bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] =
210{
211/* Event                          Action                 Next state */
212/* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
213/* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_API_DISC_ACT,  BTA_HH_W4_SEC  },
214/* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
215/* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_OPEN_FAILURE,  BTA_HH_IDLE_ST },
216/* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
217/* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
218/* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
219/* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
220/* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_IGNORE  ,      BTA_HH_W4_SEC  },
221/* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
222/* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC  },
223/* BTA_HH_OPEN_CMPL_EVT     */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
224/* BTA_HH_GATT_CLOSE_EVT    */    {BTA_HH_LE_OPEN_FAIL,  BTA_HH_IDLE_ST },
225/* BTA_HH_GATT_OPEN_EVT    */     {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
226/* BTA_HH_START_ENC_EVT    */     {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
227/* BTA_HH_ENC_CMPL_EVT     */     {BTA_HH_SEC_CMPL,      BTA_HH_W4_CONN_ST },
228/* READ_CHAR_CMPL_EVT */          {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
229/* BTA_HH_GATT_WRITE_CMPL_EVT*/   {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
230/* READ_DESCR_CMPL_EVT */         {BTA_HH_IGNORE,        BTA_HH_W4_SEC   },
231/* WRITE_DESCR_CMPL_EVT */        {BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
232/* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
233/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC   }
234};
235#endif
236
237/* type for state table */
238typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
239
240/* state table */
241const tBTA_HH_ST_TBL bta_hh_st_tbl[] =
242{
243    bta_hh_st_idle,
244    bta_hh_st_w4_conn,
245    bta_hh_st_connected
246#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
247    ,bta_hh_st_w4_sec
248#endif
249};
250
251/*****************************************************************************
252** Global data
253*****************************************************************************/
254#if BTA_DYNAMIC_MEMORY == FALSE
255tBTA_HH_CB  bta_hh_cb;
256#endif
257/*****************************************************************************
258** Static functions
259*****************************************************************************/
260#if BTA_HH_DEBUG == TRUE
261static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
262static char *bta_hh_state_code(tBTA_HH_STATE state_code);
263#endif
264
265/*******************************************************************************
266**
267** Function         bta_hh_sm_execute
268**
269** Description      State machine event handling function for HID Host
270**
271**
272** Returns          void
273**
274*******************************************************************************/
275void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA * p_data)
276{
277    tBTA_HH_ST_TBL  state_table;
278    UINT8           action;
279    tBTA_HH         cback_data;
280    tBTA_HH_EVT     cback_event = 0;
281#if BTA_HH_DEBUG == TRUE
282    tBTA_HH_STATE   in_state ;
283    UINT16          debug_event = event;
284#endif
285
286    memset(&cback_data, 0, sizeof(tBTA_HH));
287
288    /* handle exception, no valid control block was found */
289    if (!p_cb)
290    {
291        /* BTA HH enabled already? otherwise ignore the event although it's bad*/
292        if (bta_hh_cb.p_cback != NULL)
293        {
294            switch (event)
295            {
296            /* no control block available for new connection */
297            case BTA_HH_API_OPEN_EVT:
298                cback_event = BTA_HH_OPEN_EVT;
299                /* build cback data */
300                bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
301                cback_data.conn.status  = BTA_HH_ERR_DB_FULL;
302                cback_data.conn.handle  = BTA_HH_INVALID_HANDLE;
303                break;
304            /* DB full, BTA_HhAddDev */
305            case BTA_HH_API_MAINT_DEV_EVT:
306                cback_event = p_data->api_maintdev.sub_event;
307
308                if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT)
309                {
310                    bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
311                    cback_data.dev_info.status    = BTA_HH_ERR_DB_FULL;
312                    cback_data.dev_info.handle    = BTA_HH_INVALID_HANDLE;
313                }
314                else
315                {
316                    cback_data.dev_info.status    = BTA_HH_ERR_HDL;
317                    cback_data.dev_info.handle    = (UINT8)p_data->api_maintdev.hdr.layer_specific;
318                }
319                break;
320            case BTA_HH_API_WRITE_DEV_EVT:
321                cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
322                        BTA_HH_FST_TRANS_CB_EVT;
323                if (p_data->api_sndcmd.p_data != NULL)
324                {
325                    GKI_freebuf(p_data->api_sndcmd.p_data);
326                }
327                if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
328                    p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
329                    p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE)
330                {
331                    cback_data.dev_status.status = BTA_HH_ERR_HDL;
332                    cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
333                }
334                else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
335                    p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
336                {
337                    cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
338                    cback_data.hs_data.status = BTA_HH_ERR_HDL;
339                    /* hs_data.rsp_data will be all zero, which is not valid value */
340                }
341                else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
342                         p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
343                {
344                    cback_data.status = BTA_HH_ERR_HDL;
345                    cback_event = BTA_HH_VC_UNPLUG_EVT;
346                }
347                else
348                    cback_event = 0;
349                break;
350
351            case BTA_HH_API_CLOSE_EVT:
352                cback_event = BTA_HH_CLOSE_EVT;
353
354                cback_data.dev_status.status = BTA_HH_ERR_HDL;
355                cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
356                break;
357
358            default:
359                /* invalid handle, call bad API event */
360                APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
361                /* Free the callback buffer now */
362                if (p_data != NULL && p_data->hid_cback.p_data != NULL)
363                {
364                    GKI_freebuf(p_data->hid_cback.p_data);
365                    p_data->hid_cback.p_data = NULL;
366                }
367                break;
368            }
369           if (cback_event)
370               (* bta_hh_cb.p_cback)(cback_event, &cback_data);
371        }
372    }
373    /* corresponding CB is found, go to state machine */
374    else
375    {
376#if BTA_HH_DEBUG == TRUE
377        in_state = p_cb->state;
378        APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
379                          in_state, bta_hh_state_code(in_state),
380                          bta_hh_evt_code(debug_event));
381#endif
382
383        if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST))
384        {
385            APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
386                              p_cb->state,event);
387            return;
388        }
389        state_table = bta_hh_st_tbl[p_cb->state - 1];
390
391        event &= 0xff;
392
393        p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
394
395        if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE)
396        {
397            (*bta_hh_action[action])(p_cb, p_data);
398        }
399
400#if BTA_HH_DEBUG == TRUE
401        if (in_state != p_cb->state)
402        {
403            APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
404                          bta_hh_state_code(in_state),
405                          bta_hh_state_code(p_cb->state),
406                          bta_hh_evt_code(debug_event));
407        }
408#endif
409    }
410
411    return;
412}
413/*******************************************************************************
414**
415** Function         bta_hh_hdl_event
416**
417** Description      HID host main event handling function.
418**
419**
420** Returns          void
421**
422*******************************************************************************/
423BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
424{
425    UINT8           index = BTA_HH_IDX_INVALID;
426    tBTA_HH_DEV_CB *p_cb = NULL;
427
428    switch (p_msg->event)
429    {
430        case BTA_HH_API_ENABLE_EVT:
431            bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
432            break;
433
434        case BTA_HH_API_DISABLE_EVT:
435            bta_hh_api_disable();
436            break;
437
438        case BTA_HH_DISC_CMPL_EVT:          /* disable complete */
439            bta_hh_disc_cmpl();
440            break;
441
442        default:
443            /* all events processed in state machine need to find corresponding
444                CB before proceed */
445            if (p_msg->event == BTA_HH_API_OPEN_EVT)
446            {
447                index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
448            }
449            else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
450            {
451                /* if add device */
452                if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
453                {
454                    index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
455                }
456                else /* else remove device by handle */
457                {
458                    index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
459// btla-specific ++
460                    /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
461                      * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
462                      * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
463                      * So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
464                      * force the index to be IDX_INVALID
465                      */
466                    if ((index != BTA_HH_IDX_INVALID) &&
467                        (bta_hh_cb.kdev[index].in_use == FALSE)) {
468                        index = BTA_HH_IDX_INVALID;
469                    }
470// btla-specific --
471                }
472            }
473            else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
474            {
475                index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
476            }
477            else
478                index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
479
480            if (index != BTA_HH_IDX_INVALID)
481                p_cb = &bta_hh_cb.kdev[index];
482
483#if BTA_HH_DEBUG
484            APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
485#endif
486            bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
487    }
488    return (TRUE);
489}
490
491/*****************************************************************************
492**  Debug Functions
493*****************************************************************************/
494#if BTA_HH_DEBUG
495/*******************************************************************************
496**
497** Function         bta_hh_evt_code
498**
499** Description
500**
501** Returns          void
502**
503*******************************************************************************/
504static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
505{
506  switch(evt_code)
507    {
508    case BTA_HH_API_DISABLE_EVT:
509        return "BTA_HH_API_DISABLE_EVT";
510    case BTA_HH_API_ENABLE_EVT:
511        return "BTA_HH_API_ENABLE_EVT";
512    case BTA_HH_API_OPEN_EVT:
513        return "BTA_HH_API_OPEN_EVT";
514    case BTA_HH_API_CLOSE_EVT:
515        return "BTA_HH_API_CLOSE_EVT";
516    case BTA_HH_INT_OPEN_EVT:
517        return "BTA_HH_INT_OPEN_EVT";
518    case BTA_HH_INT_CLOSE_EVT:
519        return "BTA_HH_INT_CLOSE_EVT";
520    case BTA_HH_INT_HANDSK_EVT:
521        return "BTA_HH_INT_HANDSK_EVT";
522    case BTA_HH_INT_DATA_EVT:
523        return "BTA_HH_INT_DATA_EVT";
524    case BTA_HH_INT_CTRL_DATA:
525        return "BTA_HH_INT_CTRL_DATA";
526    case BTA_HH_API_WRITE_DEV_EVT:
527        return "BTA_HH_API_WRITE_DEV_EVT";
528    case BTA_HH_SDP_CMPL_EVT:
529        return "BTA_HH_SDP_CMPL_EVT";
530    case BTA_HH_DISC_CMPL_EVT:
531        return "BTA_HH_DISC_CMPL_EVT";
532    case BTA_HH_API_MAINT_DEV_EVT:
533        return "BTA_HH_API_MAINT_DEV_EVT";
534    case BTA_HH_API_GET_DSCP_EVT:
535        return "BTA_HH_API_GET_DSCP_EVT";
536    case BTA_HH_OPEN_CMPL_EVT:
537        return "BTA_HH_OPEN_CMPL_EVT";
538#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
539    case BTA_HH_GATT_CLOSE_EVT:
540        return "BTA_HH_GATT_CLOSE_EVT";
541    case BTA_HH_GATT_OPEN_EVT:
542        return "BTA_HH_GATT_OPEN_EVT";
543    case BTA_HH_START_ENC_EVT:
544        return "BTA_HH_START_ENC_EVT";
545    case BTA_HH_ENC_CMPL_EVT:
546        return "BTA_HH_ENC_CMPL_EVT";
547    case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
548        return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
549    case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
550        return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
551    case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
552        return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
553    case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
554        return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
555#endif
556    default:
557        return "unknown HID Host event code";
558    }
559}
560
561/*******************************************************************************
562**
563** Function         bta_hh_state_code
564**
565** Description      get string representation of HID host state code.
566**
567** Returns          void
568**
569*******************************************************************************/
570static char *bta_hh_state_code(tBTA_HH_STATE state_code)
571{
572    switch (state_code)
573    {
574    case BTA_HH_NULL_ST:
575        return"BTA_HH_NULL_ST";
576    case BTA_HH_IDLE_ST:
577        return "BTA_HH_IDLE_ST";
578    case BTA_HH_W4_CONN_ST:
579        return "BTA_HH_W4_CONN_ST";
580    case BTA_HH_CONN_ST:
581        return "BTA_HH_CONN_ST";
582#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
583    case BTA_HH_W4_SEC:
584        return "BTA_HH_W4_SEC";
585#endif
586    default:
587        return "unknown HID Host state";
588    }
589}
590
591#endif  /* Debug Functions */
592
593#endif /* BTA_HH_INCLUDED */
594