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