1 /******************************************************************************
2 *
3 * Copyright 2005-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the HID host main functions and state machine.
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bt_bta_hh"
26
27 #include <bluetooth/log.h>
28 #include <string.h> // memset
29
30 #include <cstdint>
31
32 #include "bta/hh/bta_hh_int.h"
33 #include "os/log.h"
34 #include "osi/include/allocator.h"
35 #include "stack/include/bt_hdr.h"
36
37 using namespace bluetooth;
38
39 /*****************************************************************************
40 * Global data
41 ****************************************************************************/
42 tBTA_HH_CB bta_hh_cb;
43
44 /*****************************************************************************
45 * Static functions
46 ****************************************************************************/
47 static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
48 static const char* bta_hh_state_code(tBTA_HH_STATE state_code);
49
bta_hh_better_state_machine(tBTA_HH_DEV_CB * p_cb,uint16_t event,const tBTA_HH_DATA * p_data)50 static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
51 const tBTA_HH_DATA* p_data) {
52 log::verbose("state:{}, event:{}", bta_hh_state_code(p_cb->state),
53 bta_hh_evt_code(static_cast<tBTA_HH_INT_EVT>(event)));
54 switch (p_cb->state) {
55 case BTA_HH_IDLE_ST:
56 switch (event) {
57 case BTA_HH_API_OPEN_EVT:
58 p_cb->state = BTA_HH_W4_CONN_ST;
59 bta_hh_connect(p_cb, p_data);
60 break;
61 case BTA_HH_INT_OPEN_EVT:
62 p_cb->state = BTA_HH_W4_CONN_ST;
63 bta_hh_open_act(p_cb, p_data);
64 break;
65 case BTA_HH_INT_CLOSE_EVT:
66 bta_hh_open_failure(p_cb, p_data);
67 break;
68 case BTA_HH_API_MAINT_DEV_EVT:
69 bta_hh_maint_dev_act(p_cb, p_data);
70 break;
71 case BTA_HH_OPEN_CMPL_EVT:
72 p_cb->state = BTA_HH_CONN_ST;
73 bta_hh_open_cmpl_act(p_cb, p_data);
74 break;
75 case BTA_HH_GATT_OPEN_EVT:
76 p_cb->state = BTA_HH_W4_CONN_ST;
77 bta_hh_gatt_open(p_cb, p_data);
78 break;
79 }
80 break;
81 case BTA_HH_W4_CONN_ST:
82 switch (event) {
83 case BTA_HH_API_CLOSE_EVT:
84 p_cb->state = BTA_HH_IDLE_ST;
85 break;
86 case BTA_HH_INT_OPEN_EVT:
87 bta_hh_open_act(p_cb, p_data);
88 break;
89 case BTA_HH_INT_CLOSE_EVT:
90 p_cb->state = BTA_HH_IDLE_ST;
91 bta_hh_open_failure(p_cb, p_data);
92 break;
93 case BTA_HH_SDP_CMPL_EVT:
94 bta_hh_sdp_cmpl(p_cb, p_data);
95 break;
96 case BTA_HH_API_WRITE_DEV_EVT:
97 bta_hh_write_dev_act(p_cb, p_data);
98 break;
99 case BTA_HH_API_MAINT_DEV_EVT:
100 p_cb->state = BTA_HH_IDLE_ST;
101 bta_hh_maint_dev_act(p_cb, p_data);
102 break;
103 case BTA_HH_OPEN_CMPL_EVT:
104 p_cb->state = BTA_HH_CONN_ST;
105 bta_hh_open_cmpl_act(p_cb, p_data);
106 break;
107 case BTA_HH_GATT_CLOSE_EVT:
108 p_cb->state = BTA_HH_IDLE_ST;
109 bta_hh_le_open_fail(p_cb, p_data);
110 break;
111 case BTA_HH_GATT_OPEN_EVT:
112 bta_hh_gatt_open(p_cb, p_data);
113 break;
114 case BTA_HH_START_ENC_EVT:
115 p_cb->state = BTA_HH_W4_SEC;
116 bta_hh_start_security(p_cb, p_data);
117 break;
118 }
119 break;
120 case BTA_HH_CONN_ST:
121 switch (event) {
122 case BTA_HH_API_CLOSE_EVT:
123 bta_hh_api_disc_act(p_cb, p_data);
124 break;
125 case BTA_HH_INT_OPEN_EVT:
126 bta_hh_open_act(p_cb, p_data);
127 break;
128 case BTA_HH_INT_CLOSE_EVT:
129 p_cb->state = BTA_HH_IDLE_ST;
130 bta_hh_close_act(p_cb, p_data);
131 break;
132 case BTA_HH_INT_DATA_EVT:
133 bta_hh_data_act(p_cb, p_data);
134 break;
135 case BTA_HH_INT_CTRL_DATA:
136 bta_hh_ctrl_dat_act(p_cb, p_data);
137 break;
138 case BTA_HH_INT_HANDSK_EVT:
139 bta_hh_handsk_act(p_cb, p_data);
140 break;
141 case BTA_HH_API_WRITE_DEV_EVT:
142 bta_hh_write_dev_act(p_cb, p_data);
143 break;
144 case BTA_HH_API_GET_DSCP_EVT:
145 bta_hh_get_dscp_act(p_cb, p_data);
146 break;
147 case BTA_HH_API_MAINT_DEV_EVT:
148 bta_hh_maint_dev_act(p_cb, p_data);
149 break;
150 case BTA_HH_GATT_CLOSE_EVT:
151 p_cb->state = BTA_HH_IDLE_ST;
152 bta_hh_gatt_close(p_cb, p_data);
153 break;
154 }
155 break;
156 case BTA_HH_W4_SEC:
157 switch (event) {
158 case BTA_HH_API_CLOSE_EVT:
159 bta_hh_api_disc_act(p_cb, p_data);
160 break;
161 case BTA_HH_INT_CLOSE_EVT:
162 p_cb->state = BTA_HH_IDLE_ST;
163 bta_hh_open_failure(p_cb, p_data);
164 break;
165 case BTA_HH_API_MAINT_DEV_EVT:
166 bta_hh_maint_dev_act(p_cb, p_data);
167 break;
168 case BTA_HH_GATT_CLOSE_EVT:
169 p_cb->state = BTA_HH_IDLE_ST;
170 bta_hh_le_open_fail(p_cb, p_data);
171 break;
172 case BTA_HH_ENC_CMPL_EVT:
173 p_cb->state = BTA_HH_W4_CONN_ST;
174 bta_hh_security_cmpl(p_cb, p_data);
175 break;
176 case BTA_HH_GATT_ENC_CMPL_EVT:
177 bta_hh_le_notify_enc_cmpl(p_cb, p_data);
178 break;
179 }
180 break;
181 }
182 }
183
184 /*******************************************************************************
185 *
186 * Function bta_hh_sm_execute
187 *
188 * Description State machine event handling function for HID Host
189 *
190 *
191 * Returns void
192 *
193 ******************************************************************************/
bta_hh_sm_execute(tBTA_HH_DEV_CB * p_cb,uint16_t event,const tBTA_HH_DATA * p_data)194 void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event,
195 const tBTA_HH_DATA* p_data) {
196 tBTA_HH cback_data;
197 tBTA_HH_EVT cback_event = 0;
198 tBTA_HH_STATE in_state;
199 tBTA_HH_INT_EVT debug_event = static_cast<tBTA_HH_INT_EVT>(event);
200
201 memset(&cback_data, 0, sizeof(tBTA_HH));
202
203 /* handle exception, no valid control block was found */
204 if (!p_cb) {
205 log::verbose("Event:{}, bta_hh_cb.p_cback:{}", bta_hh_evt_code(debug_event),
206 fmt::ptr(bta_hh_cb.p_cback));
207 /* BTA HH enabled already? otherwise ignore the event although it's bad*/
208 if (bta_hh_cb.p_cback != NULL) {
209 switch (event) {
210 /* no control block available for new connection */
211 case BTA_HH_API_OPEN_EVT:
212 cback_event = BTA_HH_OPEN_EVT;
213 /* build cback data */
214 cback_data.conn.link_spec = ((tBTA_HH_API_CONN*)p_data)->link_spec;
215 cback_data.conn.status = BTA_HH_ERR_DB_FULL;
216 cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
217 break;
218 /* DB full, BTA_HhAddDev */
219 case BTA_HH_API_MAINT_DEV_EVT:
220 cback_event = p_data->api_maintdev.sub_event;
221
222 if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
223 cback_data.dev_info.link_spec = p_data->api_maintdev.link_spec;
224 cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
225 cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
226 } else {
227 cback_data.dev_info.status = BTA_HH_ERR_HDL;
228 cback_data.dev_info.handle =
229 (uint8_t)p_data->api_maintdev.hdr.layer_specific;
230 }
231 break;
232 case BTA_HH_API_WRITE_DEV_EVT:
233 cback_event = (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) +
234 BTA_HH_GET_RPT_EVT;
235 osi_free_and_reset((void**)&p_data->api_sndcmd.p_data);
236 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
237 p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
238 p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
239 cback_data.dev_status.status = BTA_HH_ERR_HDL;
240 cback_data.dev_status.handle =
241 (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
242 } else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
243 p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
244 cback_data.hs_data.handle =
245 (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
246 cback_data.hs_data.status = BTA_HH_ERR_HDL;
247 /* hs_data.rsp_data will be all zero, which is not valid value */
248 } else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
249 p_data->api_sndcmd.param ==
250 BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
251 cback_data.status = BTA_HH_ERR_HDL;
252 cback_event = BTA_HH_VC_UNPLUG_EVT;
253 } else
254 cback_event = 0;
255 break;
256
257 case BTA_HH_API_CLOSE_EVT:
258 cback_event = BTA_HH_CLOSE_EVT;
259
260 cback_data.dev_status.status = BTA_HH_ERR_HDL;
261 cback_data.dev_status.handle =
262 (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
263 break;
264
265 default:
266 /* invalid handle, call bad API event */
267 log::error("wrong device handle:{}", p_data->hdr.layer_specific);
268 /* Free the callback buffer now */
269 if (p_data != NULL)
270 osi_free_and_reset((void**)&p_data->hid_cback.p_data);
271 break;
272 }
273 if (cback_event) (*bta_hh_cb.p_cback)(cback_event, &cback_data);
274 }
275 }
276 /* corresponding CB is found, go to state machine */
277 else {
278 in_state = p_cb->state;
279 log::verbose("State 0x{:02x} [{}], Event [{}]", in_state,
280 bta_hh_state_code(in_state), bta_hh_evt_code(debug_event));
281
282 if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) {
283 log::error("Invalid state State=0x{:x}, Event={}", p_cb->state, event);
284 return;
285 }
286
287 bta_hh_better_state_machine(p_cb, event, p_data);
288
289 if (in_state != p_cb->state) {
290 log::debug("HHID State Change: [{}] -> [{}] after Event [{}]",
291 bta_hh_state_code(in_state), bta_hh_state_code(p_cb->state),
292 bta_hh_evt_code(debug_event));
293 }
294 }
295 }
296
297 /*******************************************************************************
298 *
299 * Function bta_hh_hdl_event
300 *
301 * Description HID host main event handling function.
302 *
303 *
304 * Returns void
305 *
306 ******************************************************************************/
bta_hh_hdl_event(const BT_HDR_RIGID * p_msg)307 bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg) {
308 uint8_t index = BTA_HH_IDX_INVALID;
309 tBTA_HH_DEV_CB* p_cb = NULL;
310
311 /* all events processed in state machine need to find corresponding
312 CB before proceed */
313 if (p_msg->event == BTA_HH_API_OPEN_EVT) {
314 index = bta_hh_find_cb(((tBTA_HH_API_CONN*)p_msg)->link_spec);
315 } else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
316 /* if add device */
317 if (((tBTA_HH_MAINT_DEV*)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
318 index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV*)p_msg)->link_spec);
319 } else /* else remove device by handle */ {
320 index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
321 /* If BT disable is done while the HID device is connected and
322 * Link_Key uses unauthenticated combination
323 * then we can get into a situation where remove_bonding is called
324 * with the index set to 0 (without getting
325 * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the
326 * index and make it MAX_KNOWN.
327 * So if REMOVE_DEVICE is called and in_use is false then we should
328 * treat this as a NULL p_cb. Hence we
329 * force the index to be IDX_INVALID
330 */
331 if ((index != BTA_HH_IDX_INVALID) && (!bta_hh_cb.kdev[index].in_use)) {
332 index = BTA_HH_IDX_INVALID;
333 }
334 }
335 } else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
336 index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA*)p_msg)->link_spec);
337 } else {
338 index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
339 }
340
341 if (index != BTA_HH_IDX_INVALID) p_cb = &bta_hh_cb.kdev[index];
342
343 log::verbose("handle={} dev_cb[{}]", p_msg->layer_specific, index);
344 bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA*)p_msg);
345
346 return (true);
347 }
348
349 /*****************************************************************************
350 * Debug Functions
351 ****************************************************************************/
352 /*******************************************************************************
353 *
354 * Function bta_hh_evt_code
355 *
356 * Description
357 *
358 * Returns void
359 *
360 ******************************************************************************/
bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)361 static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code) {
362 switch (evt_code) {
363 case BTA_HH_API_OPEN_EVT:
364 return "BTA_HH_API_OPEN_EVT";
365 case BTA_HH_API_CLOSE_EVT:
366 return "BTA_HH_API_CLOSE_EVT";
367 case BTA_HH_INT_OPEN_EVT:
368 return "BTA_HH_INT_OPEN_EVT";
369 case BTA_HH_INT_CLOSE_EVT:
370 return "BTA_HH_INT_CLOSE_EVT";
371 case BTA_HH_INT_HANDSK_EVT:
372 return "BTA_HH_INT_HANDSK_EVT";
373 case BTA_HH_INT_DATA_EVT:
374 return "BTA_HH_INT_DATA_EVT";
375 case BTA_HH_INT_CTRL_DATA:
376 return "BTA_HH_INT_CTRL_DATA";
377 case BTA_HH_API_WRITE_DEV_EVT:
378 return "BTA_HH_API_WRITE_DEV_EVT";
379 case BTA_HH_SDP_CMPL_EVT:
380 return "BTA_HH_SDP_CMPL_EVT";
381 case BTA_HH_API_MAINT_DEV_EVT:
382 return "BTA_HH_API_MAINT_DEV_EVT";
383 case BTA_HH_API_GET_DSCP_EVT:
384 return "BTA_HH_API_GET_DSCP_EVT";
385 case BTA_HH_OPEN_CMPL_EVT:
386 return "BTA_HH_OPEN_CMPL_EVT";
387 case BTA_HH_GATT_CLOSE_EVT:
388 return "BTA_HH_GATT_CLOSE_EVT";
389 case BTA_HH_GATT_OPEN_EVT:
390 return "BTA_HH_GATT_OPEN_EVT";
391 case BTA_HH_START_ENC_EVT:
392 return "BTA_HH_START_ENC_EVT";
393 case BTA_HH_ENC_CMPL_EVT:
394 return "BTA_HH_ENC_CMPL_EVT";
395 default:
396 return "unknown HID Host event code";
397 }
398 }
399
400 /*******************************************************************************
401 *
402 * Function bta_hh_state_code
403 *
404 * Description get string representation of HID host state code.
405 *
406 * Returns void
407 *
408 ******************************************************************************/
bta_hh_state_code(tBTA_HH_STATE state_code)409 static const char* bta_hh_state_code(tBTA_HH_STATE state_code) {
410 switch (state_code) {
411 case BTA_HH_NULL_ST:
412 return "BTA_HH_NULL_ST";
413 case BTA_HH_IDLE_ST:
414 return "BTA_HH_IDLE_ST";
415 case BTA_HH_W4_CONN_ST:
416 return "BTA_HH_W4_CONN_ST";
417 case BTA_HH_CONN_ST:
418 return "BTA_HH_CONN_ST";
419 case BTA_HH_W4_SEC:
420 return "BTA_HH_W4_SEC";
421 default:
422 return "unknown HID Host state";
423 }
424 }
425