Home | History | Annotate | Download | only in hd
      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