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