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 "bt_common.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 osi_free_and_reset((void **)&p_data->api_sndcmd.p_data);
324 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
325 p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
326 p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE)
327 {
328 cback_data.dev_status.status = BTA_HH_ERR_HDL;
329 cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
330 }
331 else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
332 p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
333 {
334 cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
335 cback_data.hs_data.status = BTA_HH_ERR_HDL;
336 /* hs_data.rsp_data will be all zero, which is not valid value */
337 }
338 else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
339 p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
340 {
341 cback_data.status = BTA_HH_ERR_HDL;
342 cback_event = BTA_HH_VC_UNPLUG_EVT;
343 }
344 else
345 cback_event = 0;
346 break;
347
348 case BTA_HH_API_CLOSE_EVT:
349 cback_event = BTA_HH_CLOSE_EVT;
350
351 cback_data.dev_status.status = BTA_HH_ERR_HDL;
352 cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
353 break;
354
355 default:
356 /* invalid handle, call bad API event */
357 APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
358 /* Free the callback buffer now */
359 if (p_data != NULL)
360 osi_free_and_reset((void **)&p_data->hid_cback.p_data);
361 break;
362 }
363 if (cback_event)
364 (* bta_hh_cb.p_cback)(cback_event, &cback_data);
365 }
366 }
367 /* corresponding CB is found, go to state machine */
368 else
369 {
370 #if BTA_HH_DEBUG == TRUE
371 in_state = p_cb->state;
372 APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
373 in_state, bta_hh_state_code(in_state),
374 bta_hh_evt_code(debug_event));
375 #endif
376
377 if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST))
378 {
379 APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
380 p_cb->state,event);
381 return;
382 }
383 state_table = bta_hh_st_tbl[p_cb->state - 1];
384
385 event &= 0xff;
386
387 p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
388
389 if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE)
390 {
391 (*bta_hh_action[action])(p_cb, p_data);
392 }
393
394 #if BTA_HH_DEBUG == TRUE
395 if (in_state != p_cb->state)
396 {
397 APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
398 bta_hh_state_code(in_state),
399 bta_hh_state_code(p_cb->state),
400 bta_hh_evt_code(debug_event));
401 }
402 #endif
403 }
404
405 return;
406 }
407 /*******************************************************************************
408 **
409 ** Function bta_hh_hdl_event
410 **
411 ** Description HID host main event handling function.
412 **
413 **
414 ** Returns void
415 **
416 *******************************************************************************/
bta_hh_hdl_event(BT_HDR * p_msg)417 BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
418 {
419 UINT8 index = BTA_HH_IDX_INVALID;
420 tBTA_HH_DEV_CB *p_cb = NULL;
421
422 switch (p_msg->event)
423 {
424 case BTA_HH_API_ENABLE_EVT:
425 bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
426 break;
427
428 case BTA_HH_API_DISABLE_EVT:
429 bta_hh_api_disable();
430 break;
431
432 case BTA_HH_DISC_CMPL_EVT: /* disable complete */
433 bta_hh_disc_cmpl();
434 break;
435
436 default:
437 /* all events processed in state machine need to find corresponding
438 CB before proceed */
439 if (p_msg->event == BTA_HH_API_OPEN_EVT)
440 {
441 index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
442 }
443 else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
444 {
445 /* if add device */
446 if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
447 {
448 index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
449 }
450 else /* else remove device by handle */
451 {
452 index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
453 /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
454 * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
455 * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
456 * So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
457 * force the index to be IDX_INVALID
458 */
459 if ((index != BTA_HH_IDX_INVALID) &&
460 (bta_hh_cb.kdev[index].in_use == FALSE)) {
461 index = BTA_HH_IDX_INVALID;
462 }
463 }
464 }
465 else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
466 {
467 index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
468 }
469 else
470 index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
471
472 if (index != BTA_HH_IDX_INVALID)
473 p_cb = &bta_hh_cb.kdev[index];
474
475 #if BTA_HH_DEBUG
476 APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
477 #endif
478 bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
479 }
480 return (TRUE);
481 }
482
483 /*****************************************************************************
484 ** Debug Functions
485 *****************************************************************************/
486 #if BTA_HH_DEBUG
487 /*******************************************************************************
488 **
489 ** Function bta_hh_evt_code
490 **
491 ** Description
492 **
493 ** Returns void
494 **
495 *******************************************************************************/
bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)496 static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
497 {
498 switch(evt_code)
499 {
500 case BTA_HH_API_DISABLE_EVT:
501 return "BTA_HH_API_DISABLE_EVT";
502 case BTA_HH_API_ENABLE_EVT:
503 return "BTA_HH_API_ENABLE_EVT";
504 case BTA_HH_API_OPEN_EVT:
505 return "BTA_HH_API_OPEN_EVT";
506 case BTA_HH_API_CLOSE_EVT:
507 return "BTA_HH_API_CLOSE_EVT";
508 case BTA_HH_INT_OPEN_EVT:
509 return "BTA_HH_INT_OPEN_EVT";
510 case BTA_HH_INT_CLOSE_EVT:
511 return "BTA_HH_INT_CLOSE_EVT";
512 case BTA_HH_INT_HANDSK_EVT:
513 return "BTA_HH_INT_HANDSK_EVT";
514 case BTA_HH_INT_DATA_EVT:
515 return "BTA_HH_INT_DATA_EVT";
516 case BTA_HH_INT_CTRL_DATA:
517 return "BTA_HH_INT_CTRL_DATA";
518 case BTA_HH_API_WRITE_DEV_EVT:
519 return "BTA_HH_API_WRITE_DEV_EVT";
520 case BTA_HH_SDP_CMPL_EVT:
521 return "BTA_HH_SDP_CMPL_EVT";
522 case BTA_HH_DISC_CMPL_EVT:
523 return "BTA_HH_DISC_CMPL_EVT";
524 case BTA_HH_API_MAINT_DEV_EVT:
525 return "BTA_HH_API_MAINT_DEV_EVT";
526 case BTA_HH_API_GET_DSCP_EVT:
527 return "BTA_HH_API_GET_DSCP_EVT";
528 case BTA_HH_OPEN_CMPL_EVT:
529 return "BTA_HH_OPEN_CMPL_EVT";
530 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
531 case BTA_HH_GATT_CLOSE_EVT:
532 return "BTA_HH_GATT_CLOSE_EVT";
533 case BTA_HH_GATT_OPEN_EVT:
534 return "BTA_HH_GATT_OPEN_EVT";
535 case BTA_HH_START_ENC_EVT:
536 return "BTA_HH_START_ENC_EVT";
537 case BTA_HH_ENC_CMPL_EVT:
538 return "BTA_HH_ENC_CMPL_EVT";
539 case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
540 return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
541 case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
542 return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
543 case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
544 return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
545 case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
546 return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
547 #endif
548 default:
549 return "unknown HID Host event code";
550 }
551 }
552
553 /*******************************************************************************
554 **
555 ** Function bta_hh_state_code
556 **
557 ** Description get string representation of HID host state code.
558 **
559 ** Returns void
560 **
561 *******************************************************************************/
bta_hh_state_code(tBTA_HH_STATE state_code)562 static char *bta_hh_state_code(tBTA_HH_STATE state_code)
563 {
564 switch (state_code)
565 {
566 case BTA_HH_NULL_ST:
567 return"BTA_HH_NULL_ST";
568 case BTA_HH_IDLE_ST:
569 return "BTA_HH_IDLE_ST";
570 case BTA_HH_W4_CONN_ST:
571 return "BTA_HH_W4_CONN_ST";
572 case BTA_HH_CONN_ST:
573 return "BTA_HH_CONN_ST";
574 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
575 case BTA_HH_W4_SEC:
576 return "BTA_HH_W4_SEC";
577 #endif
578 default:
579 return "unknown HID Host state";
580 }
581 }
582
583 #endif /* Debug Functions */
584
585 #endif /* BTA_HH_INCLUDED */
586