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