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