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 <cstdint>
27 
28 // BTA_HD_INCLUDED
29 #include "bt_target.h"  // Must be first to define build configuration
30 #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
31 
32 #include "bta/hd/bta_hd_int.h"
33 
34 /*****************************************************************************
35  * Constants and types
36  ****************************************************************************/
37 
38 /* state machine states */
39 enum {
40   BTA_HD_INIT_ST,
41   BTA_HD_IDLE_ST,              /* not connected, waiting for connection */
42   BTA_HD_CONN_ST,              /* host connected */
43   BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT
44                                   */
45 };
46 typedef uint8_t tBTA_HD_STATE;
47 
48 /*****************************************************************************
49  * Global data
50  ****************************************************************************/
51 tBTA_HD_CB bta_hd_cb;
52 
get_state()53 static tBTA_HD_STATE get_state() { return bta_hd_cb.state; }
54 
set_state(tBTA_HD_STATE state)55 static void set_state(tBTA_HD_STATE state) { bta_hd_cb.state = state; }
56 
bta_hd_better_state_machine(uint16_t event,tBTA_HD_DATA * p_data)57 static void bta_hd_better_state_machine(uint16_t event, tBTA_HD_DATA* p_data) {
58   switch (get_state()) {
59     case BTA_HD_INIT_ST:
60       switch (event) {
61         case BTA_HD_API_REGISTER_APP_EVT:
62           set_state(BTA_HD_IDLE_ST);
63           bta_hd_register_act(p_data);
64           break;
65         case BTA_HD_API_ADD_DEVICE_EVT:
66           bta_hd_add_device_act(p_data);
67           break;
68         case BTA_HD_API_REMOVE_DEVICE_EVT:
69           bta_hd_remove_device_act(p_data);
70           break;
71       }
72       break;
73     case BTA_HD_IDLE_ST:
74       switch (event) {
75         case BTA_HD_API_UNREGISTER_APP_EVT:
76           set_state(BTA_HD_INIT_ST);
77           bta_hd_unregister_act();
78           break;
79         case BTA_HD_API_CONNECT_EVT:
80           bta_hd_connect_act(p_data);
81           break;
82         case BTA_HD_API_DISCONNECT_EVT:
83           bta_hd_disconnect_act();
84           break;
85         case BTA_HD_API_ADD_DEVICE_EVT:
86           bta_hd_add_device_act(p_data);
87           break;
88         case BTA_HD_API_REMOVE_DEVICE_EVT:
89           bta_hd_remove_device_act(p_data);
90           break;
91         case BTA_HD_API_SEND_REPORT_EVT:
92           bta_hd_send_report_act(p_data);
93           break;
94         case BTA_HD_INT_OPEN_EVT:
95           set_state(BTA_HD_CONN_ST);
96           bta_hd_open_act(p_data);
97           break;
98         case BTA_HD_INT_CLOSE_EVT:
99           bta_hd_close_act(p_data);
100           break;
101       }
102       break;
103     case BTA_HD_CONN_ST:
104       switch (event) {
105         case BTA_HD_API_UNREGISTER_APP_EVT:
106           set_state(BTA_HD_TRANSIENT_TO_INIT_ST);
107           bta_hd_disconnect_act();
108           break;
109         case BTA_HD_API_DISCONNECT_EVT:
110           bta_hd_disconnect_act();
111           break;
112         case BTA_HD_API_ADD_DEVICE_EVT:
113           bta_hd_add_device_act(p_data);
114           break;
115         case BTA_HD_API_REMOVE_DEVICE_EVT:
116           bta_hd_remove_device_act(p_data);
117           break;
118         case BTA_HD_API_SEND_REPORT_EVT:
119           bta_hd_send_report_act(p_data);
120           break;
121         case BTA_HD_API_REPORT_ERROR_EVT:
122           bta_hd_report_error_act(p_data);
123           break;
124         case BTA_HD_API_VC_UNPLUG_EVT:
125           bta_hd_vc_unplug_act();
126           break;
127         case BTA_HD_INT_CLOSE_EVT:
128           set_state(BTA_HD_IDLE_ST);
129           bta_hd_close_act(p_data);
130           break;
131         case BTA_HD_INT_INTR_DATA_EVT:
132           bta_hd_intr_data_act(p_data);
133           break;
134         case BTA_HD_INT_GET_REPORT_EVT:
135           bta_hd_get_report_act(p_data);
136           break;
137         case BTA_HD_INT_SET_REPORT_EVT:
138           bta_hd_set_report_act(p_data);
139           break;
140         case BTA_HD_INT_SET_PROTOCOL_EVT:
141           bta_hd_set_protocol_act(p_data);
142           break;
143         case BTA_HD_INT_VC_UNPLUG_EVT:
144           set_state(BTA_HD_IDLE_ST);
145           bta_hd_vc_unplug_done_act(p_data);
146           break;
147         case BTA_HD_INT_SUSPEND_EVT:
148           bta_hd_suspend_act(p_data);
149           break;
150         case BTA_HD_INT_EXIT_SUSPEND_EVT:
151           bta_hd_exit_suspend_act(p_data);
152           break;
153       }
154       break;
155     case BTA_HD_TRANSIENT_TO_INIT_ST:
156       switch (event) {
157         case BTA_HD_INT_CLOSE_EVT:
158           set_state(BTA_HD_INIT_ST);
159           bta_hd_unregister2_act(p_data);
160           break;
161         case BTA_HD_INT_VC_UNPLUG_EVT:
162           set_state(BTA_HD_INIT_ST);
163           bta_hd_unregister2_act(p_data);
164           break;
165       }
166       break;
167   }
168 }
169 
170 /*******************************************************************************
171  *
172  * Function         bta_hd_hdl_event
173  *
174  * Description      HID device main event handling function.
175  *
176  * Returns          void
177  *
178  ******************************************************************************/
bta_hd_hdl_event(BT_HDR_RIGID * p_msg)179 bool bta_hd_hdl_event(BT_HDR_RIGID* p_msg) {
180   APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event);
181 
182   switch (p_msg->event) {
183     case BTA_HD_API_ENABLE_EVT:
184       bta_hd_api_enable((tBTA_HD_DATA*)p_msg);
185       break;
186 
187     case BTA_HD_API_DISABLE_EVT:
188       if (bta_hd_cb.state == BTA_HD_CONN_ST) {
189         APPL_TRACE_WARNING("%s: host connected, disconnect before disabling",
190                            __func__);
191 
192         // unregister (and disconnect)
193         bta_hd_cb.disable_w4_close = TRUE;
194         bta_hd_better_state_machine(BTA_HD_API_UNREGISTER_APP_EVT,
195                                     (tBTA_HD_DATA*)p_msg);
196       } else {
197         bta_hd_api_disable();
198       }
199       break;
200 
201     default:
202       bta_hd_better_state_machine(p_msg->event, (tBTA_HD_DATA*)p_msg);
203   }
204   return (TRUE);
205 }
206 
207 #endif /* BTA_HD_INCLUDED */
208