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