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