• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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