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