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