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 */
40 enum
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 */
77 typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
78 
79 /* action functions */
80 const 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 */
119 const 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 
150 const 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 
180 const 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)
209 const 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 */
238 typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
239 
240 /* state table */
241 const 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
255 tBTA_HH_CB  bta_hh_cb;
256 #endif
257 /*****************************************************************************
258 ** Static functions
259 *****************************************************************************/
260 #if BTA_HH_DEBUG == TRUE
261 static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
262 static 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 *******************************************************************************/
bta_hh_sm_execute(tBTA_HH_DEV_CB * p_cb,UINT16 event,tBTA_HH_DATA * p_data)275 void 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 *******************************************************************************/
bta_hh_hdl_event(BT_HDR * p_msg)423 BOOLEAN 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 *******************************************************************************/
bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)504 static 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 *******************************************************************************/
bta_hh_state_code(tBTA_HH_STATE state_code)570 static 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