1 /****************************************************************************** 2 * 3 * Copyright (C) 2016 The Android Open Source Project 4 * Copyright (C) 2005-2012 Broadcom Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 ******************************************************************************/ 19 20 /****************************************************************************** 21 * 22 * This file contains the HID host main functions and state machine. 23 * 24 ******************************************************************************/ 25 26 #include "bt_target.h" 27 28 #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE) 29 30 #include <string.h> 31 32 #include "bta_hd_api.h" 33 #include "bta_hd_int.h" 34 35 /***************************************************************************** 36 * Constants and types 37 ****************************************************************************/ 38 39 /* state machine states */ 40 enum { 41 BTA_HD_INIT_ST, 42 BTA_HD_IDLE_ST, /* not connected, waiting for connection */ 43 BTA_HD_CONN_ST, /* host connected */ 44 BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT 45 */ 46 }; 47 typedef uint8_t tBTA_HD_STATE; 48 49 /* state machine actions */ 50 enum { 51 BTA_HD_REGISTER_ACT, 52 BTA_HD_UNREGISTER_ACT, 53 BTA_HD_UNREGISTER2_ACT, 54 BTA_HD_CONNECT_ACT, 55 BTA_HD_DISCONNECT_ACT, 56 BTA_HD_ADD_DEVICE_ACT, 57 BTA_HD_REMOVE_DEVICE_ACT, 58 BTA_HD_SEND_REPORT_ACT, 59 BTA_HD_REPORT_ERROR_ACT, 60 BTA_HD_VC_UNPLUG_ACT, 61 62 BTA_HD_OPEN_ACT, 63 BTA_HD_CLOSE_ACT, 64 BTA_HD_INTR_DATA_ACT, 65 BTA_HD_GET_REPORT_ACT, 66 BTA_HD_SET_REPORT_ACT, 67 BTA_HD_SET_PROTOCOL_ACT, 68 BTA_HD_VC_UNPLUG_DONE_ACT, 69 BTA_HD_SUSPEND_ACT, 70 BTA_HD_EXIT_SUSPEND_ACT, 71 72 BTA_HD_NUM_ACTIONS 73 }; 74 75 #define BTA_HD_IGNORE BTA_HD_NUM_ACTIONS 76 77 typedef void (*tBTA_HD_ACTION)(tBTA_HD_DATA* p_data); 78 79 /* action functions */ 80 const tBTA_HD_ACTION bta_hd_action[] = { 81 bta_hd_register_act, bta_hd_unregister_act, bta_hd_unregister2_act, 82 bta_hd_connect_act, bta_hd_disconnect_act, bta_hd_add_device_act, 83 bta_hd_remove_device_act, bta_hd_send_report_act, bta_hd_report_error_act, 84 bta_hd_vc_unplug_act, 85 86 bta_hd_open_act, bta_hd_close_act, bta_hd_intr_data_act, 87 bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act, 88 bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, 89 }; 90 91 /* state table information */ 92 #define BTA_HD_ACTION 0 /* position of action */ 93 #define BTA_HD_NEXT_STATE 1 /* position of next state */ 94 #define BTA_HD_NUM_COLS 2 /* number of columns */ 95 96 const uint8_t bta_hd_st_init[][BTA_HD_NUM_COLS] = { 97 /* Event Action Next state 98 */ 99 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_REGISTER_ACT, BTA_HD_IDLE_ST}, 100 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 101 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 102 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 103 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_INIT_ST}, 104 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_INIT_ST}, 105 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 106 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 107 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 108 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 109 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 110 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 111 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 112 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 113 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 114 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 115 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 116 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_INIT_ST}, 117 }; 118 119 const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = { 120 /* Event Action Next state 121 */ 122 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 123 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_UNREGISTER_ACT, BTA_HD_INIT_ST}, 124 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_CONNECT_ACT, BTA_HD_IDLE_ST}, 125 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_IDLE_ST}, 126 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_IDLE_ST}, 127 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, BTA_HD_IDLE_ST}, 128 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, BTA_HD_IDLE_ST}, 129 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 130 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 131 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST}, 132 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_CLOSE_ACT, BTA_HD_IDLE_ST}, 133 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 134 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 135 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 136 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 137 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 138 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 139 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, 140 }; 141 142 const uint8_t bta_hd_st_conn[][BTA_HD_NUM_COLS] = { 143 /* Event Action Next state */ 144 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST}, 145 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_DISCONNECT_ACT, 146 BTA_HD_TRANSIENT_TO_INIT_ST}, 147 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST}, 148 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_DISCONNECT_ACT, BTA_HD_CONN_ST}, 149 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_ADD_DEVICE_ACT, BTA_HD_CONN_ST}, 150 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_REMOVE_DEVICE_ACT, 151 BTA_HD_CONN_ST}, 152 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_SEND_REPORT_ACT, 153 BTA_HD_CONN_ST}, 154 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_REPORT_ERROR_ACT, 155 BTA_HD_CONN_ST}, 156 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_CONN_ST}, 157 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, BTA_HD_CONN_ST}, 158 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_CLOSE_ACT, BTA_HD_IDLE_ST}, 159 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_INTR_DATA_ACT, BTA_HD_CONN_ST}, 160 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_GET_REPORT_ACT, BTA_HD_CONN_ST}, 161 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_SET_REPORT_ACT, BTA_HD_CONN_ST}, 162 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_SET_PROTOCOL_ACT, 163 BTA_HD_CONN_ST}, 164 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_DONE_ACT, 165 BTA_HD_IDLE_ST}, 166 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_SUSPEND_ACT, BTA_HD_CONN_ST}, 167 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_EXIT_SUSPEND_ACT, 168 BTA_HD_CONN_ST}, 169 }; 170 171 const uint8_t bta_hd_st_transient_to_init[][BTA_HD_NUM_COLS] = { 172 /* Event Action Next state */ 173 /* BTA_HD_API_REGISTER_APP_EVT */ {BTA_HD_IGNORE, 174 BTA_HD_TRANSIENT_TO_INIT_ST}, 175 /* BTA_HD_API_UNREGISTER_APP_EVT */ {BTA_HD_IGNORE, 176 BTA_HD_TRANSIENT_TO_INIT_ST}, 177 /* BTA_HD_API_CONNECT_EVT */ {BTA_HD_IGNORE, 178 BTA_HD_TRANSIENT_TO_INIT_ST}, 179 /* BTA_HD_API_DISCONNECT_EVT */ {BTA_HD_IGNORE, 180 BTA_HD_TRANSIENT_TO_INIT_ST}, 181 /* BTA_HD_API_ADD_DEVICE_EVT */ {BTA_HD_IGNORE, 182 BTA_HD_TRANSIENT_TO_INIT_ST}, 183 /* BTA_HD_API_REMOVE_DEVICE_EVT */ {BTA_HD_IGNORE, 184 BTA_HD_TRANSIENT_TO_INIT_ST}, 185 /* BTA_HD_API_SEND_REPORT_EVT */ {BTA_HD_IGNORE, 186 BTA_HD_TRANSIENT_TO_INIT_ST}, 187 /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, 188 BTA_HD_TRANSIENT_TO_INIT_ST}, 189 /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_IGNORE, 190 BTA_HD_TRANSIENT_TO_INIT_ST}, 191 /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_IGNORE, 192 BTA_HD_TRANSIENT_TO_INIT_ST}, 193 /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_UNREGISTER2_ACT, 194 BTA_HD_INIT_ST}, 195 /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, 196 BTA_HD_TRANSIENT_TO_INIT_ST}, 197 /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, 198 BTA_HD_TRANSIENT_TO_INIT_ST}, 199 /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, 200 BTA_HD_TRANSIENT_TO_INIT_ST}, 201 /* BTA_HD_INT_SET_PROTOCOL_EVT */ {BTA_HD_IGNORE, 202 BTA_HD_TRANSIENT_TO_INIT_ST}, 203 /* BTA_HD_INT_VC_UNPLUG_EVT */ {BTA_HD_UNREGISTER2_ACT, 204 BTA_HD_INIT_ST}, 205 /* BTA_HD_INT_SUSPEND_EVT */ {BTA_HD_IGNORE, 206 BTA_HD_TRANSIENT_TO_INIT_ST}, 207 /* BTA_HD_INT_EXIT_SUSPEND_EVT */ {BTA_HD_IGNORE, 208 BTA_HD_TRANSIENT_TO_INIT_ST}, 209 }; 210 211 /* type for state table */ 212 typedef const uint8_t (*tBTA_HD_ST_TBL)[BTA_HD_NUM_COLS]; 213 214 /* state table */ 215 const tBTA_HD_ST_TBL bta_hd_st_tbl[] = {bta_hd_st_init, bta_hd_st_idle, 216 bta_hd_st_conn, 217 bta_hd_st_transient_to_init}; 218 219 /***************************************************************************** 220 * Global data 221 ****************************************************************************/ 222 #if BTA_DYNAMIC_MEMORY == FALSE 223 tBTA_HD_CB bta_hd_cb; 224 #endif 225 226 static const char* bta_hd_evt_code(tBTA_HD_INT_EVT evt_code); 227 static const char* bta_hd_state_code(tBTA_HD_STATE state_code); 228 229 /******************************************************************************* 230 * 231 * Function bta_hd_sm_execute 232 * 233 * Description State machine event handling function for HID Device 234 * 235 * Returns void 236 * 237 ******************************************************************************/ 238 void bta_hd_sm_execute(uint16_t event, tBTA_HD_DATA* p_data) { 239 tBTA_HD_ST_TBL state_table; 240 tBTA_HD_STATE prev_state; 241 uint8_t action; 242 tBTA_HD cback_data; 243 244 APPL_TRACE_EVENT("%s: state=%s (%d) event=%s (%d)", __func__, 245 bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state, 246 bta_hd_evt_code(event), event); 247 248 prev_state = bta_hd_cb.state; 249 250 memset(&cback_data, 0, sizeof(tBTA_HD)); 251 252 state_table = bta_hd_st_tbl[bta_hd_cb.state]; 253 254 event &= 0xff; 255 256 action = state_table[event][BTA_HD_ACTION]; 257 if (action < BTA_HD_IGNORE) { 258 (*bta_hd_action[action])(p_data); 259 } 260 261 bta_hd_cb.state = state_table[event][BTA_HD_NEXT_STATE]; 262 263 if (bta_hd_cb.state != prev_state) { 264 APPL_TRACE_EVENT("%s: [new] state=%s (%d)", __func__, 265 bta_hd_state_code(bta_hd_cb.state), bta_hd_cb.state); 266 } 267 268 return; 269 } 270 271 /******************************************************************************* 272 * 273 * Function bta_hd_hdl_event 274 * 275 * Description HID device main event handling function. 276 * 277 * Returns void 278 * 279 ******************************************************************************/ 280 bool bta_hd_hdl_event(BT_HDR* p_msg) { 281 APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event); 282 283 switch (p_msg->event) { 284 case BTA_HD_API_ENABLE_EVT: 285 bta_hd_api_enable((tBTA_HD_DATA*)p_msg); 286 break; 287 288 case BTA_HD_API_DISABLE_EVT: 289 if (bta_hd_cb.state == BTA_HD_CONN_ST) { 290 APPL_TRACE_WARNING("%s: host connected, disconnect before disabling", 291 __func__); 292 293 // unregister (and disconnect) 294 bta_hd_cb.disable_w4_close = TRUE; 295 bta_hd_sm_execute(BTA_HD_API_UNREGISTER_APP_EVT, (tBTA_HD_DATA*)p_msg); 296 } else { 297 bta_hd_api_disable(); 298 } 299 break; 300 301 default: 302 bta_hd_sm_execute(p_msg->event, (tBTA_HD_DATA*)p_msg); 303 } 304 return (TRUE); 305 } 306 307 static const char* bta_hd_evt_code(tBTA_HD_INT_EVT evt_code) { 308 switch (evt_code) { 309 case BTA_HD_API_REGISTER_APP_EVT: 310 return "BTA_HD_API_REGISTER_APP_EVT"; 311 case BTA_HD_API_UNREGISTER_APP_EVT: 312 return "BTA_HD_API_UNREGISTER_APP_EVT"; 313 case BTA_HD_API_CONNECT_EVT: 314 return "BTA_HD_API_CONNECT_EVT"; 315 case BTA_HD_API_DISCONNECT_EVT: 316 return "BTA_HD_API_DISCONNECT_EVT"; 317 case BTA_HD_API_ADD_DEVICE_EVT: 318 return "BTA_HD_API_ADD_DEVICE_EVT"; 319 case BTA_HD_API_REMOVE_DEVICE_EVT: 320 return "BTA_HD_API_REMOVE_DEVICE_EVT"; 321 case BTA_HD_API_SEND_REPORT_EVT: 322 return "BTA_HD_API_SEND_REPORT_EVT"; 323 case BTA_HD_API_REPORT_ERROR_EVT: 324 return "BTA_HD_API_REPORT_ERROR_EVT"; 325 case BTA_HD_API_VC_UNPLUG_EVT: 326 return "BTA_HD_API_VC_UNPLUG_EVT"; 327 case BTA_HD_INT_OPEN_EVT: 328 return "BTA_HD_INT_OPEN_EVT"; 329 case BTA_HD_INT_CLOSE_EVT: 330 return "BTA_HD_INT_CLOSE_EVT"; 331 case BTA_HD_INT_INTR_DATA_EVT: 332 return "BTA_HD_INT_INTR_DATA_EVT"; 333 case BTA_HD_INT_GET_REPORT_EVT: 334 return "BTA_HD_INT_GET_REPORT_EVT"; 335 case BTA_HD_INT_SET_REPORT_EVT: 336 return "BTA_HD_INT_SET_REPORT_EVT"; 337 case BTA_HD_INT_SET_PROTOCOL_EVT: 338 return "BTA_HD_INT_SET_PROTOCOL_EVT"; 339 case BTA_HD_INT_VC_UNPLUG_EVT: 340 return "BTA_HD_INT_VC_UNPLUG_EVT"; 341 case BTA_HD_INT_SUSPEND_EVT: 342 return "BTA_HD_INT_SUSPEND_EVT"; 343 case BTA_HD_INT_EXIT_SUSPEND_EVT: 344 return "BTA_HD_INT_EXIT_SUSPEND_EVT"; 345 default: 346 return "<unknown>"; 347 } 348 } 349 350 static const char* bta_hd_state_code(tBTA_HD_STATE state_code) { 351 switch (state_code) { 352 case BTA_HD_INIT_ST: 353 return "BTA_HD_INIT_ST"; 354 case BTA_HD_IDLE_ST: 355 return "BTA_HD_IDLE_ST"; 356 case BTA_HD_CONN_ST: 357 return "BTA_HD_CONN_ST"; 358 case BTA_HD_TRANSIENT_TO_INIT_ST: 359 return "BTA_HD_TRANSIENT_TO_INIT_ST"; 360 default: 361 return "<unknown>"; 362 } 363 } 364 365 #endif /* BTA_HD_INCLUDED */ 366