Home | History | Annotate | Download | only in hh
      1 /******************************************************************************
      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 
     27 #if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
     28 
     29 #include <string.h>
     30 
     31 #include "bta_hh_api.h"
     32 #include "bta_hh_int.h"
     33 #include "gki.h"
     34 
     35 /*****************************************************************************
     36 ** Constants and types
     37 *****************************************************************************/
     38 
     39 /* state machine action enumeration list */
     40 enum
     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,
     54     BTA_HH_OPEN_FAILURE,
     55 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
     56     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,
     68     BTA_HH_LE_UPDATE_SCPP,
     69     BTA_HH_GATT_ENC_CMPL,
     70 #endif
     71     BTA_HH_NUM_ACTIONS
     72 };
     73 
     74 #define BTA_HH_IGNORE       BTA_HH_NUM_ACTIONS
     75 
     76 /* type for action functions */
     77 typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
     78 
     79 /* action functions */
     80 const tBTA_HH_ACTION bta_hh_action[] =
     81 {
     82     bta_hh_api_disc_act,
     83     bta_hh_open_act,
     84     bta_hh_close_act,
     85     bta_hh_data_act,
     86     bta_hh_ctrl_dat_act,
     87     bta_hh_handsk_act,
     88     bta_hh_start_sdp,
     89     bta_hh_sdp_cmpl,
     90     bta_hh_write_dev_act,
     91     bta_hh_get_dscp_act,
     92     bta_hh_maint_dev_act,
     93     bta_hh_open_cmpl_act,
     94     bta_hh_open_failure
     95 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
     96     ,bta_hh_gatt_close
     97     ,bta_hh_le_open_fail
     98     ,bta_hh_gatt_open
     99     ,bta_hh_w4_le_read_char_cmpl
    100     ,bta_hh_le_read_char_cmpl
    101     ,bta_hh_w4_le_read_descr_cmpl
    102     ,bta_hh_le_read_descr_cmpl
    103     ,bta_hh_w4_le_write_cmpl
    104     ,bta_hh_le_write_cmpl
    105     ,bta_hh_le_write_char_descr_cmpl
    106     ,bta_hh_start_security
    107     ,bta_hh_security_cmpl
    108     ,bta_hh_le_update_scpp
    109     ,bta_hh_le_notify_enc_cmpl
    110 #endif
    111 };
    112 
    113 /* state table information */
    114 #define BTA_HH_ACTION                   0       /* position of action */
    115 #define BTA_HH_NEXT_STATE               1       /* position of next state */
    116 #define BTA_HH_NUM_COLS                 2       /* number of columns */
    117 
    118 /* state table for idle state */
    119 const UINT8 bta_hh_st_idle[][BTA_HH_NUM_COLS] =
    120 {
    121 /* Event                          Action                    Next state */
    122 /* BTA_HH_API_OPEN_EVT      */    {BTA_HH_START_SDP,     BTA_HH_W4_CONN_ST },
    123 /* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    124 /* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_W4_CONN_ST },
    125 /* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_CLOSE_ACT,     BTA_HH_IDLE_ST    },
    126 /* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    127 /* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    128 /* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    129 /* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    130 /* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    131 /* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    132 /* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST    },
    133 /* BTA_HH_OPEN_CMPL_EVT        */  {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST    }
    134 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    135 /* BTA_HH_GATT_CLOSE_EVT    */   ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
    136 /* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_GATT_OPEN,      BTA_HH_W4_CONN_ST }
    137 /* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
    138 /* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,         BTA_HH_IDLE_ST    }
    139 /* READ_CHAR_CMPL_EVT */         ,{BTA_HH_IGNORE,       BTA_HH_IDLE_ST  }
    140 /* BTA_HH_GATT_WRITE_CMPL_EVT*/    ,{BTA_HH_IGNORE,       BTA_HH_IDLE_ST  }
    141 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST  }
    142 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
    143 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
    144 /* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
    145 #endif
    146 
    147 };
    148 
    149 
    150 const UINT8 bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] =
    151 {
    152 /* Event                          Action                 Next state */
    153 /* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
    154 /* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_IGNORE,        BTA_HH_IDLE_ST    },
    155 /* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_W4_CONN_ST },
    156 /* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_OPEN_FAILURE,  BTA_HH_IDLE_ST    },
    157 /* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
    158 /* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
    159 /* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
    160 /* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_SDP_CMPL,      BTA_HH_W4_CONN_ST },
    161 /* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
    162 /* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST },
    163 /* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST    },
    164 /* BTA_HH_OPEN_CMPL_EVT     */    {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST    }
    165 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    166 /* BTA_HH_GATT_CLOSE_EVT    */   ,{BTA_HH_LE_OPEN_FAIL,  BTA_HH_IDLE_ST    }
    167 /* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_GATT_OPEN,     BTA_HH_W4_CONN_ST }
    168 /* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_START_SEC,     BTA_HH_W4_SEC     }
    169 /* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST }
    170 /* READ_CHAR_CMPL_EVT */        ,{BTA_HH_W4_LE_READ_CHAR,    BTA_HH_W4_CONN_ST  }
    171 /* BTA_HH_GATT_WRITE_CMPL_EVT*/  ,{BTA_HH_W4_LE_WRITE,    BTA_HH_W4_CONN_ST  }
    172 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST  }
    173 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_W4_CONN_ST   }
    174 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_W4_CONN_ST   }
    175 /* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST }
    176 #endif
    177 };
    178 
    179 
    180 const UINT8 bta_hh_st_connected[][BTA_HH_NUM_COLS] =
    181 {
    182 /* Event                          Action                 Next state */
    183 /* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_CONN_ST    },
    184 /* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_API_DISC_ACT,  BTA_HH_CONN_ST    },
    185 /* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_OPEN_ACT,      BTA_HH_CONN_ST    },
    186 /* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_CLOSE_ACT,     BTA_HH_IDLE_ST    },
    187 /* BTA_HH_INT_DATA_EVT      */    {BTA_HH_DATA_ACT,      BTA_HH_CONN_ST    },
    188 /* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_CTRL_DAT_ACT,  BTA_HH_CONN_ST    },
    189 /* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_HANDSK_ACT,    BTA_HH_CONN_ST    },
    190 /* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,         BTA_HH_CONN_ST       },
    191 /* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST    },
    192 /* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_GET_DSCP_ACT,  BTA_HH_CONN_ST    },
    193 /* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST    },
    194 /* BTA_HH_OPEN_CMPL_EVT        */    {BTA_HH_IGNORE,         BTA_HH_CONN_ST    }
    195 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    196 /* BTA_HH_GATT_CLOSE_EVT    */    ,{BTA_HH_GATT_CLOSE,    BTA_HH_IDLE_ST    }
    197 /* BTA_HH_GATT_OPEN_EVT    */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST    }
    198 /* BTA_HH_START_ENC_EVT    */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
    199 /* BTA_HH_ENC_CMPL_EVT     */    ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
    200 /* READ_CHAR_CMPL_EVT */         ,{BTA_HH_LE_READ_CHAR,  BTA_HH_CONN_ST     }
    201 /* WRITE_CHAR_CMPL_EVT*/         ,{BTA_HH_LE_WRITE,      BTA_HH_CONN_ST     }
    202 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST     }   /* do not currently read any descr when connection up */
    203 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_CONN_ST     }   /* do not currently write any descr when connection up */
    204 /* SCPP_UPDATE_EVT */            ,{BTA_HH_LE_UPDATE_SCPP,  BTA_HH_CONN_ST   }
    205 /* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
    206 #endif
    207 };
    208 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    209 const UINT8 bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] =
    210 {
    211 /* Event                          Action                 Next state */
    212 /* BTA_HH_API_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    213 /* BTA_HH_API_CLOSE_EVT     */    {BTA_HH_API_DISC_ACT,  BTA_HH_W4_SEC  },
    214 /* BTA_HH_INT_OPEN_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    215 /* BTA_HH_INT_CLOSE_EVT     */    {BTA_HH_OPEN_FAILURE,  BTA_HH_IDLE_ST },
    216 /* BTA_HH_INT_DATA_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    217 /* BTA_HH_INT_CTRL_DATA     */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    218 /* BTA_HH_INT_HANDSK_EVT    */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    219 /* BTA_HH_SDP_CMPL_EVT      */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    220 /* BTA_HH_API_WRITE_DEV_EVT */    {BTA_HH_IGNORE  ,      BTA_HH_W4_SEC  },
    221 /* BTA_HH_API_GET_DSCP_EVT  */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    222 /* BTA_HH_API_MAINT_DEV_EVT */    {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC  },
    223 /* BTA_HH_OPEN_CMPL_EVT     */    {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    224 /* BTA_HH_GATT_CLOSE_EVT    */    {BTA_HH_LE_OPEN_FAIL,  BTA_HH_IDLE_ST },
    225 /* BTA_HH_GATT_OPEN_EVT    */     {BTA_HH_IGNORE,        BTA_HH_W4_SEC  },
    226 /* BTA_HH_START_ENC_EVT    */     {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
    227 /* BTA_HH_ENC_CMPL_EVT     */     {BTA_HH_SEC_CMPL,      BTA_HH_W4_CONN_ST },
    228 /* READ_CHAR_CMPL_EVT */          {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
    229 /* BTA_HH_GATT_WRITE_CMPL_EVT*/   {BTA_HH_IGNORE,        BTA_HH_W4_SEC     },
    230 /* READ_DESCR_CMPL_EVT */         {BTA_HH_IGNORE,        BTA_HH_W4_SEC   },
    231 /* WRITE_DESCR_CMPL_EVT */        {BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
    232 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
    233 /* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC   }
    234 };
    235 #endif
    236 
    237 /* type for state table */
    238 typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
    239 
    240 /* state table */
    241 const tBTA_HH_ST_TBL bta_hh_st_tbl[] =
    242 {
    243     bta_hh_st_idle,
    244     bta_hh_st_w4_conn,
    245     bta_hh_st_connected
    246 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    247     ,bta_hh_st_w4_sec
    248 #endif
    249 };
    250 
    251 /*****************************************************************************
    252 ** Global data
    253 *****************************************************************************/
    254 #if BTA_DYNAMIC_MEMORY == FALSE
    255 tBTA_HH_CB  bta_hh_cb;
    256 #endif
    257 /*****************************************************************************
    258 ** Static functions
    259 *****************************************************************************/
    260 #if BTA_HH_DEBUG == TRUE
    261 static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
    262 static char *bta_hh_state_code(tBTA_HH_STATE state_code);
    263 #endif
    264 
    265 /*******************************************************************************
    266 **
    267 ** Function         bta_hh_sm_execute
    268 **
    269 ** Description      State machine event handling function for HID Host
    270 **
    271 **
    272 ** Returns          void
    273 **
    274 *******************************************************************************/
    275 void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA * p_data)
    276 {
    277     tBTA_HH_ST_TBL  state_table;
    278     UINT8           action;
    279     tBTA_HH         cback_data;
    280     tBTA_HH_EVT     cback_event = 0;
    281 #if BTA_HH_DEBUG == TRUE
    282     tBTA_HH_STATE   in_state ;
    283     UINT16          debug_event = event;
    284 #endif
    285 
    286     memset(&cback_data, 0, sizeof(tBTA_HH));
    287 
    288     /* handle exception, no valid control block was found */
    289     if (!p_cb)
    290     {
    291         /* BTA HH enabled already? otherwise ignore the event although it's bad*/
    292         if (bta_hh_cb.p_cback != NULL)
    293         {
    294             switch (event)
    295             {
    296             /* no control block available for new connection */
    297             case BTA_HH_API_OPEN_EVT:
    298                 cback_event = BTA_HH_OPEN_EVT;
    299                 /* build cback data */
    300                 bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
    301                 cback_data.conn.status  = BTA_HH_ERR_DB_FULL;
    302                 cback_data.conn.handle  = BTA_HH_INVALID_HANDLE;
    303                 break;
    304             /* DB full, BTA_HhAddDev */
    305             case BTA_HH_API_MAINT_DEV_EVT:
    306                 cback_event = p_data->api_maintdev.sub_event;
    307 
    308                 if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT)
    309                 {
    310                     bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
    311                     cback_data.dev_info.status    = BTA_HH_ERR_DB_FULL;
    312                     cback_data.dev_info.handle    = BTA_HH_INVALID_HANDLE;
    313                 }
    314                 else
    315                 {
    316                     cback_data.dev_info.status    = BTA_HH_ERR_HDL;
    317                     cback_data.dev_info.handle    = (UINT8)p_data->api_maintdev.hdr.layer_specific;
    318                 }
    319                 break;
    320             case BTA_HH_API_WRITE_DEV_EVT:
    321                 cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
    322                         BTA_HH_FST_TRANS_CB_EVT;
    323                 if (p_data->api_sndcmd.p_data != NULL)
    324                 {
    325                     GKI_freebuf(p_data->api_sndcmd.p_data);
    326                 }
    327                 if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
    328                     p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
    329                     p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE)
    330                 {
    331                     cback_data.dev_status.status = BTA_HH_ERR_HDL;
    332                     cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
    333                 }
    334                 else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
    335                     p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
    336                 {
    337                     cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
    338                     cback_data.hs_data.status = BTA_HH_ERR_HDL;
    339                     /* hs_data.rsp_data will be all zero, which is not valid value */
    340                 }
    341                 else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
    342                          p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
    343                 {
    344                     cback_data.status = BTA_HH_ERR_HDL;
    345                     cback_event = BTA_HH_VC_UNPLUG_EVT;
    346                 }
    347                 else
    348                     cback_event = 0;
    349                 break;
    350 
    351             case BTA_HH_API_CLOSE_EVT:
    352                 cback_event = BTA_HH_CLOSE_EVT;
    353 
    354                 cback_data.dev_status.status = BTA_HH_ERR_HDL;
    355                 cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
    356                 break;
    357 
    358             default:
    359                 /* invalid handle, call bad API event */
    360                 APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
    361                 /* Free the callback buffer now */
    362                 if (p_data != NULL && p_data->hid_cback.p_data != NULL)
    363                 {
    364                     GKI_freebuf(p_data->hid_cback.p_data);
    365                     p_data->hid_cback.p_data = NULL;
    366                 }
    367                 break;
    368             }
    369            if (cback_event)
    370                (* bta_hh_cb.p_cback)(cback_event, &cback_data);
    371         }
    372     }
    373     /* corresponding CB is found, go to state machine */
    374     else
    375     {
    376 #if BTA_HH_DEBUG == TRUE
    377         in_state = p_cb->state;
    378         APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
    379                           in_state, bta_hh_state_code(in_state),
    380                           bta_hh_evt_code(debug_event));
    381 #endif
    382 
    383         if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST))
    384         {
    385             APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
    386                               p_cb->state,event);
    387             return;
    388         }
    389         state_table = bta_hh_st_tbl[p_cb->state - 1];
    390 
    391         event &= 0xff;
    392 
    393         p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
    394 
    395         if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE)
    396         {
    397             (*bta_hh_action[action])(p_cb, p_data);
    398         }
    399 
    400 #if BTA_HH_DEBUG == TRUE
    401         if (in_state != p_cb->state)
    402         {
    403             APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
    404                           bta_hh_state_code(in_state),
    405                           bta_hh_state_code(p_cb->state),
    406                           bta_hh_evt_code(debug_event));
    407         }
    408 #endif
    409     }
    410 
    411     return;
    412 }
    413 /*******************************************************************************
    414 **
    415 ** Function         bta_hh_hdl_event
    416 **
    417 ** Description      HID host main event handling function.
    418 **
    419 **
    420 ** Returns          void
    421 **
    422 *******************************************************************************/
    423 BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
    424 {
    425     UINT8           index = BTA_HH_IDX_INVALID;
    426     tBTA_HH_DEV_CB *p_cb = NULL;
    427 
    428     switch (p_msg->event)
    429     {
    430         case BTA_HH_API_ENABLE_EVT:
    431             bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
    432             break;
    433 
    434         case BTA_HH_API_DISABLE_EVT:
    435             bta_hh_api_disable();
    436             break;
    437 
    438         case BTA_HH_DISC_CMPL_EVT:          /* disable complete */
    439             bta_hh_disc_cmpl();
    440             break;
    441 
    442         default:
    443             /* all events processed in state machine need to find corresponding
    444                 CB before proceed */
    445             if (p_msg->event == BTA_HH_API_OPEN_EVT)
    446             {
    447                 index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
    448             }
    449             else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
    450             {
    451                 /* if add device */
    452                 if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
    453                 {
    454                     index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
    455                 }
    456                 else /* else remove device by handle */
    457                 {
    458                     index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
    459 // btla-specific ++
    460                     /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
    461                       * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
    462                       * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
    463                       * So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
    464                       * force the index to be IDX_INVALID
    465                       */
    466                     if ((index != BTA_HH_IDX_INVALID) &&
    467                         (bta_hh_cb.kdev[index].in_use == FALSE)) {
    468                         index = BTA_HH_IDX_INVALID;
    469                     }
    470 // btla-specific --
    471                 }
    472             }
    473             else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
    474             {
    475                 index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
    476             }
    477             else
    478                 index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
    479 
    480             if (index != BTA_HH_IDX_INVALID)
    481                 p_cb = &bta_hh_cb.kdev[index];
    482 
    483 #if BTA_HH_DEBUG
    484             APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
    485 #endif
    486             bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
    487     }
    488     return (TRUE);
    489 }
    490 
    491 /*****************************************************************************
    492 **  Debug Functions
    493 *****************************************************************************/
    494 #if BTA_HH_DEBUG
    495 /*******************************************************************************
    496 **
    497 ** Function         bta_hh_evt_code
    498 **
    499 ** Description
    500 **
    501 ** Returns          void
    502 **
    503 *******************************************************************************/
    504 static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
    505 {
    506   switch(evt_code)
    507     {
    508     case BTA_HH_API_DISABLE_EVT:
    509         return "BTA_HH_API_DISABLE_EVT";
    510     case BTA_HH_API_ENABLE_EVT:
    511         return "BTA_HH_API_ENABLE_EVT";
    512     case BTA_HH_API_OPEN_EVT:
    513         return "BTA_HH_API_OPEN_EVT";
    514     case BTA_HH_API_CLOSE_EVT:
    515         return "BTA_HH_API_CLOSE_EVT";
    516     case BTA_HH_INT_OPEN_EVT:
    517         return "BTA_HH_INT_OPEN_EVT";
    518     case BTA_HH_INT_CLOSE_EVT:
    519         return "BTA_HH_INT_CLOSE_EVT";
    520     case BTA_HH_INT_HANDSK_EVT:
    521         return "BTA_HH_INT_HANDSK_EVT";
    522     case BTA_HH_INT_DATA_EVT:
    523         return "BTA_HH_INT_DATA_EVT";
    524     case BTA_HH_INT_CTRL_DATA:
    525         return "BTA_HH_INT_CTRL_DATA";
    526     case BTA_HH_API_WRITE_DEV_EVT:
    527         return "BTA_HH_API_WRITE_DEV_EVT";
    528     case BTA_HH_SDP_CMPL_EVT:
    529         return "BTA_HH_SDP_CMPL_EVT";
    530     case BTA_HH_DISC_CMPL_EVT:
    531         return "BTA_HH_DISC_CMPL_EVT";
    532     case BTA_HH_API_MAINT_DEV_EVT:
    533         return "BTA_HH_API_MAINT_DEV_EVT";
    534     case BTA_HH_API_GET_DSCP_EVT:
    535         return "BTA_HH_API_GET_DSCP_EVT";
    536     case BTA_HH_OPEN_CMPL_EVT:
    537         return "BTA_HH_OPEN_CMPL_EVT";
    538 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    539     case BTA_HH_GATT_CLOSE_EVT:
    540         return "BTA_HH_GATT_CLOSE_EVT";
    541     case BTA_HH_GATT_OPEN_EVT:
    542         return "BTA_HH_GATT_OPEN_EVT";
    543     case BTA_HH_START_ENC_EVT:
    544         return "BTA_HH_START_ENC_EVT";
    545     case BTA_HH_ENC_CMPL_EVT:
    546         return "BTA_HH_ENC_CMPL_EVT";
    547     case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
    548         return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
    549     case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
    550         return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
    551     case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
    552         return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
    553     case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
    554         return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
    555 #endif
    556     default:
    557         return "unknown HID Host event code";
    558     }
    559 }
    560 
    561 /*******************************************************************************
    562 **
    563 ** Function         bta_hh_state_code
    564 **
    565 ** Description      get string representation of HID host state code.
    566 **
    567 ** Returns          void
    568 **
    569 *******************************************************************************/
    570 static char *bta_hh_state_code(tBTA_HH_STATE state_code)
    571 {
    572     switch (state_code)
    573     {
    574     case BTA_HH_NULL_ST:
    575         return"BTA_HH_NULL_ST";
    576     case BTA_HH_IDLE_ST:
    577         return "BTA_HH_IDLE_ST";
    578     case BTA_HH_W4_CONN_ST:
    579         return "BTA_HH_W4_CONN_ST";
    580     case BTA_HH_CONN_ST:
    581         return "BTA_HH_CONN_ST";
    582 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    583     case BTA_HH_W4_SEC:
    584         return "BTA_HH_W4_SEC";
    585 #endif
    586     default:
    587         return "unknown HID Host state";
    588     }
    589 }
    590 
    591 #endif  /* Debug Functions */
    592 
    593 #endif /* BTA_HH_INCLUDED */
    594