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
29 #include <cstdint>
30
31 #include "bta/hh/bta_hh_int.h"
32 #include "bta_hh_api.h"
33 #include "hiddefs.h"
34 #include "main/shim/dumpsys.h"
35 #include "osi/include/allocator.h"
36 #include "stack/include/bt_hdr.h"
37
38 // TODO(b/369381361) Enfore -Wmissing-prototypes
39 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
40
41 using namespace bluetooth;
42
43 /*****************************************************************************
44 * Global data
45 ****************************************************************************/
46 tBTA_HH_CB bta_hh_cb;
47
48 /*****************************************************************************
49 * Static functions
50 ****************************************************************************/
51 /*******************************************************************************
52 *
53 * Function bta_hh_evt_code
54 *
55 * Description
56 *
57 * Returns void
58 *
59 ******************************************************************************/
bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)60 static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code) {
61 switch (evt_code) {
62 case BTA_HH_API_OPEN_EVT:
63 return "BTA_HH_API_OPEN_EVT";
64 case BTA_HH_API_CLOSE_EVT:
65 return "BTA_HH_API_CLOSE_EVT";
66 case BTA_HH_INT_OPEN_EVT:
67 return "BTA_HH_INT_OPEN_EVT";
68 case BTA_HH_INT_CLOSE_EVT:
69 return "BTA_HH_INT_CLOSE_EVT";
70 case BTA_HH_INT_HANDSK_EVT:
71 return "BTA_HH_INT_HANDSK_EVT";
72 case BTA_HH_INT_DATA_EVT:
73 return "BTA_HH_INT_DATA_EVT";
74 case BTA_HH_INT_CTRL_DATA:
75 return "BTA_HH_INT_CTRL_DATA";
76 case BTA_HH_API_WRITE_DEV_EVT:
77 return "BTA_HH_API_WRITE_DEV_EVT";
78 case BTA_HH_SDP_CMPL_EVT:
79 return "BTA_HH_SDP_CMPL_EVT";
80 case BTA_HH_API_MAINT_DEV_EVT:
81 return "BTA_HH_API_MAINT_DEV_EVT";
82 case BTA_HH_API_GET_DSCP_EVT:
83 return "BTA_HH_API_GET_DSCP_EVT";
84 case BTA_HH_OPEN_CMPL_EVT:
85 return "BTA_HH_OPEN_CMPL_EVT";
86 case BTA_HH_GATT_CLOSE_EVT:
87 return "BTA_HH_GATT_CLOSE_EVT";
88 case BTA_HH_GATT_OPEN_EVT:
89 return "BTA_HH_GATT_OPEN_EVT";
90 case BTA_HH_START_ENC_EVT:
91 return "BTA_HH_START_ENC_EVT";
92 case BTA_HH_ENC_CMPL_EVT:
93 return "BTA_HH_ENC_CMPL_EVT";
94 default:
95 return "unknown HID Host event code";
96 }
97 }
98
99 /*******************************************************************************
100 *
101 * Function bta_hh_state_code
102 *
103 * Description get string representation of HID host state code.
104 *
105 * Returns void
106 *
107 ******************************************************************************/
bta_hh_state_code(tBTA_HH_STATE state_code)108 static const char* bta_hh_state_code(tBTA_HH_STATE state_code) {
109 switch (state_code) {
110 case BTA_HH_NULL_ST:
111 return "BTA_HH_NULL_ST";
112 case BTA_HH_IDLE_ST:
113 return "BTA_HH_IDLE_ST";
114 case BTA_HH_W4_CONN_ST:
115 return "BTA_HH_W4_CONN_ST";
116 case BTA_HH_CONN_ST:
117 return "BTA_HH_CONN_ST";
118 case BTA_HH_W4_SEC:
119 return "BTA_HH_W4_SEC";
120 default:
121 return "unknown HID Host state";
122 }
123 }
124
125 /* Finds the related control block, if any */
bta_hh_find_cb_by_event(const BT_HDR_RIGID * p_msg)126 static tBTA_HH_DEV_CB* bta_hh_find_cb_by_event(const BT_HDR_RIGID* p_msg) {
127 tBTA_HH_DEV_CB* p_cb = nullptr;
128
129 if (p_msg->event == BTA_HH_API_OPEN_EVT) {
130 // Connection requested, find or allocate the control block
131 p_cb = bta_hh_get_cb(((tBTA_HH_API_CONN*)p_msg)->link_spec);
132 } else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
133 if (((tBTA_HH_MAINT_DEV*)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
134 // Device is being added, find or allocate the control block
135 p_cb = bta_hh_get_cb(((tBTA_HH_MAINT_DEV*)p_msg)->link_spec);
136 } else /* else remove device by handle */ {
137 p_cb = bta_hh_find_cb_by_handle((uint8_t)p_msg->layer_specific);
138 /* If BT disable is done while the HID device is connected and
139 * Link_Key uses unauthenticated combination
140 * then we can get into a situation where remove_bonding is called
141 * with the index set to 0 (without getting
142 * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the
143 * index and make it MAX_KNOWN.
144 * So if REMOVE_DEVICE is called and in_use is false then we should
145 * treat this as a NULL p_cb. Hence we
146 * force the index to be IDX_INVALID
147 */
148 if (p_cb != nullptr && !p_cb->in_use) {
149 log::warn("Control block getting removed, device: {}, index: {}, handle: {}",
150 p_cb->link_spec, p_cb->index, p_cb->hid_handle);
151 p_cb = nullptr;
152 }
153 }
154 } else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
155 p_cb = bta_hh_get_cb(((tBTA_HH_CBACK_DATA*)p_msg)->link_spec);
156 } else {
157 p_cb = bta_hh_find_cb_by_handle((uint8_t)p_msg->layer_specific);
158 }
159
160 return p_cb;
161 }
162
163 /* Handles events related to connection control blocks */
bta_hh_sm_execute(tBTA_HH_DEV_CB * p_cb,tBTA_HH_INT_EVT event,const tBTA_HH_DATA * p_data)164 void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, tBTA_HH_INT_EVT event, const tBTA_HH_DATA* p_data) {
165 tBTA_HH_STATE in_state = p_cb->state;
166 if (p_cb->state == BTA_HH_NULL_ST || p_cb->state >= BTA_HH_INVALID_ST) {
167 log::error("Invalid state State:{}, Event:{} for {}", bta_hh_state_code(in_state),
168 bta_hh_evt_code(event), p_cb->link_spec);
169 return;
170 }
171
172 bool unexpected_event = false;
173 log::verbose("State {}, Event {} for {}", bta_hh_state_code(in_state), bta_hh_evt_code(event),
174 p_cb->link_spec);
175
176 switch (in_state) {
177 case BTA_HH_IDLE_ST:
178 switch (event) {
179 case BTA_HH_API_OPEN_EVT:
180 p_cb->state = BTA_HH_W4_CONN_ST;
181 bta_hh_connect(p_cb, p_data);
182 break;
183 case BTA_HH_INT_OPEN_EVT:
184 p_cb->state = BTA_HH_W4_CONN_ST;
185 bta_hh_open_act(p_cb, p_data);
186 break;
187 case BTA_HH_INT_CLOSE_EVT:
188 bta_hh_open_failure(p_cb, p_data);
189 break;
190 case BTA_HH_API_MAINT_DEV_EVT:
191 bta_hh_maint_dev_act(p_cb, p_data);
192 break;
193 case BTA_HH_OPEN_CMPL_EVT:
194 p_cb->state = BTA_HH_CONN_ST;
195 bta_hh_open_cmpl_act(p_cb, p_data);
196 break;
197 case BTA_HH_GATT_OPEN_EVT:
198 p_cb->state = BTA_HH_W4_CONN_ST;
199 bta_hh_gatt_open(p_cb, p_data);
200 break;
201 default:
202 unexpected_event = true;
203 break;
204 }
205 break;
206 case BTA_HH_W4_CONN_ST:
207 switch (event) {
208 case BTA_HH_API_CLOSE_EVT:
209 p_cb->state = BTA_HH_IDLE_ST;
210 break;
211 case BTA_HH_INT_OPEN_EVT:
212 bta_hh_open_act(p_cb, p_data);
213 break;
214 case BTA_HH_INT_CLOSE_EVT:
215 p_cb->state = BTA_HH_IDLE_ST;
216 bta_hh_open_failure(p_cb, p_data);
217 break;
218 case BTA_HH_SDP_CMPL_EVT:
219 bta_hh_sdp_cmpl(p_cb, p_data);
220 break;
221 case BTA_HH_API_WRITE_DEV_EVT:
222 bta_hh_write_dev_act(p_cb, p_data);
223 break;
224 case BTA_HH_API_MAINT_DEV_EVT:
225 p_cb->state = BTA_HH_IDLE_ST;
226 bta_hh_maint_dev_act(p_cb, p_data);
227 break;
228 case BTA_HH_OPEN_CMPL_EVT:
229 p_cb->state = BTA_HH_CONN_ST;
230 bta_hh_open_cmpl_act(p_cb, p_data);
231 break;
232 case BTA_HH_GATT_CLOSE_EVT:
233 p_cb->state = BTA_HH_IDLE_ST;
234 bta_hh_le_open_fail(p_cb, p_data);
235 break;
236 case BTA_HH_GATT_OPEN_EVT:
237 bta_hh_gatt_open(p_cb, p_data);
238 break;
239 case BTA_HH_START_ENC_EVT:
240 p_cb->state = BTA_HH_W4_SEC;
241 bta_hh_start_security(p_cb, p_data);
242 break;
243 default:
244 unexpected_event = true;
245 break;
246 }
247 break;
248 case BTA_HH_CONN_ST:
249 switch (event) {
250 case BTA_HH_API_CLOSE_EVT:
251 bta_hh_api_disc_act(p_cb, p_data);
252 break;
253 case BTA_HH_INT_OPEN_EVT:
254 bta_hh_open_act(p_cb, p_data);
255 break;
256 case BTA_HH_INT_CLOSE_EVT:
257 p_cb->state = BTA_HH_IDLE_ST;
258 bta_hh_close_act(p_cb, p_data);
259 break;
260 case BTA_HH_INT_DATA_EVT:
261 bta_hh_data_act(p_cb, p_data);
262 break;
263 case BTA_HH_INT_CTRL_DATA:
264 bta_hh_ctrl_dat_act(p_cb, p_data);
265 break;
266 case BTA_HH_INT_HANDSK_EVT:
267 bta_hh_handsk_act(p_cb, p_data);
268 break;
269 case BTA_HH_API_WRITE_DEV_EVT:
270 bta_hh_write_dev_act(p_cb, p_data);
271 break;
272 case BTA_HH_API_GET_DSCP_EVT:
273 bta_hh_get_dscp_act(p_cb, p_data);
274 break;
275 case BTA_HH_API_MAINT_DEV_EVT:
276 bta_hh_maint_dev_act(p_cb, p_data);
277 break;
278 case BTA_HH_GATT_CLOSE_EVT:
279 p_cb->state = BTA_HH_IDLE_ST;
280 bta_hh_gatt_close(p_cb, p_data);
281 break;
282 default:
283 unexpected_event = true;
284 break;
285 }
286 break;
287 case BTA_HH_W4_SEC:
288 switch (event) {
289 case BTA_HH_API_CLOSE_EVT:
290 bta_hh_api_disc_act(p_cb, p_data);
291 break;
292 case BTA_HH_INT_CLOSE_EVT:
293 p_cb->state = BTA_HH_IDLE_ST;
294 bta_hh_open_failure(p_cb, p_data);
295 break;
296 case BTA_HH_API_MAINT_DEV_EVT:
297 bta_hh_maint_dev_act(p_cb, p_data);
298 break;
299 case BTA_HH_GATT_CLOSE_EVT:
300 p_cb->state = BTA_HH_IDLE_ST;
301 bta_hh_le_open_fail(p_cb, p_data);
302 break;
303 case BTA_HH_ENC_CMPL_EVT:
304 p_cb->state = BTA_HH_W4_CONN_ST;
305 bta_hh_security_cmpl(p_cb, p_data);
306 break;
307 case BTA_HH_GATT_ENC_CMPL_EVT:
308 bta_hh_le_notify_enc_cmpl(p_cb, p_data);
309 break;
310 default:
311 unexpected_event = true;
312 break;
313 }
314 break;
315 }
316
317 if (unexpected_event) {
318 log::warn("Unexpected event event {} in state {} for {}", bta_hh_evt_code(event),
319 bta_hh_state_code(in_state), p_cb->link_spec);
320 } else if (in_state != p_cb->state) {
321 log::debug("State Change: [{}] -> [{}] after Event [{}]", bta_hh_state_code(in_state),
322 bta_hh_state_code(p_cb->state), bta_hh_evt_code(event));
323 }
324 }
325
326 /*******************************************************************************
327 *
328 * Function bta_hh_hdl_failure
329 *
330 * Description Handler for state machine failures
331 *
332 * Returns void
333 *
334 ******************************************************************************/
bta_hh_hdl_failure(tBTA_HH_INT_EVT event,const tBTA_HH_DATA * p_data)335 void bta_hh_hdl_failure(tBTA_HH_INT_EVT event, const tBTA_HH_DATA* p_data) {
336 if (bta_hh_cb.p_cback == nullptr) {
337 log::error("No callback handler");
338 return;
339 }
340
341 log::verbose("Event:{}", bta_hh_evt_code(event));
342 tBTA_HH cback_data = {};
343 tBTA_HH_EVT cback_event = BTA_HH_EMPTY_EVT;
344 switch (event) {
345 /* no control block available for new connection */
346 case BTA_HH_API_OPEN_EVT:
347 cback_event = BTA_HH_OPEN_EVT;
348 /* build cback data */
349 cback_data.conn.link_spec = ((tBTA_HH_API_CONN*)p_data)->link_spec;
350 cback_data.conn.status = BTA_HH_ERR_DB_FULL;
351 cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
352 break;
353 /* DB full, BTA_HhAddDev */
354 case BTA_HH_API_MAINT_DEV_EVT:
355 cback_event = p_data->api_maintdev.sub_event;
356
357 if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
358 cback_data.dev_info.link_spec = p_data->api_maintdev.link_spec;
359 cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
360 cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
361 } else {
362 cback_data.dev_info.status = BTA_HH_ERR_HDL;
363 cback_data.dev_info.handle = (uint8_t)p_data->api_maintdev.hdr.layer_specific;
364 }
365 break;
366 case BTA_HH_API_WRITE_DEV_EVT:
367 cback_event = (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) + BTA_HH_GET_RPT_EVT;
368 osi_free_and_reset((void**)&p_data->api_sndcmd.p_data);
369 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
370 p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
371 p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
372 cback_data.dev_status.status = BTA_HH_ERR_HDL;
373 cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
374 } else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
375 p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
376 cback_data.hs_data.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
377 cback_data.hs_data.status = BTA_HH_ERR_HDL;
378 /* hs_data.rsp_data will be all zero, which is not valid value */
379 } else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
380 p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
381 cback_data.status = BTA_HH_ERR_HDL;
382 cback_event = BTA_HH_VC_UNPLUG_EVT;
383 } else {
384 cback_event = 0;
385 }
386 break;
387
388 case BTA_HH_API_CLOSE_EVT:
389 cback_event = BTA_HH_CLOSE_EVT;
390 cback_data.dev_status.status = BTA_HH_ERR_HDL;
391 cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
392 break;
393
394 default:
395 /* Likely an invalid handle, call bad API event */
396 log::error("wrong device handle:{} in event:{}", p_data->hdr.layer_specific,
397 bta_hh_evt_code(event));
398 /* Free the callback buffer now */
399 if (p_data != nullptr) {
400 osi_free_and_reset((void**)&p_data->hid_cback.p_data);
401 }
402 break;
403 }
404
405 if (cback_event) {
406 (*bta_hh_cb.p_cback)(cback_event, &cback_data);
407 }
408 }
409
410 /*******************************************************************************
411 *
412 * Function bta_hh_hdl_event
413 *
414 * Description HID host main event handling function.
415 *
416 *
417 * Returns void
418 *
419 ******************************************************************************/
bta_hh_hdl_event(const BT_HDR_RIGID * p_msg)420 bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg) {
421 tBTA_HH_DEV_CB* p_cb = bta_hh_find_cb_by_event(p_msg);
422 tBTA_HH_INT_EVT event = static_cast<tBTA_HH_INT_EVT>(p_msg->event);
423
424 if (p_cb != nullptr) {
425 bta_hh_sm_execute(p_cb, event, (tBTA_HH_DATA*)p_msg);
426 } else {
427 bta_hh_hdl_failure(event, (tBTA_HH_DATA*)p_msg);
428 }
429
430 return true;
431 }
432
433 #define DUMPSYS_TAG "shim::legacy::hid"
bta_hh_dump(int fd)434 void bta_hh_dump(int fd) {
435 for (auto dev : bta_hh_cb.kdev) {
436 if (dev.in_use) {
437 LOG_DUMPSYS(fd, "[%d] Device:%s, handle:%d, state:%s, sub class:%d, ", dev.index,
438 dev.link_spec.ToRedactedStringForLogging().c_str(), dev.hid_handle,
439 bta_hh_state_code(dev.state), dev.sub_class);
440 }
441 }
442 }
443 #undef DUMPSYS_TAG
444