Home | History | Annotate | Download | only in smp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-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 #include "bt_target.h"
     20 
     21 #if SMP_INCLUDED == TRUE
     22 
     23 #include <string.h>
     24 #include "smp_int.h"
     25 
     26 const char *const smp_state_name [] =
     27 {
     28     "SMP_STATE_IDLE",
     29     "SMP_STATE_WAIT_APP_RSP",
     30     "SMP_STATE_SEC_REQ_PENDING",
     31     "SMP_STATE_PAIR_REQ_RSP",
     32     "SMP_STATE_WAIT_CONFIRM",
     33     "SMP_STATE_CONFIRM",
     34     "SMP_STATE_RAND",
     35     "SMP_STATE_PUBLIC_KEY_EXCH",
     36     "SMP_STATE_SEC_CONN_PHS1_START",
     37     "SMP_STATE_WAIT_COMMITMENT",
     38     "SMP_STATE_WAIT_NONCE",
     39     "SMP_STATE_SEC_CONN_PHS2_START",
     40     "SMP_STATE_WAIT_DHK_CHECK",
     41     "SMP_STATE_DHK_CHECK",
     42     "SMP_STATE_ENCRYPTION_PENDING",
     43     "SMP_STATE_BOND_PENDING",
     44     "SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA",
     45     "SMP_STATE_MAX"
     46 };
     47 
     48 const char *const smp_event_name [] =
     49 {
     50     "PAIRING_REQ_EVT",
     51     "PAIRING_RSP_EVT",
     52     "CONFIRM_EVT",
     53     "RAND_EVT",
     54     "PAIRING_FAILED_EVT",
     55     "ENC_INFO_EVT",
     56     "MASTER_ID_EVT",
     57     "ID_INFO_EVT",
     58     "ID_ADDR_EVT",
     59     "SIGN_INFO_EVT",
     60     "SECURITY_REQ_EVT",
     61     "PAIR_PUBLIC_KEY_EVT",
     62     "PAIR_DHKEY_CHECK_EVT",
     63     "PAIR_KEYPRESS_NOTIFICATION_EVT",
     64     "PAIR_COMMITMENT_EVT",
     65     "KEY_READY_EVT",
     66     "ENCRYPTED_EVT",
     67     "L2CAP_CONN_EVT",
     68     "L2CAP_DISCONN_EVT",
     69     "API_IO_RSP_EVT",
     70     "API_SEC_GRANT_EVT",
     71     "TK_REQ_EVT",
     72     "AUTH_CMPL_EVT",
     73     "ENC_REQ_EVT",
     74     "BOND_REQ_EVT",
     75     "DISCARD_SEC_REQ_EVT",
     76     "PUBLIC_KEY_EXCHANGE_REQ_EVT",
     77     "LOCAL_PUBLIC_KEY_CRTD_EVT",
     78     "BOTH_PUBLIC_KEYS_RCVD_EVT",
     79     "SEC_CONN_DHKEY_COMPLETE_EVT",
     80     "HAVE_LOCAL_NONCE_EVT",
     81     "SEC_CONN_PHASE1_CMPLT_EVT",
     82     "SEC_CONN_CALC_NC_EVT",
     83     "SEC_CONN_DISPLAY_NC_EVT",
     84     "SEC_CONN_OK_EVT",
     85     "SEC_CONN_2_DHCK_CHECKS_PRESENT_EVT",
     86     "SEC_CONN_KEY_READY_EVT",
     87     "KEYPRESS_NOTIFICATION_EVT",
     88     "SEC_CONN_OOB_DATA_EVT",
     89     "CREATE_LOCAL_SEC_CONN_OOB_DATA_EVT",
     90     "OUT_OF_RANGE_EVT"
     91 };
     92 
     93 const char *smp_get_event_name(tSMP_EVENT event);
     94 const char *smp_get_state_name(tSMP_STATE state);
     95 
     96 #define SMP_SM_IGNORE       0
     97 #define SMP_NUM_ACTIONS     2
     98 #define SMP_SME_NEXT_STATE  2
     99 #define SMP_SM_NUM_COLS     3
    100 
    101 typedef const UINT8(*tSMP_SM_TBL)[SMP_SM_NUM_COLS];
    102 
    103 enum
    104 {
    105     SMP_PROC_SEC_REQ,
    106     SMP_SEND_PAIR_REQ,
    107     SMP_SEND_PAIR_RSP,
    108     SMP_SEND_CONFIRM,
    109     SMP_SEND_PAIR_FAIL,
    110     SMP_SEND_RAND,
    111     SMP_SEND_ENC_INFO,
    112     SMP_SEND_ID_INFO,
    113     SMP_SEND_LTK_REPLY,
    114     SMP_PROC_PAIR_CMD,
    115     SMP_PROC_PAIR_FAIL,
    116     SMP_PROC_CONFIRM,
    117     SMP_PROC_RAND,
    118     SMP_PROC_ENC_INFO,
    119     SMP_PROC_MASTER_ID,
    120     SMP_PROC_ID_INFO,
    121     SMP_PROC_ID_ADDR,
    122     SMP_PROC_SRK_INFO,
    123     SMP_PROC_SEC_GRANT,
    124     SMP_PROC_SL_KEY,
    125     SMP_PROC_COMPARE,
    126     SMP_PROC_IO_RSP,
    127     SMP_GENERATE_COMPARE,
    128     SMP_GENERATE_CONFIRM,
    129     SMP_GENERATE_STK,
    130     SMP_KEY_DISTRIBUTE,
    131     SMP_START_ENC,
    132     SMP_PAIRING_CMPL,
    133     SMP_DECIDE_ASSO_MODEL,
    134     SMP_SEND_APP_CBACK,
    135     SMP_CHECK_AUTH_REQ,
    136     SMP_PAIR_TERMINATE,
    137     SMP_ENC_CMPL,
    138     SMP_PROC_DISCARD,
    139     SMP_CREATE_PRIVATE_KEY,
    140     SMP_USE_OOB_PRIVATE_KEY,
    141     SMP_SEND_PAIR_PUBLIC_KEY,
    142     SMP_PROCESS_PAIR_PUBLIC_KEY,
    143     SMP_HAVE_BOTH_PUBLIC_KEYS,
    144     SMP_START_SEC_CONN_PHASE1,
    145     SMP_PROCESS_LOCAL_NONCE,
    146     SMP_SEND_COMMITMENT,
    147     SMP_PROCESS_PAIRING_COMMITMENT,
    148     SMP_PROCESS_PEER_NONCE,
    149     SMP_CALCULATE_LOCAL_DHKEY_CHECK,
    150     SMP_SEND_DHKEY_CHECK,
    151     SMP_PROCESS_DHKEY_CHECK,
    152     SMP_CALCULATE_PEER_DHKEY_CHECK,
    153     SMP_MATCH_DHKEY_CHECKS,
    154     SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER,
    155     SMP_MOVE_TO_SEC_CONN_PHASE2,
    156     SMP_PH2_DHKEY_CHECKS_ARE_PRESENT,
    157     SMP_WAIT_FOR_BOTH_PUBLIC_KEYS,
    158     SMP_START_PASSKEY_VERIFICATION,
    159     SMP_SEND_KEYPRESS_NOTIFICATION,
    160     SMP_PROCESS_KEYPRESS_NOTIFICATION,
    161     SMP_PROCESS_SECURE_CONNECTION_OOB_DATA,
    162     SMP_SET_LOCAL_OOB_KEYS,
    163     SMP_SET_LOCAL_OOB_RAND_COMMITMENT,
    164     SMP_IDLE_TERMINATE,
    165     SMP_FAST_CONN_PARAM,
    166     SMP_SM_NO_ACTION
    167 };
    168 
    169 static const tSMP_ACT smp_sm_action[] =
    170 {
    171     smp_proc_sec_req,
    172     smp_send_pair_req,
    173     smp_send_pair_rsp,
    174     smp_send_confirm,
    175     smp_send_pair_fail,
    176     smp_send_rand,
    177     smp_send_enc_info,
    178     smp_send_id_info,
    179     smp_send_ltk_reply,
    180     smp_proc_pair_cmd,
    181     smp_proc_pair_fail,
    182     smp_proc_confirm,
    183     smp_proc_rand,
    184     smp_proc_enc_info,
    185     smp_proc_master_id,
    186     smp_proc_id_info,
    187     smp_proc_id_addr,
    188     smp_proc_srk_info,
    189     smp_proc_sec_grant,
    190     smp_proc_sl_key,
    191     smp_proc_compare,
    192     smp_process_io_response,
    193     smp_generate_compare,
    194     smp_generate_srand_mrand_confirm,
    195     smp_generate_stk,
    196     smp_key_distribution,
    197     smp_start_enc,
    198     smp_pairing_cmpl,
    199     smp_decide_association_model,
    200     smp_send_app_cback,
    201     smp_check_auth_req,
    202     smp_pair_terminate,
    203     smp_enc_cmpl,
    204     smp_proc_discard,
    205     smp_create_private_key,
    206     smp_use_oob_private_key,
    207     smp_send_pair_public_key,
    208     smp_process_pairing_public_key,
    209     smp_both_have_public_keys,
    210     smp_start_secure_connection_phase1,
    211     smp_process_local_nonce,
    212     smp_send_commitment,
    213     smp_process_pairing_commitment,
    214     smp_process_peer_nonce,
    215     smp_calculate_local_dhkey_check,
    216     smp_send_dhkey_check,
    217     smp_process_dhkey_check,
    218     smp_calculate_peer_dhkey_check,
    219     smp_match_dhkey_checks,
    220     smp_calculate_numeric_comparison_display_number,
    221     smp_move_to_secure_connections_phase2,
    222     smp_phase_2_dhkey_checks_are_present,
    223     smp_wait_for_both_public_keys,
    224     smp_start_passkey_verification,
    225     smp_send_keypress_notification,
    226     smp_process_keypress_notification,
    227     smp_process_secure_connection_oob_data,
    228     smp_set_local_oob_keys,
    229     smp_set_local_oob_random_commitment,
    230     smp_idle_terminate,
    231     smp_fast_conn_param
    232 };
    233 
    234 /************ SMP Master FSM State/Event Indirection Table **************/
    235 static const UINT8 smp_master_entry_map[][SMP_STATE_MAX] =
    236 {
    237 /* state name:             Idle WaitApp SecReq Pair   Wait Confirm Rand PublKey SCPhs1  Wait  Wait  SCPhs2  Wait   DHKChk Enc   Bond  CrLocSc
    238                                  Rsp    Pend   ReqRsp Cfm               Exch    Strt    Cmtm  Nonce Strt    DHKChk        Pend  Pend  OobData   */
    239 /* PAIR_REQ             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    240 /* PAIR_RSP             */{ 0,    0,     0,      1,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    241 /* CONFIRM              */{ 0,    0,     0,      0,     0,   1,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    242 /* RAND                 */{ 0,    0,     0,      0,     0,   0,    1,   0,      0,      0,    1,    0,      0,     0,     0,    0,     0   },
    243 /* PAIR_FAIL            */{ 0,    0x81,  0,      0x81,  0x81,0x81, 0x81,0x81,   0x81,   0x81, 0x81, 0x81,   0x81,  0x81,  0,    0,     0   },
    244 /* ENC_INFO             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    1,     0   },
    245 /* MASTER_ID            */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    4,     0   },
    246 /* ID_INFO              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    2,     0   },
    247 /* ID_ADDR              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    5,     0   },
    248 /* SIGN_INFO            */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    3,     0   },
    249 /* SEC_REQ              */{ 2,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    250 /* PAIR_PUBLIC_KEY      */{ 0,    0,     0,      0,     0,   0,    0,   2,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    251 /* PAIR_DHKEY_CHCK      */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      1,     0,     0,    0,     0   },
    252 /* PAIR_KEYPR_NOTIF     */{ 0,    8,     0,      0,     0,   0,    0,   0,      5,      2,    0,    0,      0,     0,     0,    0,     0   },
    253 /* PAIR_COMMITM         */{ 0,    0,     0,      0,     0,   0,    0,   0,      6,      1,    0,    0,      0,     0,     0,    0,     0   },
    254 /* KEY_READY            */{ 0,    3,     0,      3,     1,   0,    2,   0,      4,      0,    0,    0,      0,     0,     1,    6,     0   },
    255 /* ENC_CMPL             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     2,    0,     0   },
    256 /* L2C_CONN             */{ 1,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    257 /* L2C_DISC             */{ 3,    0x83,  0,      0x83,  0x83,0x83, 0x83,0x83,   0x83,   0x83, 0x83, 0x83,   0x83,  0x83,  0x83, 0x83,  0   },
    258 /* IO_RSP               */{ 0,    2,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    259 /* SEC_GRANT            */{ 0,    1,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    260 /* TK_REQ               */{ 0,    0,     0,      2,     0,   0,    0,   0,      3,      0,    0,    0,      0,     0,     0,    0,     0   },
    261 /* AUTH_CMPL            */{ 4,    0x82,  0,      0x82,  0x82,0x82, 0x82,0x82,   0x82,   0x82, 0x82, 0x82,   0x82,  0x82,  0x82, 0x82,  0   },
    262 /* ENC_REQ              */{ 0,    4,     0,      0,     0,   0,    3,   0,      0,      0,    0,    0,      0,     2,     0,    0,     0   },
    263 /* BOND_REQ             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     3,    0,     0   },
    264 /* DISCARD_SEC_REQ      */{ 0,    5,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     3,    0,     0   },
    265 /* PUBL_KEY_EXCH_REQ    */{ 0,    0,     0,      4,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    266 /* LOC_PUBL_KEY_CRTD    */{ 0,    0,     0,      0,     0,   0,    0,   1,      0,      0,    0,    0,      0,     0,     0,    0,     1   },
    267 /* BOTH_PUBL_KEYS_RCVD  */{ 0,    0,     0,      0,     0,   0,    0,   3,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    268 /* SC_DHKEY_CMPLT       */{ 0,    0,     0,      0,     0,   0,    0,   0,      1,      0,    0,    0,      0,     0,     0,    0,     0   },
    269 /* HAVE_LOC_NONCE       */{ 0,    0,     0,      0,     0,   0,    0,   0,      2,      0,    0,    0,      0,     0,     0,    0,     2   },
    270 /* SC_PHASE1_CMPLT      */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    1,      0,     0,     0,    0,     0   },
    271 /* SC_CALC_NC           */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    2,    0,      0,     0,     0,    0,     0   },
    272 /* SC_DSPL_NC           */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    3,    0,      0,     0,     0,    0,     0   },
    273 /* SC_NC_OK             */{ 0,    6,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    274 /* SC_2_DHCK_CHKS_PRES  */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    275 /* SC_KEY_READY         */{ 0,    7,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     1,     0,    0,     0   },
    276 /* KEYPR_NOTIF          */{ 0,    9,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    277 /* SC_OOB_DATA          */{ 0,    10,    0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    278 /* CR_LOC_SC_OOB_DATA   */{ 5,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    279 };
    280 
    281 static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] =
    282 {
    283 /*                       Event                     Action                 Next State */
    284 /* PAIR_FAIL */          {SMP_PROC_PAIR_FAIL,      SMP_PAIRING_CMPL, SMP_STATE_IDLE},
    285 /* AUTH_CMPL */          {SMP_SEND_PAIR_FAIL,      SMP_PAIRING_CMPL, SMP_STATE_IDLE},
    286 /* L2C_DISC  */          {SMP_PAIR_TERMINATE,      SMP_SM_NO_ACTION, SMP_STATE_IDLE}
    287 };
    288 
    289 static const UINT8 smp_master_idle_table[][SMP_SM_NUM_COLS] =
    290 {
    291 /*                   Event                  Action               Next State */
    292 /* L2C_CONN */      {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_STATE_WAIT_APP_RSP},
    293 /* SEC_REQ  */      {SMP_PROC_SEC_REQ,       SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
    294 /* L2C_DISC  */     {SMP_IDLE_TERMINATE,     SMP_SM_NO_ACTION, SMP_STATE_IDLE},
    295 /* AUTH_CMPL */     {SMP_PAIRING_CMPL,       SMP_SM_NO_ACTION, SMP_STATE_IDLE}
    296 /* CR_LOC_SC_OOB_DATA   */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}
    297 
    298 };
    299 
    300 static const UINT8 smp_master_wait_for_app_response_table[][SMP_SM_NUM_COLS] =
    301 {
    302 /*                            Event                Action               Next State */
    303 /* SEC_GRANT            */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
    304 /* IO_RSP               */ {SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP},
    305 
    306                     /* TK ready */
    307 /* KEY_READY            */ {SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION,   SMP_STATE_WAIT_CONFIRM},
    308 
    309                     /* start enc mode setup */
    310 /* ENC_REQ              */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_STATE_ENCRYPTION_PENDING},
    311 /* DISCARD_SEC_REQ      */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
    312 /* user confirms NC 'OK', i.e. phase 1 is completed */
    313 /* SC_NC_OK             */,{ SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START},
    314 /* user-provided passkey is rcvd */
    315 /* SC_KEY_READY  */ { SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    316 /* PAIR_KEYPR_NOTIF */ { SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
    317 /* KEYPR_NOTIF          */ { SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    318 /* SC_OOB_DATA      */ { SMP_USE_OOB_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}
    319 };
    320 
    321 static const UINT8 smp_master_pair_request_response_table[][SMP_SM_NUM_COLS] =
    322 {
    323 /*               Event                  Action                  Next State */
    324 /* PAIR_RSP */ { SMP_PROC_PAIR_CMD,     SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
    325 /* TK_REQ   */ { SMP_SEND_APP_CBACK,    SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    326 
    327                     /* TK ready */
    328 /* KEY_READY */{ SMP_GENERATE_CONFIRM,  SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM}
    329 /* PUBL_KEY_EXCH_REQ    */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}
    330 };
    331 
    332 static const UINT8 smp_master_wait_for_confirm_table[][SMP_SM_NUM_COLS] =
    333 {
    334 /*              Event                   Action          Next State */
    335 /* KEY_READY*/ {SMP_SEND_CONFIRM,     SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}/* CONFIRM ready */
    336 };
    337 
    338 static const UINT8 smp_master_confirm_table[][SMP_SM_NUM_COLS] =
    339 {
    340 /*               Event                  Action                 Next State */
    341 /* CONFIRM  */ { SMP_PROC_CONFIRM, SMP_SEND_RAND, SMP_STATE_RAND}
    342 };
    343 
    344 static const UINT8 smp_master_rand_table[][SMP_SM_NUM_COLS] =
    345 {
    346 /*               Event                  Action                   Next State */
    347 /* RAND     */ { SMP_PROC_RAND,         SMP_GENERATE_COMPARE, SMP_STATE_RAND},
    348 /* KEY_READY*/ { SMP_PROC_COMPARE,      SMP_SM_NO_ACTION,   SMP_STATE_RAND},  /* Compare ready */
    349 /* ENC_REQ  */ { SMP_GENERATE_STK,      SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}
    350 };
    351 
    352 static const UINT8 smp_master_public_key_exchange_table[][SMP_SM_NUM_COLS] =
    353 {
    354 /*                          Event                        Action              Next State */
    355 /* LOC_PUBL_KEY_CRTD    */{ SMP_SEND_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
    356 /* PAIR_PUBLIC_KEY      */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
    357 /* BOTH_PUBL_KEYS_RCVD  */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    358 };
    359 
    360 static const UINT8 smp_master_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] =
    361 {
    362 /*                          Event                  Action                Next State */
    363 /* SC_DHKEY_CMPLT       */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    364 /* HAVE_LOC_NONCE       */{ SMP_PROCESS_LOCAL_NONCE, SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT},
    365 /* TK_REQ               */{ SMP_SEND_APP_CBACK,    SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    366 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display,*/
    367 /* It's time to start commitment calculation */
    368 /* KEY_READY            */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    369 /* PAIR_KEYPR_NOTIF  */{ SMP_PROCESS_KEYPRESS_NOTIFICATION,  SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START},
    370 /* PAIR_COMMITM  */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    371 };
    372 
    373 static const UINT8 smp_master_wait_commitment_table[][SMP_SM_NUM_COLS] =
    374 {
    375 /*                          Event                  Action                 Next State */
    376 /* PAIR_COMMITM         */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_RAND, SMP_STATE_WAIT_NONCE},
    377 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT},
    378 };
    379 
    380 static const UINT8 smp_master_wait_nonce_table[][SMP_SM_NUM_COLS] =
    381 {
    382 /*                          Event                  Action                 Next State */
    383 /* peer nonce is received */
    384 /* RAND                 */{SMP_PROC_RAND,  SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START},
    385 /* NC model, time to calculate number for NC */
    386 /* SC_CALC_NC           */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE},
    387 /* NC model, time to display calculated number for NC to the user */
    388 /* SC_DSPL_NC           */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    389 };
    390 
    391 static const UINT8 smp_master_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] =
    392 {
    393 /*                          Event                  Action                 Next State */
    394 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_SEND_DHKEY_CHECK, SMP_STATE_WAIT_DHK_CHECK},
    395 };
    396 
    397 static const UINT8 smp_master_wait_dhk_check_table[][SMP_SM_NUM_COLS] =
    398 {
    399 /*                          Event                  Action                 Next State */
    400 /* PAIR_DHKEY_CHCK  */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK},
    401 };
    402 
    403 static const UINT8 smp_master_dhk_check_table[][SMP_SM_NUM_COLS] =
    404 {
    405 /*                          Event                  Action                 Next State */
    406 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check actually received from peer */
    407 /* SC_KEY_READY         */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
    408 /* locally calculated peer dhkey check is ready -> calculate STK, go to sending */
    409 /* HCI LE Start Encryption command */
    410 /* ENC_REQ              */{SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    411 };
    412 
    413 static const UINT8 smp_master_enc_pending_table[][SMP_SM_NUM_COLS] =
    414 {
    415 /*                          Event                  Action                 Next State */
    416 /* STK ready */
    417 /* KEY_READY */ { SMP_START_ENC,        SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    418 /* ENCRYPTED */ { SMP_CHECK_AUTH_REQ,   SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    419 /* BOND_REQ  */ { SMP_KEY_DISTRIBUTE,   SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
    420 };
    421 static const UINT8 smp_master_bond_pending_table[][SMP_SM_NUM_COLS] =
    422 {
    423 /*                          Event                  Action                 Next State */
    424 /* ENC_INFO */ { SMP_PROC_ENC_INFO,     SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    425 /* ID_INFO  */ { SMP_PROC_ID_INFO,      SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    426 /* SIGN_INFO*/ { SMP_PROC_SRK_INFO,     SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    427 /* MASTER_ID*/ { SMP_PROC_MASTER_ID,    SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    428 /* ID_ADDR  */ { SMP_PROC_ID_ADDR,      SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    429 /* KEY_READY */{SMP_SEND_ENC_INFO,      SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} /* LTK ready */
    430 };
    431 
    432 static const UINT8 smp_master_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] =
    433 {
    434 /*                       Event                   Action            Next State */
    435 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS,   SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA},
    436 /* HAVE_LOC_NONCE    */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
    437 };
    438 
    439 
    440 /************ SMP Slave FSM State/Event Indirection Table **************/
    441 static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] =
    442 {
    443 /* state name:             Idle WaitApp SecReq Pair   Wait Confirm Rand PublKey SCPhs1  Wait  Wait  SCPhs2  Wait   DHKChk Enc   Bond  CrLocSc
    444                                  Rsp    Pend   ReqRsp Cfm               Exch    Strt    Cmtm  Nonce Strt    DHKChk        Pend  Pend  OobData   */
    445 /* PAIR_REQ             */{ 2,    0,     1,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    446 /* PAIR_RSP             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    447 /* CONFIRM              */{ 0,    4,     0,      1,     1,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    448 /* RAND                 */{ 0,    0,     0,      0,     0,   1,    2,   0,      0,      0,    1,    0,      0,     0,     0,    0,     0   },
    449 /* PAIR_FAIL            */{ 0,    0x81,  0x81,   0x81,  0x81,0x81, 0x81,0x81,   0x81,   0x81, 0x81, 0x81,   0x81,  0x81,  0x81, 0,     0   },
    450 /* ENC_INFO             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    3,     0   },
    451 /* MASTER_ID            */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    5,     0   },
    452 /* ID_INFO              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    4,     0   },
    453 /* ID_ADDR              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    6,     0   },
    454 /* SIGN_INFO            */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    2,     0   },
    455 /* SEC_REQ              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    456 /* PAIR_PUBLIC_KEY      */{ 0,    0,     0,      5,     0,   0,    0,   2,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    457 /* PAIR_DHKEY_CHCK      */{ 0,    5,     0,      0,     0,   0,    0,   0,      0,      0,    0,    2,      1,     2,     0,    0,     0   },
    458 /* PAIR_KEYPR_NOTIF     */{ 0,    9,     0,      0,     0,   0,    0,   0,      5,      2,    0,    0,      0,     0,     0,    0,     0   },
    459 /* PAIR_COMMITM         */{ 0,    8,     0,      0,     0,   0,    0,   0,      6,      1,    0,    0,      0,     0,     0,    0,     0   },
    460 /* KEY_READY            */{ 0,    3,     0,      3,     2,   2,    1,   0,      4,      0,    0,    0,      0,     0,     2,    1,     0   },
    461 /* ENC_CMPL             */{ 0,    0,     2,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     3,    0,     0   },
    462 /* L2C_CONN             */{ 1,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    463 /* L2C_DISC             */{ 0,    0x83,  0x83,   0x83,  0x83,0x83, 0x83,0x83,   0x83,   0x83, 0x83, 0x83,   0x83,  0x83,  0x83, 0x83,  0   },
    464 /* IO_RSP               */{ 0,    1,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    465 /* SEC_GRANT            */{ 0,    2,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    466 /* TK_REQ               */{ 0,    0,     0,      2,     0,   0,    0,   0,      3,      0,    0,    0,      0,     0,     0,    0,     0   },
    467 /* AUTH_CMPL            */{ 0,    0x82,  0x82,   0x82,  0x82,0x82, 0x82,0x82,   0x82,   0x82, 0x82, 0x82,   0x82,  0x82,  0x82, 0x82,  0   },
    468 /* ENC_REQ              */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     1,    0,     0   },
    469 /* BOND_REQ             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     4,    0,     0   },
    470 /* DISCARD_SEC_REQ      */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    471 /* PUBL_KEY_EXCH_REQ    */{ 0,    0,     0,      4,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    472 /* LOC_PUBL_KEY_CRTD    */{ 0,    0,     0,      0,     0,   0,    0,   1,      0,      0,    0,    0,      0,     0,     0,    0,     1   },
    473 /* BOTH_PUBL_KEYS_RCVD  */{ 0,    0,     0,      0,     0,   0,    0,   3,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    474 /* SC_DHKEY_CMPLT       */{ 0,    0,     0,      0,     0,   0,    0,   0,      1,      0,    0,    0,      0,     0,     0,    0,     0   },
    475 /* HAVE_LOC_NONCE       */{ 0,    0,     0,      0,     0,   0,    0,   0,      2,      0,    0,    0,      0,     0,     0,    0,     2   },
    476 /* SC_PHASE1_CMPLT      */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    1,      0,     0,     0,    0,     0   },
    477 /* SC_CALC_NC           */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    2,    0,      0,     0,     0,    0,     0   },
    478 /* SC_DSPL_NC           */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    3,    0,      0,     0,     0,    0,     0   },
    479 /* SC_NC_OK             */{ 0,    6,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    480 /* SC_2_DHCK_CHKS_PRES  */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      2,     0,     0,    0,     0   },
    481 /* SC_KEY_READY         */{ 0,    7,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     1,     0,    0,     0   },
    482 /* KEYPR_NOTIF          */{ 0,    10,    0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    483 /* SC_OOB_DATA          */{ 0,    11,    0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    484 /* CR_LOC_SC_OOB_DATA   */{ 3,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
    485 };
    486 
    487 static const UINT8 smp_slave_idle_table[][SMP_SM_NUM_COLS] =
    488 {
    489 /*                   Event                 Action                Next State */
    490 /* L2C_CONN */      {SMP_SEND_APP_CBACK,  SMP_SM_NO_ACTION,      SMP_STATE_WAIT_APP_RSP},
    491 /* PAIR_REQ */      {SMP_PROC_PAIR_CMD,   SMP_SEND_APP_CBACK,     SMP_STATE_WAIT_APP_RSP}
    492 /* CR_LOC_SC_OOB_DATA   */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}
    493 };
    494 
    495 static const UINT8 smp_slave_wait_for_app_response_table [][SMP_SM_NUM_COLS] =
    496 {
    497 /*               Event                   Action                 Next State */
    498 /* IO_RSP    */ {SMP_PROC_IO_RSP,       SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP},
    499 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT,    SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
    500 
    501                         /* TK ready */
    502 /* KEY_READY */ {SMP_PROC_SL_KEY,   SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    503 /* CONFIRM   */ {SMP_PROC_CONFIRM,   SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}
    504 /* DHKey Check from master is received before phase 1 is completed - race */
    505 /* PAIR_DHKEY_CHCK      */,{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION,  SMP_STATE_WAIT_APP_RSP},
    506 /* user confirms NC 'OK', i.e. phase 1 is completed */
    507 /* SC_NC_OK             */ {SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION,  SMP_STATE_SEC_CONN_PHS2_START},
    508 /* user-provided passkey is rcvd */
    509 /* SC_KEY_READY   */ {SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    510 /* PAIR_COMMITM   */ {SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    511 /* PAIR_KEYPR_NOTIF */ {SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
    512 /* KEYPR_NOTIF */ {SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    513 /* SC_OOB_DATA          */ {SMP_SEND_PAIR_RSP,    SMP_SM_NO_ACTION,    SMP_STATE_PAIR_REQ_RSP},
    514 };
    515 
    516 static const UINT8 smp_slave_sec_request_table[][SMP_SM_NUM_COLS] =
    517 {
    518 /*                          Event                  Action                 Next State */
    519 /* PAIR_REQ */{SMP_PROC_PAIR_CMD,       SMP_SM_NO_ACTION,       SMP_STATE_PAIR_REQ_RSP},
    520 /* ENCRYPTED*/{SMP_ENC_CMPL,            SMP_SM_NO_ACTION,       SMP_STATE_PAIR_REQ_RSP},
    521 };
    522 
    523 static const UINT8 smp_slave_pair_request_response_table[][SMP_SM_NUM_COLS] =
    524 {
    525 /*                          Event                  Action                 Next State */
    526 /* CONFIRM  */ {SMP_PROC_CONFIRM,       SMP_SM_NO_ACTION,   SMP_STATE_CONFIRM},
    527 /* TK_REQ   */ {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_STATE_WAIT_APP_RSP},
    528 
    529                     /* TK/Confirm ready */
    530 /* KEY_READY */{SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,   SMP_STATE_PAIR_REQ_RSP}
    531 /* PUBL_KEY_EXCH_REQ    */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
    532 /* PAIR_PUBLIC_KEY      */ { SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION,   SMP_STATE_PAIR_REQ_RSP},
    533 };
    534 
    535 static const UINT8 smp_slave_wait_confirm_table[][SMP_SM_NUM_COLS] =
    536 {
    537 /*                          Event                  Action                 Next State */
    538 /* CONFIRM  */ {SMP_PROC_CONFIRM,       SMP_SEND_CONFIRM,   SMP_STATE_CONFIRM},
    539 /* KEY_READY*/ {SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,   SMP_STATE_WAIT_CONFIRM}
    540 };
    541 
    542 static const UINT8 smp_slave_confirm_table[][SMP_SM_NUM_COLS] =
    543 {
    544 /*                          Event                  Action                 Next State */
    545 /* RAND     */ {SMP_PROC_RAND,          SMP_GENERATE_COMPARE,   SMP_STATE_RAND},
    546 
    547                     /* TK/Confirm ready */
    548 /* KEY_READY*/ {SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,       SMP_STATE_CONFIRM}
    549 };
    550 
    551 static const UINT8 smp_slave_rand_table[][SMP_SM_NUM_COLS] =
    552 {
    553 /*                          Event                  Action                 Next State */
    554 /* KEY_READY */ {SMP_PROC_COMPARE,      SMP_SM_NO_ACTION,   SMP_STATE_RAND}, /* compare match */
    555 /* RAND      */ {SMP_SEND_RAND,         SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}
    556 };
    557 
    558 static const UINT8 smp_slave_public_key_exch_table[][SMP_SM_NUM_COLS] =
    559 {
    560 /*                          Event                  Action                 Next State */
    561 /* LOC_PUBL_KEY_CRTD  */{ SMP_WAIT_FOR_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
    562 /* PAIR_PUBLIC_KEY      */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
    563 /* BOTH_PUBL_KEYS_RCVD */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    564 };
    565 
    566 static const UINT8 smp_slave_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] =
    567 {
    568 /*                          Event                  Action                 Next State */
    569 /* SC_DHKEY_CMPLT       */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    570 /* HAVE_LOC_NONCE       */{ SMP_PROCESS_LOCAL_NONCE,SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT},
    571 /* TK_REQ               */{ SMP_SEND_APP_CBACK,      SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    572 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display, it's time to start */
    573 /* commitment calculation */
    574 /* KEY_READY */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    575 /* PAIR_KEYPR_NOTIF  */{ SMP_PROCESS_KEYPRESS_NOTIFICATION,SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START},
    576 /*COMMIT*/{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
    577 };
    578 
    579 static const UINT8 smp_slave_wait_commitment_table[][SMP_SM_NUM_COLS] =
    580 {
    581 /*                          Event                  Action                 Next State */
    582 /* PAIR_COMMITM  */{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_COMMITMENT,  SMP_STATE_WAIT_NONCE},
    583 /* PAIR_KEYPR_NOTIF */{SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT},
    584 };
    585 
    586 static const UINT8 smp_slave_wait_nonce_table[][SMP_SM_NUM_COLS] =
    587 {
    588 /*                          Event                  Action                 Next State */
    589 /* peer nonce is received */
    590 /* RAND           */{SMP_PROC_RAND, SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START},
    591 /* NC model, time to calculate number for NC */
    592 /* SC_CALC_NC  */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE},
    593 /* NC model, time to display calculated number for NC to the user */
    594 /* SC_DSPL_NC   */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
    595 };
    596 
    597 static const UINT8 smp_slave_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] =
    598 {
    599 /*                          Event                  Action                 Next State */
    600 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_PH2_DHKEY_CHECKS_ARE_PRESENT, SMP_STATE_WAIT_DHK_CHECK},
    601 /* DHKey Check from master is received before slave DHKey calculation is completed - race */
    602 /* PAIR_DHKEY_CHCK  */{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START},
    603 };
    604 
    605 static const UINT8 smp_slave_wait_dhk_check_table[][SMP_SM_NUM_COLS] =
    606 {
    607 /*                          Event                  Action                 Next State */
    608 /* PAIR_DHKEY_CHCK      */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK},
    609 /* DHKey Check from master was received before slave came to this state */
    610 /* SC_2_DHCK_CHKS_PRES  */{SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
    611 };
    612 
    613 static const UINT8 smp_slave_dhk_check_table[][SMP_SM_NUM_COLS] =
    614 {
    615 /*                          Event                  Action                 Next State */
    616 
    617 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check */
    618 /* actually received from peer */
    619 /* SC_KEY_READY         */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
    620 
    621 /* dhkey checks match -> send local dhkey check to master, go to wait for HCI LE */
    622 /* Long Term Key Request Event */
    623 /* PAIR_DHKEY_CHCK      */{SMP_SEND_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    624 };
    625 
    626 static const UINT8 smp_slave_enc_pending_table[][SMP_SM_NUM_COLS] =
    627 {
    628 /*                          Event                  Action                 Next State */
    629 /* ENC_REQ   */ {SMP_GENERATE_STK,      SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    630 
    631                     /* STK ready */
    632 /* KEY_READY */ {SMP_SEND_LTK_REPLY,    SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    633 /* ENCRYPTED */ {SMP_CHECK_AUTH_REQ,    SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
    634 /* BOND_REQ  */ {SMP_KEY_DISTRIBUTE,    SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
    635 };
    636 static const UINT8 smp_slave_bond_pending_table[][SMP_SM_NUM_COLS] =
    637 {
    638 /*                          Event                  Action                 Next State */
    639 
    640                 /* LTK ready */
    641 /* KEY_READY */{ SMP_SEND_ENC_INFO,     SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    642 
    643                 /* rev SRK */
    644 /* SIGN_INFO */{ SMP_PROC_SRK_INFO,     SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    645 /* ENC_INFO */ { SMP_PROC_ENC_INFO,     SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    646 /* ID_INFO  */ { SMP_PROC_ID_INFO,      SMP_SM_NO_ACTION,  SMP_STATE_BOND_PENDING},
    647 /* MASTER_ID*/ { SMP_PROC_MASTER_ID,    SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
    648 /* ID_ADDR  */ { SMP_PROC_ID_ADDR,      SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
    649 
    650 };
    651 
    652 static const UINT8 smp_slave_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] =
    653 {
    654 /*                          Event                  Action                 Next State */
    655 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA},
    656 /* HAVE_LOC_NONCE    */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
    657 };
    658 
    659 static const tSMP_SM_TBL smp_state_table[][2] =
    660 {
    661     /* SMP_STATE_IDLE */
    662     {smp_master_idle_table, smp_slave_idle_table},
    663 
    664     /* SMP_STATE_WAIT_APP_RSP */
    665     {smp_master_wait_for_app_response_table, smp_slave_wait_for_app_response_table},
    666 
    667     /* SMP_STATE_SEC_REQ_PENDING */
    668     {NULL, smp_slave_sec_request_table},
    669 
    670     /* SMP_STATE_PAIR_REQ_RSP */
    671     {smp_master_pair_request_response_table, smp_slave_pair_request_response_table},
    672 
    673     /* SMP_STATE_WAIT_CONFIRM */
    674     {smp_master_wait_for_confirm_table, smp_slave_wait_confirm_table},
    675 
    676     /* SMP_STATE_CONFIRM */
    677     {smp_master_confirm_table, smp_slave_confirm_table},
    678 
    679     /* SMP_STATE_RAND */
    680     {smp_master_rand_table, smp_slave_rand_table},
    681 
    682     /* SMP_STATE_PUBLIC_KEY_EXCH */
    683     {smp_master_public_key_exchange_table,smp_slave_public_key_exch_table},
    684 
    685     /* SMP_STATE_SEC_CONN_PHS1_START */
    686     {smp_master_sec_conn_phs1_start_table, smp_slave_sec_conn_phs1_start_table},
    687 
    688     /* SMP_STATE_WAIT_COMMITMENT */
    689     {smp_master_wait_commitment_table, smp_slave_wait_commitment_table},
    690 
    691     /* SMP_STATE_WAIT_NONCE */
    692     {smp_master_wait_nonce_table, smp_slave_wait_nonce_table},
    693 
    694      /* SMP_STATE_SEC_CONN_PHS2_START */
    695     {smp_master_sec_conn_phs2_start_table, smp_slave_sec_conn_phs2_start_table},
    696 
    697     /* SMP_STATE_WAIT_DHK_CHECK */
    698     {smp_master_wait_dhk_check_table, smp_slave_wait_dhk_check_table},
    699 
    700     /* SMP_STATE_DHK_CHECK */
    701     {smp_master_dhk_check_table, smp_slave_dhk_check_table},
    702 
    703     /* SMP_STATE_ENCRYPTION_PENDING */
    704     {smp_master_enc_pending_table, smp_slave_enc_pending_table},
    705 
    706      /* SMP_STATE_BOND_PENDING */
    707     {smp_master_bond_pending_table, smp_slave_bond_pending_table},
    708 
    709     /* SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA */
    710     {smp_master_create_local_sec_conn_oob_data, smp_slave_create_local_sec_conn_oob_data}
    711 };
    712 
    713 typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_STATE_MAX];
    714 static const tSMP_ENTRY_TBL smp_entry_table[] =
    715 {
    716     smp_master_entry_map,
    717     smp_slave_entry_map
    718 };
    719 
    720 #if SMP_DYNAMIC_MEMORY == FALSE
    721 tSMP_CB  smp_cb;
    722 #endif
    723 #define SMP_ALL_TBL_MASK        0x80
    724 
    725 /*******************************************************************************
    726 ** Function     smp_set_state
    727 ** Returns      None
    728 *******************************************************************************/
    729 void smp_set_state(tSMP_STATE state)
    730 {
    731     if (state < SMP_STATE_MAX)
    732     {
    733         SMP_TRACE_DEBUG( "State change: %s(%d) ==> %s(%d)",
    734                           smp_get_state_name(smp_cb.state), smp_cb.state,
    735                           smp_get_state_name(state), state );
    736         smp_cb.state = state;
    737     }
    738     else
    739     {
    740         SMP_TRACE_DEBUG("smp_set_state invalid state =%d", state );
    741     }
    742 }
    743 
    744 /*******************************************************************************
    745 ** Function     smp_get_state
    746 ** Returns      The smp state
    747 *******************************************************************************/
    748 tSMP_STATE smp_get_state(void)
    749 {
    750     return smp_cb.state;
    751 }
    752 
    753 /*******************************************************************************
    754 **
    755 ** Function     smp_sm_event
    756 **
    757 ** Description  Handle events to the state machine. It looks up the entry
    758 **              in the smp_entry_table array.
    759 **              If it is a valid entry, it gets the state table.Set the next state,
    760 **              if not NULL state.Execute the action function according to the
    761 **              state table. If the state returned by action function is not NULL
    762 **              state, adjust the new state to the returned state.If (api_evt != MAX),
    763 **              call callback function.
    764 **
    765 ** Returns      void.
    766 **
    767 *******************************************************************************/
    768 void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
    769 {
    770     UINT8           curr_state = p_cb->state;
    771     tSMP_SM_TBL     state_table;
    772     UINT8           action, entry, i;
    773     tSMP_ENTRY_TBL  entry_table =  smp_entry_table[p_cb->role];
    774 
    775     SMP_TRACE_EVENT("main smp_sm_event");
    776     if (curr_state >= SMP_STATE_MAX)
    777     {
    778         SMP_TRACE_DEBUG( "Invalid state: %d", curr_state) ;
    779         return;
    780     }
    781 
    782     SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
    783                       (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
    784                       p_cb->state, smp_get_event_name(event), event) ;
    785 
    786     /* look up the state table for the current state */
    787     /* lookup entry /w event & curr_state */
    788     /* If entry is ignore, return.
    789      * Otherwise, get state table (according to curr_state or all_state) */
    790     if ((event <= SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
    791     {
    792         if (entry & SMP_ALL_TBL_MASK)
    793         {
    794             entry &= ~SMP_ALL_TBL_MASK;
    795             state_table = smp_all_table;
    796         }
    797         else
    798             state_table = smp_state_table[curr_state][p_cb->role];
    799     }
    800     else
    801     {
    802         SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
    803                           smp_get_event_name(event), event, smp_get_state_name(curr_state),
    804                           curr_state);
    805         return;
    806     }
    807 
    808     /* Get possible next state from state table. */
    809 
    810     smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);
    811 
    812     /* If action is not ignore, clear param, exec action and get next state.
    813      * The action function may set the Param for cback.
    814      * Depending on param, call cback or free buffer. */
    815     /* execute action */
    816     /* execute action functions */
    817     for (i = 0; i < SMP_NUM_ACTIONS; i++)
    818     {
    819         if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
    820         {
    821             (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
    822         }
    823         else
    824         {
    825             break;
    826         }
    827     }
    828     SMP_TRACE_DEBUG( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
    829 }
    830 
    831 /*******************************************************************************
    832 ** Function     smp_get_state_name
    833 ** Returns      The smp state name.
    834 *******************************************************************************/
    835 const char * smp_get_state_name(tSMP_STATE state)
    836 {
    837     const char *p_str = smp_state_name[SMP_STATE_MAX];
    838 
    839     if (state < SMP_STATE_MAX)
    840     {
    841         p_str = smp_state_name[state];
    842     }
    843     return p_str;
    844 }
    845 
    846 /*******************************************************************************
    847 ** Function     smp_get_event_name
    848 ** Returns      The smp event name.
    849 *******************************************************************************/
    850 const char * smp_get_event_name(tSMP_EVENT event)
    851 {
    852     const char *p_str = smp_event_name[SMP_MAX_EVT];
    853 
    854     if (event <= SMP_MAX_EVT)
    855     {
    856         p_str = smp_event_name[event- 1];
    857     }
    858     return p_str;
    859 }
    860 
    861 #endif
    862 
    863