blob: 1d565e03a476b256c34ec5565930142961ddb2ca [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 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 "bt_target.h"
26
Marie Janssene9e58ce2016-06-17 14:12:17 -070027#if (BTA_HH_INCLUDED == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -080028
29#include <string.h>
30
31#include "bta_hh_api.h"
32#include "bta_hh_int.h"
Pavlin Radoslavov258c2532015-09-27 20:59:05 -070033#include "bt_common.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080034
35/*****************************************************************************
36** Constants and types
37*****************************************************************************/
38
39/* state machine action enumeration list */
40enum
41{
42 BTA_HH_API_DISC_ACT, /* HID host process API close action */
43 BTA_HH_OPEN_ACT, /* HID host process BTA_HH_EVT_OPEN */
44 BTA_HH_CLOSE_ACT, /* HID host process BTA_HH_EVT_CLOSE */
45 BTA_HH_DATA_ACT, /* HID host receive data report */
46 BTA_HH_CTRL_DAT_ACT,
47 BTA_HH_HANDSK_ACT,
48 BTA_HH_START_SDP, /* HID host inquery */
49 BTA_HH_SDP_CMPL,
50 BTA_HH_WRITE_DEV_ACT,
51 BTA_HH_GET_DSCP_ACT,
52 BTA_HH_MAINT_DEV_ACT,
53 BTA_HH_OPEN_CMPL_ACT,
Andre Eisenbach2e7fa682013-08-08 15:42:48 -070054 BTA_HH_OPEN_FAILURE,
Marie Janssene9e58ce2016-06-17 14:12:17 -070055#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -070056 BTA_HH_GATT_CLOSE,
57 BTA_HH_LE_OPEN_FAIL,
58 BTA_HH_GATT_OPEN,
59 BTA_HH_W4_LE_READ_CHAR,
60 BTA_HH_LE_READ_CHAR,
61 BTA_HH_W4_LE_READ_DESCR,
62 BTA_HH_LE_READ_DESCR,
63 BTA_HH_W4_LE_WRITE,
64 BTA_HH_LE_WRITE,
65 BTA_HH_WRITE_DESCR,
66 BTA_HH_START_SEC,
67 BTA_HH_SEC_CMPL,
Zhihai Xu7051db32013-11-12 20:18:37 -080068 BTA_HH_GATT_ENC_CMPL,
Andre Eisenbach2e7fa682013-08-08 15:42:48 -070069#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -080070 BTA_HH_NUM_ACTIONS
71};
72
73#define BTA_HH_IGNORE BTA_HH_NUM_ACTIONS
74
75/* type for action functions */
76typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
77
78/* action functions */
79const tBTA_HH_ACTION bta_hh_action[] =
80{
81 bta_hh_api_disc_act,
82 bta_hh_open_act,
83 bta_hh_close_act,
84 bta_hh_data_act,
85 bta_hh_ctrl_dat_act,
86 bta_hh_handsk_act,
87 bta_hh_start_sdp,
88 bta_hh_sdp_cmpl,
89 bta_hh_write_dev_act,
90 bta_hh_get_dscp_act,
91 bta_hh_maint_dev_act,
Andre Eisenbach2e7fa682013-08-08 15:42:48 -070092 bta_hh_open_cmpl_act,
93 bta_hh_open_failure
Marie Janssene9e58ce2016-06-17 14:12:17 -070094#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -070095 ,bta_hh_gatt_close
96 ,bta_hh_le_open_fail
97 ,bta_hh_gatt_open
98 ,bta_hh_w4_le_read_char_cmpl
99 ,bta_hh_le_read_char_cmpl
100 ,bta_hh_w4_le_read_descr_cmpl
101 ,bta_hh_le_read_descr_cmpl
102 ,bta_hh_w4_le_write_cmpl
103 ,bta_hh_le_write_cmpl
104 ,bta_hh_le_write_char_descr_cmpl
105 ,bta_hh_start_security
106 ,bta_hh_security_cmpl
Zhihai Xu7051db32013-11-12 20:18:37 -0800107 ,bta_hh_le_notify_enc_cmpl
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700108#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800109};
110
111/* state table information */
112#define BTA_HH_ACTION 0 /* position of action */
113#define BTA_HH_NEXT_STATE 1 /* position of next state */
114#define BTA_HH_NUM_COLS 2 /* number of columns */
115
116/* state table for idle state */
Marie Janssene9e58ce2016-06-17 14:12:17 -0700117const uint8_t bta_hh_st_idle[][BTA_HH_NUM_COLS] =
The Android Open Source Project5738f832012-12-12 16:00:35 -0800118{
119/* Event Action Next state */
120/* BTA_HH_API_OPEN_EVT */ {BTA_HH_START_SDP, BTA_HH_W4_CONN_ST },
121/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
122/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
123/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
124/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
125/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
126/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
127/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
128/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
129/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
130/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800131/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
Marie Janssene9e58ce2016-06-17 14:12:17 -0700132#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700133/* BTA_HH_GATT_CLOSE_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
134/* BTA_HH_GATT_OPEN_EVT */ ,{BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
135/* BTA_HH_START_ENC_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
136/* BTA_HH_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
137/* READ_CHAR_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
138/* BTA_HH_GATT_WRITE_CMPL_EVT*/ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
139/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
140/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
Zhihai Xu7051db32013-11-12 20:18:37 -0800141/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_IDLE_ST }
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700142#endif
143
The Android Open Source Project5738f832012-12-12 16:00:35 -0800144};
145
146
Marie Janssene9e58ce2016-06-17 14:12:17 -0700147const uint8_t bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] =
The Android Open Source Project5738f832012-12-12 16:00:35 -0800148{
149/* Event Action Next state */
150/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
151/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
152/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700153/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
The Android Open Source Project5738f832012-12-12 16:00:35 -0800154/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
155/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
156/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
157/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_SDP_CMPL, BTA_HH_W4_CONN_ST },
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700158/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
The Android Open Source Project5738f832012-12-12 16:00:35 -0800159/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
160/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800161/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
Marie Janssene9e58ce2016-06-17 14:12:17 -0700162#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700163/* BTA_HH_GATT_CLOSE_EVT */ ,{BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST }
164/* BTA_HH_GATT_OPEN_EVT */ ,{BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
165/* BTA_HH_START_ENC_EVT */ ,{BTA_HH_START_SEC, BTA_HH_W4_SEC }
166/* BTA_HH_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
167/* READ_CHAR_CMPL_EVT */ ,{BTA_HH_W4_LE_READ_CHAR, BTA_HH_W4_CONN_ST }
168/* BTA_HH_GATT_WRITE_CMPL_EVT*/ ,{BTA_HH_W4_LE_WRITE, BTA_HH_W4_CONN_ST }
169/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST }
170/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_WRITE_DESCR, BTA_HH_W4_CONN_ST }
Zhihai Xu7051db32013-11-12 20:18:37 -0800171/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700172#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800173};
174
175
Marie Janssene9e58ce2016-06-17 14:12:17 -0700176const uint8_t bta_hh_st_connected[][BTA_HH_NUM_COLS] =
The Android Open Source Project5738f832012-12-12 16:00:35 -0800177{
178/* Event Action Next state */
179/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
180/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_CONN_ST },
181/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_CONN_ST },
182/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
183/* BTA_HH_INT_DATA_EVT */ {BTA_HH_DATA_ACT, BTA_HH_CONN_ST },
184/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_CTRL_DAT_ACT, BTA_HH_CONN_ST },
185/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_HANDSK_ACT, BTA_HH_CONN_ST },
186/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
187/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST },
188/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_GET_DSCP_ACT, BTA_HH_CONN_ST },
189/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST },
190/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST }
Marie Janssene9e58ce2016-06-17 14:12:17 -0700191#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700192/* BTA_HH_GATT_CLOSE_EVT */ ,{BTA_HH_GATT_CLOSE, BTA_HH_IDLE_ST }
193/* BTA_HH_GATT_OPEN_EVT */ ,{BTA_HH_IGNORE, BTA_HH_CONN_ST }
194/* BTA_HH_START_ENC_EVT */ ,{BTA_HH_IGNORE, BTA_HH_CONN_ST }
195/* BTA_HH_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_CONN_ST }
196/* READ_CHAR_CMPL_EVT */ ,{BTA_HH_LE_READ_CHAR, BTA_HH_CONN_ST }
197/* WRITE_CHAR_CMPL_EVT*/ ,{BTA_HH_LE_WRITE, BTA_HH_CONN_ST }
198/* READ_DESCR_CMPL_EVT */ ,{BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST } /* do not currently read any descr when connection up */
199/* WRITE_DESCR_CMPL_EVT */ ,{BTA_HH_WRITE_DESCR, BTA_HH_CONN_ST } /* do not currently write any descr when connection up */
Zhihai Xu7051db32013-11-12 20:18:37 -0800200/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_IGNORE, BTA_HH_CONN_ST }
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700201#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800202};
Marie Janssene9e58ce2016-06-17 14:12:17 -0700203#if (BTA_HH_LE_INCLUDED == TRUE)
204const uint8_t bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] =
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700205{
206/* Event Action Next state */
207/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
208/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_W4_SEC },
209/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
210/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
211/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
212/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
213/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
214/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
215/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE , BTA_HH_W4_SEC },
216/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
217/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC },
218/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
219/* BTA_HH_GATT_CLOSE_EVT */ {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST },
220/* BTA_HH_GATT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
221/* BTA_HH_START_ENC_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
222/* BTA_HH_ENC_CMPL_EVT */ {BTA_HH_SEC_CMPL, BTA_HH_W4_CONN_ST },
223/* READ_CHAR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
224/* BTA_HH_GATT_WRITE_CMPL_EVT*/ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
225/* READ_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
226/* WRITE_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC }
Zhihai Xu7051db32013-11-12 20:18:37 -0800227/* BTA_HH_GATT_ENC_CMPL_EVT */ ,{BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC }
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700228};
229#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800230
231/* type for state table */
Marie Janssene9e58ce2016-06-17 14:12:17 -0700232typedef const uint8_t (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
The Android Open Source Project5738f832012-12-12 16:00:35 -0800233
234/* state table */
235const tBTA_HH_ST_TBL bta_hh_st_tbl[] =
236{
237 bta_hh_st_idle,
238 bta_hh_st_w4_conn,
239 bta_hh_st_connected
Marie Janssene9e58ce2016-06-17 14:12:17 -0700240#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700241 ,bta_hh_st_w4_sec
242#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800243};
244
245/*****************************************************************************
246** Global data
247*****************************************************************************/
Marie Janssene9e58ce2016-06-17 14:12:17 -0700248#if (BTA_DYNAMIC_MEMORY == FALSE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800249tBTA_HH_CB bta_hh_cb;
250#endif
251/*****************************************************************************
252** Static functions
253*****************************************************************************/
Marie Janssene9e58ce2016-06-17 14:12:17 -0700254#if (BTA_HH_DEBUG == TRUE)
Jakub Pawlowskib7938c12016-05-26 17:57:22 -0700255static const char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
256static const char *bta_hh_state_code(tBTA_HH_STATE state_code);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800257#endif
258
259/*******************************************************************************
260**
261** Function bta_hh_sm_execute
262**
263** Description State machine event handling function for HID Host
264**
265**
266** Returns void
267**
268*******************************************************************************/
Marie Janssene9e58ce2016-06-17 14:12:17 -0700269void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, uint16_t event, tBTA_HH_DATA * p_data)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800270{
271 tBTA_HH_ST_TBL state_table;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700272 uint8_t action;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800273 tBTA_HH cback_data;
274 tBTA_HH_EVT cback_event = 0;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700275#if (BTA_HH_DEBUG == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800276 tBTA_HH_STATE in_state ;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700277 uint16_t debug_event = event;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800278#endif
279
280 memset(&cback_data, 0, sizeof(tBTA_HH));
281
282 /* handle exception, no valid control block was found */
283 if (!p_cb)
284 {
285 /* BTA HH enabled already? otherwise ignore the event although it's bad*/
286 if (bta_hh_cb.p_cback != NULL)
287 {
288 switch (event)
289 {
290 /* no control block available for new connection */
291 case BTA_HH_API_OPEN_EVT:
292 cback_event = BTA_HH_OPEN_EVT;
293 /* build cback data */
294 bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
295 cback_data.conn.status = BTA_HH_ERR_DB_FULL;
296 cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
297 break;
298 /* DB full, BTA_HhAddDev */
299 case BTA_HH_API_MAINT_DEV_EVT:
300 cback_event = p_data->api_maintdev.sub_event;
301
302 if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT)
303 {
304 bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
305 cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
306 cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
307 }
308 else
309 {
310 cback_data.dev_info.status = BTA_HH_ERR_HDL;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700311 cback_data.dev_info.handle = (uint8_t)p_data->api_maintdev.hdr.layer_specific;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800312 }
313 break;
314 case BTA_HH_API_WRITE_DEV_EVT:
315 cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
316 BTA_HH_FST_TRANS_CB_EVT;
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -0800317 osi_free_and_reset((void **)&p_data->api_sndcmd.p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800318 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
319 p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
320 p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE)
321 {
322 cback_data.dev_status.status = BTA_HH_ERR_HDL;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700323 cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800324 }
325 else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
326 p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
327 {
Marie Janssene9e58ce2016-06-17 14:12:17 -0700328 cback_data.hs_data.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800329 cback_data.hs_data.status = BTA_HH_ERR_HDL;
330 /* hs_data.rsp_data will be all zero, which is not valid value */
331 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800332 else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
333 p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
334 {
335 cback_data.status = BTA_HH_ERR_HDL;
336 cback_event = BTA_HH_VC_UNPLUG_EVT;
337 }
338 else
339 cback_event = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800340 break;
341
342 case BTA_HH_API_CLOSE_EVT:
343 cback_event = BTA_HH_CLOSE_EVT;
344
345 cback_data.dev_status.status = BTA_HH_ERR_HDL;
Marie Janssene9e58ce2016-06-17 14:12:17 -0700346 cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800347 break;
348
349 default:
350 /* invalid handle, call bad API event */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700351 APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
Zhihai Xu2cba29a2013-11-24 16:23:55 +0530352 /* Free the callback buffer now */
Pavlin Radoslavov20524d32016-02-02 18:12:08 -0800353 if (p_data != NULL)
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -0800354 osi_free_and_reset((void **)&p_data->hid_cback.p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800355 break;
356 }
357 if (cback_event)
358 (* bta_hh_cb.p_cback)(cback_event, &cback_data);
359 }
360 }
361 /* corresponding CB is found, go to state machine */
362 else
363 {
Marie Janssene9e58ce2016-06-17 14:12:17 -0700364#if (BTA_HH_DEBUG == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800365 in_state = p_cb->state;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700366 APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800367 in_state, bta_hh_state_code(in_state),
368 bta_hh_evt_code(debug_event));
369#endif
370
Harish Paryanida8b1f62013-08-27 14:52:03 -0700371 if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST))
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700372 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700373 APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
Harish Paryanida8b1f62013-08-27 14:52:03 -0700374 p_cb->state,event);
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700375 return;
376 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800377 state_table = bta_hh_st_tbl[p_cb->state - 1];
378
379 event &= 0xff;
380
381 p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
382
383 if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE)
384 {
385 (*bta_hh_action[action])(p_cb, p_data);
386 }
387
Marie Janssene9e58ce2016-06-17 14:12:17 -0700388#if (BTA_HH_DEBUG == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800389 if (in_state != p_cb->state)
390 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700391 APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800392 bta_hh_state_code(in_state),
393 bta_hh_state_code(p_cb->state),
394 bta_hh_evt_code(debug_event));
395 }
396#endif
397 }
398
399 return;
400}
401/*******************************************************************************
402**
403** Function bta_hh_hdl_event
404**
405** Description HID host main event handling function.
406**
407**
408** Returns void
409**
410*******************************************************************************/
Marie Janssene9e58ce2016-06-17 14:12:17 -0700411bool bta_hh_hdl_event(BT_HDR *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800412{
Marie Janssene9e58ce2016-06-17 14:12:17 -0700413 uint8_t index = BTA_HH_IDX_INVALID;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800414 tBTA_HH_DEV_CB *p_cb = NULL;
415
416 switch (p_msg->event)
417 {
418 case BTA_HH_API_ENABLE_EVT:
419 bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
420 break;
421
422 case BTA_HH_API_DISABLE_EVT:
423 bta_hh_api_disable();
424 break;
425
426 case BTA_HH_DISC_CMPL_EVT: /* disable complete */
427 bta_hh_disc_cmpl();
428 break;
429
430 default:
431 /* all events processed in state machine need to find corresponding
432 CB before proceed */
433 if (p_msg->event == BTA_HH_API_OPEN_EVT)
434 {
435 index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
436 }
437 else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
438 {
439 /* if add device */
440 if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
441 {
442 index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
443 }
444 else /* else remove device by handle */
445 {
Marie Janssene9e58ce2016-06-17 14:12:17 -0700446 index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800447 /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
448 * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
449 * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
Marie Janssene9e58ce2016-06-17 14:12:17 -0700450 * So if REMOVE_DEVICE is called and in_use is false then we should treat this as a NULL p_cb. Hence we
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800451 * force the index to be IDX_INVALID
The Android Open Source Project5738f832012-12-12 16:00:35 -0800452 */
Zhihai Xufac9fef2013-09-29 15:12:55 -0700453 if ((index != BTA_HH_IDX_INVALID) &&
Marie Janssene9e58ce2016-06-17 14:12:17 -0700454 (bta_hh_cb.kdev[index].in_use == false)) {
Zhihai Xufac9fef2013-09-29 15:12:55 -0700455 index = BTA_HH_IDX_INVALID;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800456 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800457 }
458 }
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700459 else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
460 {
461 index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
462 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800463 else
Marie Janssene9e58ce2016-06-17 14:12:17 -0700464 index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800465
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800466 if (index != BTA_HH_IDX_INVALID)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800467 p_cb = &bta_hh_cb.kdev[index];
468
Marie Janssene9e58ce2016-06-17 14:12:17 -0700469#if (BTA_HH_DEBUG == TRUE)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700470 APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800471#endif
472 bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
473 }
Marie Janssene9e58ce2016-06-17 14:12:17 -0700474 return (true);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800475}
476
477/*****************************************************************************
478** Debug Functions
479*****************************************************************************/
Marie Janssene9e58ce2016-06-17 14:12:17 -0700480#if (BTA_HH_DEBUG == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800481/*******************************************************************************
482**
483** Function bta_hh_evt_code
484**
485** Description
486**
487** Returns void
488**
489*******************************************************************************/
Jakub Pawlowskib7938c12016-05-26 17:57:22 -0700490static const char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800491{
492 switch(evt_code)
493 {
494 case BTA_HH_API_DISABLE_EVT:
495 return "BTA_HH_API_DISABLE_EVT";
496 case BTA_HH_API_ENABLE_EVT:
497 return "BTA_HH_API_ENABLE_EVT";
498 case BTA_HH_API_OPEN_EVT:
499 return "BTA_HH_API_OPEN_EVT";
500 case BTA_HH_API_CLOSE_EVT:
501 return "BTA_HH_API_CLOSE_EVT";
502 case BTA_HH_INT_OPEN_EVT:
503 return "BTA_HH_INT_OPEN_EVT";
504 case BTA_HH_INT_CLOSE_EVT:
505 return "BTA_HH_INT_CLOSE_EVT";
506 case BTA_HH_INT_HANDSK_EVT:
507 return "BTA_HH_INT_HANDSK_EVT";
508 case BTA_HH_INT_DATA_EVT:
509 return "BTA_HH_INT_DATA_EVT";
510 case BTA_HH_INT_CTRL_DATA:
511 return "BTA_HH_INT_CTRL_DATA";
512 case BTA_HH_API_WRITE_DEV_EVT:
513 return "BTA_HH_API_WRITE_DEV_EVT";
514 case BTA_HH_SDP_CMPL_EVT:
515 return "BTA_HH_SDP_CMPL_EVT";
516 case BTA_HH_DISC_CMPL_EVT:
517 return "BTA_HH_DISC_CMPL_EVT";
518 case BTA_HH_API_MAINT_DEV_EVT:
519 return "BTA_HH_API_MAINT_DEV_EVT";
520 case BTA_HH_API_GET_DSCP_EVT:
521 return "BTA_HH_API_GET_DSCP_EVT";
522 case BTA_HH_OPEN_CMPL_EVT:
523 return "BTA_HH_OPEN_CMPL_EVT";
Marie Janssene9e58ce2016-06-17 14:12:17 -0700524#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700525 case BTA_HH_GATT_CLOSE_EVT:
526 return "BTA_HH_GATT_CLOSE_EVT";
527 case BTA_HH_GATT_OPEN_EVT:
528 return "BTA_HH_GATT_OPEN_EVT";
529 case BTA_HH_START_ENC_EVT:
530 return "BTA_HH_START_ENC_EVT";
531 case BTA_HH_ENC_CMPL_EVT:
532 return "BTA_HH_ENC_CMPL_EVT";
533 case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
534 return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
535 case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
536 return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
537 case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
538 return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
539 case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
540 return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
541#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800542 default:
543 return "unknown HID Host event code";
544 }
545}
546
547/*******************************************************************************
548**
549** Function bta_hh_state_code
550**
551** Description get string representation of HID host state code.
552**
553** Returns void
554**
555*******************************************************************************/
Jakub Pawlowskib7938c12016-05-26 17:57:22 -0700556static const char *bta_hh_state_code(tBTA_HH_STATE state_code)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800557{
558 switch (state_code)
559 {
560 case BTA_HH_NULL_ST:
561 return"BTA_HH_NULL_ST";
562 case BTA_HH_IDLE_ST:
563 return "BTA_HH_IDLE_ST";
564 case BTA_HH_W4_CONN_ST:
565 return "BTA_HH_W4_CONN_ST";
566 case BTA_HH_CONN_ST:
567 return "BTA_HH_CONN_ST";
Marie Janssene9e58ce2016-06-17 14:12:17 -0700568#if (BTA_HH_LE_INCLUDED == TRUE)
Andre Eisenbach2e7fa682013-08-08 15:42:48 -0700569 case BTA_HH_W4_SEC:
570 return "BTA_HH_W4_SEC";
571#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800572 default:
573 return "unknown HID Host state";
574 }
575}
576
577#endif /* Debug Functions */
578
579#endif /* BTA_HH_INCLUDED */