1 /******************************************************************************
2 *
3 * Copyright (C) 2016 The Android Open Source Project
4 * Copyright (C) 2005-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19 /******************************************************************************
20 *
21 * This file contains the HID host main functions and state machine.
22 *
23 ******************************************************************************/
24 #include "common/bt_target.h"
25
26 #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
27
28 #include "bta/bta_hd_api.h"
29 #include "bta_hd_int.h"
30 #include <string.h>
31
32 /*****************************************************************************
33 * Constants and types
34 ****************************************************************************/
35 /* state machine states */
36 enum {
37 BTA_HD_INIT_ST,
38 BTA_HD_IDLE_ST, /* not connected, waiting for connection */
39 BTA_HD_CONN_ST, /* host connected */
40 BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT */
41 };
42 typedef uint8_t tBTA_HD_STATE;
43
44 /* state machine actions */
45 enum {
46 BTA_HD_REGISTER_ACT,
47 BTA_HD_UNREGISTER_ACT,
48 BTA_HD_UNREGISTER2_ACT,
49 BTA_HD_CONNECT_ACT,
50 BTA_HD_DISCONNECT_ACT,
51 BTA_HD_ADD_DEVICE_ACT,
52 BTA_HD_REMOVE_DEVICE_ACT,
53 BTA_HD_SEND_REPORT_ACT,
54 BTA_HD_REPORT_ERROR_ACT,
55 BTA_HD_VC_UNPLUG_ACT,
56 BTA_HD_OPEN_ACT,
57 BTA_HD_CLOSE_ACT,
58 BTA_HD_INTR_DATA_ACT,
59 BTA_HD_GET_REPORT_ACT,
60 BTA_HD_SET_REPORT_ACT,
61 BTA_HD_SET_PROTOCOL_ACT,
62 BTA_HD_VC_UNPLUG_DONE_ACT,
63 BTA_HD_SUSPEND_ACT,
64 BTA_HD_EXIT_SUSPEND_ACT,
65 BTA_HD_NUM_ACTIONS
66 };
67
68 #define BTA_HD_IGNORE BTA_HD_NUM_ACTIONS
69
70 typedef void (*tBTA_HD_ACTION)(tBTA_HD_DATA *p_data);
71 /* action functions */
72 const tBTA_HD_ACTION bta_hd_action[] = {
73 bta_hd_register_act, bta_hd_unregister_act, bta_hd_unregister2_act, bta_hd_connect_act,
74 bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act,
75 bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act,
76 bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act,
77 bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act,
78 };
79
80 /* state table information */
81 #define BTA_HD_ACTION 0 /* position of action */
82 #define BTA_HD_NEXT_STATE 1 /* position of next state */
83 #define BTA_HD_NUM_COLS 2 /* number of columns */
84
85 const uint8_t bta_hd_st_init[][BTA_HD_NUM_COLS] = {
86 /* Event Action Next state
87 */
88 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_REGISTER_ACT, BTA_HD_IDLE_ST},
89 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
90 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
91 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
92 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_INIT_ST},
93 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_INIT_ST},
94 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
95 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
96 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
97 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
98 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
99 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
100 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
101 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
102 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
103 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
104 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
105 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST},
106 };
107
108 const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = {
109 /* Event Action Next state
110 */
111 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
112 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_UNREGISTER_ACT, BTA_HD_INIT_ST},
113 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_CONNECT_ACT, BTA_HD_IDLE_ST},
114 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
115 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_IDLE_ST},
116 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_IDLE_ST},
117 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_IDLE_ST},
118 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
119 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
120 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST},
121 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
122 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
123 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
124 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
125 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
126 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
127 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
128 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST},
129 };
130
131 const uint8_t bta_hd_st_conn[][BTA_HD_NUM_COLS] = {
132 /* Event Action Next state */
133 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
134 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_TRANSIENT_TO_INIT_ST},
135 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
136 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_CONN_ST},
137 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_CONN_ST},
138 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_CONN_ST},
139 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_CONN_ST},
140 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_REPORT_ERROR_ACT, BTA_HD_CONN_ST},
141 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_CONN_ST},
142 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST},
143 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_CLOSE_ACT, BTA_HD_IDLE_ST},
144 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_INTR_DATA_ACT, BTA_HD_CONN_ST},
145 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_GET_REPORT_ACT, BTA_HD_CONN_ST},
146 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_SET_REPORT_ACT, BTA_HD_CONN_ST},
147 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_SET_PROTOCOL_ACT, BTA_HD_CONN_ST},
148 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_DONE_ACT, BTA_HD_IDLE_ST},
149 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_SUSPEND_ACT, BTA_HD_CONN_ST},
150 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_EXIT_SUSPEND_ACT, BTA_HD_CONN_ST},
151 };
152
153 const uint8_t bta_hd_st_transient_to_init[][BTA_HD_NUM_COLS] = {
154 /* Event Action Next state */
155 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
156 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
157 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
158 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
159 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
160 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
161 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
162 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
163 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
164 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
165 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
166 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
167 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
168 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
169 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
170 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_UNREGISTER2_ACT, BTA_HD_INIT_ST},
171 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
172 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_TRANSIENT_TO_INIT_ST},
173 };
174
175 /* type for state table */
176 typedef const uint8_t (*tBTA_HD_ST_TBL)[BTA_HD_NUM_COLS];
177 /* state table */
178 const tBTA_HD_ST_TBL bta_hd_st_tbl[] = {bta_hd_st_init, bta_hd_st_idle, bta_hd_st_conn, bta_hd_st_transient_to_init};
179
180 /*****************************************************************************
181 * Global data
182 ****************************************************************************/
183 #if BTA_DYNAMIC_MEMORY == FALSE
184 tBTA_HD_CB bta_hd_cb;
185 #else
186 tBTA_HD_CB *bta_hd_cb_ptr;
187 #endif
188
189 static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code);
190 static const char *bta_hd_state_code(tBTA_HD_STATE state_code);
191
192 /*******************************************************************************
193 *
194 * Function bta_hd_sm_execute
195 *
196 * Description State machine event handling function for HID Device
197 *
198 * Returns void
199 *
200 ******************************************************************************/
bta_hd_sm_execute(uint16_t event,tBTA_HD_DATA * p_data)201 void bta_hd_sm_execute(uint16_t event, tBTA_HD_DATA *p_data)
202 {
203 tBTA_HD_ST_TBL state_table;
204 tBTA_HD_STATE prev_state;
205 uint8_t action;
206 tBTA_HD cback_data;
207
208 APPL_TRACE_EVENT("%s: state=%s (%d) event=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state,
209 bta_hd_evt_code(event), event);
210
211 prev_state = bta_hd_cb.state;
212 memset(&cback_data, 0, sizeof(tBTA_HD));
213 state_table = bta_hd_st_tbl[bta_hd_cb.state];
214 event &= 0xff;
215
216 if ((action = state_table[event][BTA_HD_ACTION]) < BTA_HD_IGNORE) {
217 (*bta_hd_action[action])(p_data);
218 }
219
220 bta_hd_cb.state = state_table[event][BTA_HD_NEXT_STATE];
221
222 if (bta_hd_cb.state != prev_state) {
223 APPL_TRACE_EVENT("%s: [new] state=%s (%d)", __func__, bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state);
224 }
225 return;
226 }
227
228 /*******************************************************************************
229 *
230 * Function bta_hd_hdl_event
231 *
232 * Description HID device main event handling function.
233 *
234 * Returns void
235 *
236 ******************************************************************************/
bta_hd_hdl_event(BT_HDR * p_msg)237 bool bta_hd_hdl_event(BT_HDR *p_msg)
238 {
239 APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event);
240
241 switch (p_msg->event) {
242 case BTA_HD_API_ENABLE_EVT:
243 bta_hd_api_enable((tBTA_HD_DATA *)p_msg);
244 break;
245 case BTA_HD_API_DISABLE_EVT:
246 if (bta_hd_cb.state == BTA_HD_CONN_ST) {
247 APPL_TRACE_WARNING("%s: host connected, disconnect before disabling", __func__);
248 // unregister (and disconnect)
249 bta_hd_cb.disable_w4_close = TRUE;
250 bta_hd_sm_execute(BTA_HD_API_UNREGISTER_APP_EVT, (tBTA_HD_DATA *)p_msg);
251 } else {
252 bta_hd_api_disable();
253 }
254 break;
255 default:
256 bta_hd_sm_execute(p_msg->event, (tBTA_HD_DATA *)p_msg);
257 }
258 return (TRUE);
259 }
260
bta_hd_evt_code(tBTA_HD_INT_EVT evt_code)261 static const char *bta_hd_evt_code(tBTA_HD_INT_EVT evt_code)
262 {
263 switch (evt_code) {
264 case BTA_HD_API_REGISTER_APP_EVT:
265 return "BTA_HD_API_REGISTER_APP_EVT";
266 case BTA_HD_API_UNREGISTER_APP_EVT:
267 return "BTA_HD_API_UNREGISTER_APP_EVT";
268 case BTA_HD_API_CONNECT_EVT:
269 return "BTA_HD_API_CONNECT_EVT";
270 case BTA_HD_API_DISCONNECT_EVT:
271 return "BTA_HD_API_DISCONNECT_EVT";
272 case BTA_HD_API_ADD_DEVICE_EVT:
273 return "BTA_HD_API_ADD_DEVICE_EVT";
274 case BTA_HD_API_REMOVE_DEVICE_EVT:
275 return "BTA_HD_API_REMOVE_DEVICE_EVT";
276 case BTA_HD_API_SEND_REPORT_EVT:
277 return "BTA_HD_API_SEND_REPORT_EVT";
278 case BTA_HD_API_REPORT_ERROR_EVT:
279 return "BTA_HD_API_REPORT_ERROR_EVT";
280 case BTA_HD_API_VC_UNPLUG_EVT:
281 return "BTA_HD_API_VC_UNPLUG_EVT";
282 case BTA_HD_INT_OPEN_EVT:
283 return "BTA_HD_INT_OPEN_EVT";
284 case BTA_HD_INT_CLOSE_EVT:
285 return "BTA_HD_INT_CLOSE_EVT";
286 case BTA_HD_INT_INTR_DATA_EVT:
287 return "BTA_HD_INT_INTR_DATA_EVT";
288 case BTA_HD_INT_GET_REPORT_EVT:
289 return "BTA_HD_INT_GET_REPORT_EVT";
290 case BTA_HD_INT_SET_REPORT_EVT:
291 return "BTA_HD_INT_SET_REPORT_EVT";
292 case BTA_HD_INT_SET_PROTOCOL_EVT:
293 return "BTA_HD_INT_SET_PROTOCOL_EVT";
294 case BTA_HD_INT_VC_UNPLUG_EVT:
295 return "BTA_HD_INT_VC_UNPLUG_EVT";
296 case BTA_HD_INT_SUSPEND_EVT:
297 return "BTA_HD_INT_SUSPEND_EVT";
298 case BTA_HD_INT_EXIT_SUSPEND_EVT:
299 return "BTA_HD_INT_EXIT_SUSPEND_EVT";
300 default:
301 return "<unknown>";
302 }
303 }
304
bta_hd_state_code(tBTA_HD_STATE state_code)305 static const char *bta_hd_state_code(tBTA_HD_STATE state_code)
306 {
307 switch (state_code) {
308 case BTA_HD_INIT_ST:
309 return "BTA_HD_INIT_ST";
310 case BTA_HD_IDLE_ST:
311 return "BTA_HD_IDLE_ST";
312 case BTA_HD_CONN_ST:
313 return "BTA_HD_CONN_ST";
314 case BTA_HD_TRANSIENT_TO_INIT_ST:
315 return "BTA_HD_TRANSIENT_TO_INIT_ST";
316 default:
317 return "<unknown>";
318 }
319 }
320 #endif /* BTA_HD_INCLUDED */
321