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