Home | History | Annotate | Download | only in smp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2014-2015 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 #include "bt_target.h"
     20 
     21 #include <string.h>
     22 #include "smp_int.h"
     23 
     24 #if BLE_INCLUDED == TRUE
     25 
     26 const char *const smp_br_state_name [SMP_BR_STATE_MAX+1] =
     27 {
     28     "SMP_BR_STATE_IDLE",
     29     "SMP_BR_STATE_WAIT_APP_RSP",
     30     "SMP_BR_STATE_PAIR_REQ_RSP",
     31     "SMP_BR_STATE_BOND_PENDING",
     32     "SMP_BR_STATE_OUT_OF_RANGE"
     33 };
     34 
     35 const char *const smp_br_event_name [SMP_BR_MAX_EVT] =
     36 {
     37     "BR_PAIRING_REQ_EVT",
     38     "BR_PAIRING_RSP_EVT",
     39     "BR_CONFIRM_EVT",
     40     "BR_RAND_EVT",
     41     "BR_PAIRING_FAILED_EVT",
     42     "BR_ENCRPTION_INFO_EVT",
     43     "BR_MASTER_ID_EVT",
     44     "BR_ID_INFO_EVT",
     45     "BR_ID_ADDR_EVT",
     46     "BR_SIGN_INFO_EVT",
     47     "BR_SECURITY_REQ_EVT",
     48     "BR_PAIR_PUBLIC_KEY_EVT",
     49     "BR_PAIR_DHKEY_CHCK_EVT",
     50     "BR_PAIR_KEYPR_NOTIF_EVT",
     51     "BR_KEY_READY_EVT",
     52     "BR_ENCRYPTED_EVT",
     53     "BR_L2CAP_CONN_EVT",
     54     "BR_L2CAP_DISCONN_EVT",
     55     "BR_KEYS_RSP_EVT",
     56     "BR_API_SEC_GRANT_EVT",
     57     "BR_TK_REQ_EVT",
     58     "BR_AUTH_CMPL_EVT",
     59     "BR_ENC_REQ_EVT",
     60     "BR_BOND_REQ_EVT",
     61     "BR_DISCARD_SEC_REQ_EVT",
     62     "BR_OUT_OF_RANGE_EVT"
     63 };
     64 
     65 const char *smp_get_br_event_name(tSMP_BR_EVENT event);
     66 const char *smp_get_br_state_name(tSMP_BR_STATE state);
     67 
     68 #define SMP_BR_SM_IGNORE       0
     69 #define SMP_BR_NUM_ACTIONS     2
     70 #define SMP_BR_SME_NEXT_STATE  2
     71 #define SMP_BR_SM_NUM_COLS     3
     72 typedef const UINT8 (*tSMP_BR_SM_TBL)[SMP_BR_SM_NUM_COLS];
     73 
     74 enum
     75 {
     76     SMP_SEND_PAIR_REQ,
     77     SMP_BR_SEND_PAIR_RSP,
     78     SMP_SEND_PAIR_FAIL,
     79     SMP_SEND_ID_INFO,
     80     SMP_BR_PROC_PAIR_CMD,
     81     SMP_PROC_PAIR_FAIL,
     82     SMP_PROC_ID_INFO,
     83     SMP_PROC_ID_ADDR,
     84     SMP_PROC_SRK_INFO,
     85     SMP_BR_PROC_SEC_GRANT,
     86     SMP_BR_PROC_SL_KEYS_RSP,
     87     SMP_BR_KEY_DISTRIBUTION,
     88     SMP_BR_PAIRING_COMPLETE,
     89     SMP_SEND_APP_CBACK,
     90     SMP_BR_CHECK_AUTH_REQ,
     91     SMP_PAIR_TERMINATE,
     92     SMP_IDLE_TERMINATE,
     93     SMP_BR_SM_NO_ACTION
     94 };
     95 
     96 static const tSMP_ACT smp_br_sm_action[] =
     97 {
     98     smp_send_pair_req,
     99     smp_br_send_pair_response,
    100     smp_send_pair_fail,
    101     smp_send_id_info,
    102     smp_br_process_pairing_command,
    103     smp_proc_pair_fail,
    104     smp_proc_id_info,
    105     smp_proc_id_addr,
    106     smp_proc_srk_info,
    107     smp_br_process_security_grant,
    108     smp_br_process_slave_keys_response,
    109     smp_br_select_next_key,
    110     smp_br_pairing_complete,
    111     smp_send_app_cback,
    112     smp_br_check_authorization_request,
    113     smp_pair_terminate,
    114     smp_idle_terminate
    115 };
    116 
    117 static const UINT8 smp_br_all_table[][SMP_BR_SM_NUM_COLS] =
    118 {
    119 /*                               Event                    Action           Next State */
    120 /* BR_PAIRING_FAILED        */  {SMP_PROC_PAIR_FAIL,  SMP_BR_PAIRING_COMPLETE, SMP_BR_STATE_IDLE},
    121 /* BR_AUTH_CMPL             */  {SMP_SEND_PAIR_FAIL,  SMP_BR_PAIRING_COMPLETE, SMP_BR_STATE_IDLE},
    122 /* BR_L2CAP_DISCONN         */  {SMP_PAIR_TERMINATE,  SMP_BR_SM_NO_ACTION, SMP_BR_STATE_IDLE}
    123 };
    124 
    125 /************ SMP Master FSM State/Event Indirection Table **************/
    126 static const UINT8 smp_br_master_entry_map[][SMP_BR_STATE_MAX] =
    127 {
    128 /* br_state name:               Idle      WaitApp  Pair    Bond
    129                                           Rsp      ReqRsp  Pend       */
    130 /* BR_PAIRING_REQ           */  { 0,       0,       0,      0     },
    131 /* BR_PAIRING_RSP           */  { 0,       0,       1,      0     },
    132 /* BR_CONFIRM               */  { 0,       0,       0,      0     },
    133 /* BR_RAND                  */  { 0,       0,       0,      0     },
    134 /* BR_PAIRING_FAILED        */  { 0,       0x81,    0x81,   0     },
    135 /* BR_ENCRPTION_INFO        */  { 0,       0,       0,      0     },
    136 /* BR_MASTER_ID             */  { 0,       0,       0,      0     },
    137 /* BR_ID_INFO               */  { 0,       0,       0,      1     },
    138 /* BR_ID_ADDR               */  { 0,       0,       0,      2     },
    139 /* BR_SIGN_INFO             */  { 0,       0,       0,      3     },
    140 /* BR_SECURITY_REQ          */  { 0,       0,       0,      0     },
    141 /* BR_PAIR_PUBLIC_KEY_EVT   */  { 0,       0,       0,      0     },
    142 /* BR_PAIR_DHKEY_CHCK_EVT   */  { 0,       0,       0,      0     },
    143 /* BR_PAIR_KEYPR_NOTIF_EVT  */  { 0,       0,       0,      0     },
    144 /* BR_KEY_READY             */  { 0,       0,       0,      0     },
    145 /* BR_ENCRYPTED             */  { 0,       0,       0,      0     },
    146 /* BR_L2CAP_CONN            */  { 1,       0,       0,      0     },
    147 /* BR_L2CAP_DISCONN         */  { 2,       0x83,    0x83,   0x83  },
    148 /* BR_KEYS_RSP              */  { 0,       1,       0,      0     },
    149 /* BR_API_SEC_GRANT         */  { 0,       0,       0,      0     },
    150 /* BR_TK_REQ                */  { 0,       0,       0,      0     },
    151 /* BR_AUTH_CMPL             */  { 0,       0x82,    0x82,   0x82  },
    152 /* BR_ENC_REQ               */  { 0,       0,       0,      0     },
    153 /* BR_BOND_REQ              */  { 0,       0,       2,      0     },
    154 /* BR_DISCARD_SEC_REQ       */  { 0,       0,       0,      0     }
    155 };
    156 
    157 static const UINT8 smp_br_master_idle_table[][SMP_BR_SM_NUM_COLS] =
    158 {
    159 /*                                Event               Action               Next State */
    160 /* BR_L2CAP_CONN        */  {SMP_SEND_APP_CBACK, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_WAIT_APP_RSP},
    161 /* BR_L2CAP_DISCONN   */  {SMP_IDLE_TERMINATE,  SMP_BR_SM_NO_ACTION, SMP_BR_STATE_IDLE}
    162 };
    163 
    164 static const UINT8 smp_br_master_wait_appln_response_table[][SMP_BR_SM_NUM_COLS] =
    165 {
    166 /*                                Event               Action              Next State */
    167 /* BR_KEYS_RSP           */{SMP_SEND_PAIR_REQ, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_PAIR_REQ_RSP}
    168 };
    169 
    170 static const UINT8 smp_br_master_pair_request_response_table [][SMP_BR_SM_NUM_COLS] =
    171 {
    172 /*                        Event               Action                  Next State */
    173 /* BR_PAIRING_RSP   */  {SMP_BR_PROC_PAIR_CMD, SMP_BR_CHECK_AUTH_REQ, SMP_BR_STATE_PAIR_REQ_RSP},
    174 /* BR_BOND_REQ      */  {SMP_BR_SM_NO_ACTION, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
    175 };
    176 
    177 static const UINT8 smp_br_master_bond_pending_table[][SMP_BR_SM_NUM_COLS] =
    178 {
    179 /*                                Event               Action              Next State */
    180 /* BR_ID_INFO               */{SMP_PROC_ID_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
    181 /* BR_ID_ADDR               */{SMP_PROC_ID_ADDR, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
    182 /* BR_SIGN_INFO             */{SMP_PROC_SRK_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
    183 };
    184 
    185 static const UINT8 smp_br_slave_entry_map[][SMP_BR_STATE_MAX] =
    186 {
    187 /* br_state name:               Idle      WaitApp  Pair    Bond
    188                                           Rsp      ReqRsp  Pend      */
    189 /* BR_PAIRING_REQ           */  { 1,       0,       0,      0    },
    190 /* BR_PAIRING_RSP           */  { 0,       0,       0,      0    },
    191 /* BR_CONFIRM               */  { 0,       0,       0,      0    },
    192 /* BR_RAND                  */  { 0,       0,       0,      0    },
    193 /* BR_PAIRING_FAILED        */  { 0,       0x81,    0x81,   0x81 },
    194 /* BR_ENCRPTION_INFO        */  { 0,       0,       0,      0    },
    195 /* BR_MASTER_ID             */  { 0,       0,       0,      0    },
    196 /* BR_ID_INFO               */  { 0,       0,       0,      1    },
    197 /* BR_ID_ADDR               */  { 0,       0,       0,      2    },
    198 /* BR_SIGN_INFO             */  { 0,       0,       0,      3    },
    199 /* BR_SECURITY_REQ          */  { 0,       0,       0,      0    },
    200 /* BR_PAIR_PUBLIC_KEY_EVT   */  { 0,       0,       0,      0    },
    201 /* BR_PAIR_DHKEY_CHCK_EVT   */  { 0,       0,       0,      0    },
    202 /* BR_PAIR_KEYPR_NOTIF_EVT  */  { 0,       0,       0,      0    },
    203 /* BR_KEY_READY             */  { 0,       0,       0,      0    },
    204 /* BR_ENCRYPTED             */  { 0,       0,       0,      0    },
    205 /* BR_L2CAP_CONN            */  { 0,       0,       0,      0    },
    206 /* BR_L2CAP_DISCONN         */  { 0,       0x83,    0x83,   0x83 },
    207 /* BR_KEYS_RSP              */  { 0,       2,       0,      0    },
    208 /* BR_API_SEC_GRANT         */  { 0,       1,       0,      0    },
    209 /* BR_TK_REQ                */  { 0,       0,       0,      0    },
    210 /* BR_AUTH_CMPL             */  { 0,       0x82,    0x82,   0x82 },
    211 /* BR_ENC_REQ               */  { 0,       0,       0,      0    },
    212 /* BR_BOND_REQ              */  { 0,       3,       0,      0    },
    213 /* BR_DISCARD_SEC_REQ       */  { 0,       0,       0,      0    }
    214 };
    215 
    216 static const UINT8 smp_br_slave_idle_table[][SMP_BR_SM_NUM_COLS] =
    217 {
    218 /*                               Event                Action              Next State */
    219 /* BR_PAIRING_REQ    */ {SMP_BR_PROC_PAIR_CMD, SMP_SEND_APP_CBACK, SMP_BR_STATE_WAIT_APP_RSP}
    220 };
    221 
    222 static const UINT8 smp_br_slave_wait_appln_response_table [][SMP_BR_SM_NUM_COLS] =
    223 {
    224 /*                               Event                 Action             Next State */
    225 /* BR_API_SEC_GRANT */ {SMP_BR_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_BR_STATE_WAIT_APP_RSP},
    226 /* BR_KEYS_RSP     */{SMP_BR_PROC_SL_KEYS_RSP, SMP_BR_CHECK_AUTH_REQ,SMP_BR_STATE_WAIT_APP_RSP},
    227 /* BR_BOND_REQ        */ {SMP_BR_KEY_DISTRIBUTION, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
    228 };
    229 
    230 static const UINT8 smp_br_slave_bond_pending_table[][SMP_BR_SM_NUM_COLS] =
    231 {
    232 /*                                Event               Action               Next State */
    233 /* BR_ID_INFO               */  {SMP_PROC_ID_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
    234 /* BR_ID_ADDR               */  {SMP_PROC_ID_ADDR, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
    235 /* BR_SIGN_INFO             */  {SMP_PROC_SRK_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
    236 };
    237 
    238 static const tSMP_BR_SM_TBL smp_br_state_table[][2] =
    239 {
    240     /* SMP_BR_STATE_IDLE */
    241     {smp_br_master_idle_table, smp_br_slave_idle_table},
    242 
    243     /* SMP_BR_STATE_WAIT_APP_RSP */
    244     {smp_br_master_wait_appln_response_table, smp_br_slave_wait_appln_response_table},
    245 
    246     /* SMP_BR_STATE_PAIR_REQ_RSP */
    247     {smp_br_master_pair_request_response_table, NULL},
    248 
    249     /* SMP_BR_STATE_BOND_PENDING */
    250     {smp_br_master_bond_pending_table, smp_br_slave_bond_pending_table},
    251 };
    252 
    253 typedef const UINT8 (*tSMP_BR_ENTRY_TBL)[SMP_BR_STATE_MAX];
    254 
    255 static const tSMP_BR_ENTRY_TBL smp_br_entry_table[] =
    256 {
    257     smp_br_master_entry_map,
    258     smp_br_slave_entry_map
    259 };
    260 
    261 #define SMP_BR_ALL_TABLE_MASK  0x80
    262 
    263 /*******************************************************************************
    264 ** Function     smp_set_br_state
    265 ** Returns      None
    266 *******************************************************************************/
    267 void smp_set_br_state(tSMP_BR_STATE br_state)
    268 {
    269     if (br_state < SMP_BR_STATE_MAX)
    270     {
    271         SMP_TRACE_DEBUG( "BR_State change: %s(%d) ==> %s(%d)",
    272                           smp_get_br_state_name(smp_cb.br_state), smp_cb.br_state,
    273                           smp_get_br_state_name(br_state), br_state );
    274         smp_cb.br_state = br_state;
    275     }
    276     else
    277     {
    278         SMP_TRACE_DEBUG("%s invalid br_state =%d", __FUNCTION__,br_state );
    279     }
    280 }
    281 
    282 /*******************************************************************************
    283 ** Function     smp_get_br_state
    284 ** Returns      The smp_br state
    285 *******************************************************************************/
    286 tSMP_BR_STATE smp_get_br_state(void)
    287 {
    288     return smp_cb.br_state;
    289 }
    290 
    291 /*******************************************************************************
    292 ** Function     smp_get_br_state_name
    293 ** Returns      The smp_br state name.
    294 *******************************************************************************/
    295 const char *smp_get_br_state_name(tSMP_BR_STATE br_state)
    296 {
    297     const char *p_str = smp_br_state_name[SMP_BR_STATE_MAX];
    298 
    299     if (br_state < SMP_BR_STATE_MAX)
    300         p_str = smp_br_state_name[br_state];
    301 
    302     return p_str;
    303 }
    304 /*******************************************************************************
    305 ** Function     smp_get_br_event_name
    306 ** Returns      The smp_br event name.
    307 *******************************************************************************/
    308 const char * smp_get_br_event_name(tSMP_BR_EVENT event)
    309 {
    310     const char * p_str = smp_br_event_name[SMP_BR_MAX_EVT - 1];
    311 
    312     if (event < SMP_BR_MAX_EVT)
    313     {
    314         p_str = smp_br_event_name[event- 1];
    315     }
    316     return p_str;
    317 }
    318 
    319 /*******************************************************************************
    320 **
    321 ** Function     smp_br_state_machine_event
    322 **
    323 ** Description  Handle events to the state machine. It looks up the entry
    324 **              in the smp_br_entry_table array.
    325 **              If it is a valid entry, it gets the state table.Set the next state,
    326 **              if not NULL state. Execute the action function according to the
    327 **              state table. If the state returned by action function is not NULL
    328 **              state, adjust the new state to the returned state.
    329 **
    330 ** Returns      void.
    331 **
    332 *******************************************************************************/
    333 void smp_br_state_machine_event(tSMP_CB *p_cb, tSMP_BR_EVENT event, void *p_data)
    334 {
    335     tSMP_BR_STATE       curr_state = p_cb->br_state;
    336     tSMP_BR_SM_TBL      state_table;
    337     UINT8               action, entry;
    338     tSMP_BR_ENTRY_TBL   entry_table =  smp_br_entry_table[p_cb->role];
    339 
    340     SMP_TRACE_EVENT("main %s", __func__);
    341     if (curr_state >= SMP_BR_STATE_MAX)
    342     {
    343         SMP_TRACE_DEBUG( "Invalid br_state: %d", curr_state) ;
    344         return;
    345     }
    346 
    347     SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",
    348                       (p_cb->role == HCI_ROLE_SLAVE) ? "Slave" : "Master",
    349                       smp_get_br_state_name( p_cb->br_state),
    350                       p_cb->br_state, smp_get_br_event_name(event), event) ;
    351 
    352     /* look up the state table for the current state */
    353     /* lookup entry / w event & curr_state */
    354     /* If entry is ignore, return.
    355      * Otherwise, get state table (according to curr_state or all_state) */
    356     if ((event <= SMP_BR_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state])
    357         != SMP_BR_SM_IGNORE ))
    358     {
    359         if (entry & SMP_BR_ALL_TABLE_MASK)
    360         {
    361             entry &= ~SMP_BR_ALL_TABLE_MASK;
    362             state_table = smp_br_all_table;
    363         }
    364         else
    365         {
    366             state_table = smp_br_state_table[curr_state][p_cb->role];
    367         }
    368     }
    369     else
    370     {
    371         SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
    372                           smp_get_br_event_name(event), event,
    373                           smp_get_br_state_name(curr_state), curr_state);
    374         return;
    375     }
    376 
    377     /* Get possible next state from state table. */
    378 
    379     smp_set_br_state(state_table[entry - 1][SMP_BR_SME_NEXT_STATE]);
    380 
    381     /* If action is not ignore, clear param, exec action and get next state.
    382      * The action function may set the Param for cback.
    383      * Depending on param, call cback or free buffer. */
    384     /* execute action functions */
    385     for (UINT8 i = 0; i < SMP_BR_NUM_ACTIONS; i++)
    386     {
    387         if ((action = state_table[entry - 1][i]) != SMP_BR_SM_NO_ACTION)
    388         {
    389             (*smp_br_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
    390         }
    391         else
    392         {
    393             break;
    394         }
    395     }
    396     SMP_TRACE_DEBUG( "result state = %s", smp_get_br_state_name( p_cb->br_state ) ) ;
    397 }
    398 
    399 #endif
    400