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