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