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 
     27 const char * const smp_state_name [] =
     28 {
     29     "SMP_ST_IDLE",
     30     "SMP_ST_WAIT_APP_RSP",
     31     "SMP_ST_SEC_REQ_PENDING",
     32     "SMP_ST_PAIR_REQ_RSP",
     33     "SMP_ST_WAIT_CONFIRM",
     34     "SMP_ST_CONFIRM",
     35     "SMP_ST_RAND",
     36     "SMP_ST_ENC_PENDING",
     37     "SMP_ST_BOND_PENDING",
     38     "SMP_ST_RELEASE_DELAY",
     39     "SMP_ST_MAX"
     40 };
     41 const char * const smp_event_name [] =
     42 {
     43     "PAIRING_REQ_EVT",
     44     "PAIRING_RSP_EVT",
     45     "CONFIRM_EVT",
     46     "RAND_EVT",
     47     "PAIRING_FAILED_EVT",
     48     "ENC_INFO_EVT",
     49     "MASTER_ID_EVT",
     50     "ID_INFO_EVT",
     51     "ID_ADDR_EVT",
     52     "SIGN_INFO_EVT",
     53     "SECURITY_REQ_EVT",
     54     "KEY_READY_EVT",
     55     "ENCRYPTED_EVT",
     56     "L2CAP_CONN_EVT",
     57     "L2CAP_DISCONN_EVT",
     58     "API_IO_RSP_EVT",
     59     "API_SEC_GRANT_EVT",
     60     "TK_REQ_EVT",
     61     "AUTH_CMPL_EVT",
     62     "ENC_REQ_EVT",
     63     "BOND_REQ_EVT",
     64     "DISCARD_SEC_REQ_EVT",
     65     "RELEASE_DELAY_EVT",
     66     "RELEASE_DELAY_TOUT_EVT",
     67     "MAX_EVT"
     68 };
     69 const char * smp_get_event_name(tSMP_EVENT event);
     70 const char * smp_get_state_name(tSMP_STATE state);
     71 
     72     #define SMP_SM_IGNORE       0
     73     #define SMP_NUM_ACTIONS     2
     74     #define SMP_SME_NEXT_STATE  2
     75     #define SMP_SM_NUM_COLS     3
     76 typedef const UINT8 (*tSMP_SM_TBL)[SMP_SM_NUM_COLS];
     77 
     78 enum
     79 {
     80     SMP_PROC_SEC_REQ,
     81     SMP_SEND_PAIR_REQ,
     82     SMP_SEND_PAIR_RSP,
     83     SMP_SEND_CONFIRM,
     84     SMP_SEND_PAIR_FAIL,
     85     SMP_SEND_INIT,
     86     SMP_SEND_SECU_INFO,
     87     SMP_SEND_ID_INFO,
     88     SMP_SEND_LTK_REPLY,
     89     SMP_PROC_PAIR_CMD,
     90     SMP_PROC_PAIR_FAIL,
     91     SMP_PROC_CONFIRM,
     92     SMP_PROC_INIT,
     93     SMP_PROC_ENC_INFO,
     94     SMP_PROC_MASTER_ID,
     95     SMP_PROC_ID_INFO,
     96     SMP_PROC_ID_ADDR,
     97     SMP_PROC_SRK_INFO,
     98     SMP_PROC_SEC_GRANT,
     99     SMP_PROC_SL_KEY,
    100     SMP_PROC_COMPARE,
    101     SMP_PROC_IO_RSP,
    102     SMP_GENERATE_COMPARE,
    103     SMP_GENERATE_CONFIRM,
    104     SMP_GENERATE_STK,
    105     SMP_KEY_DISTRIBUTE,
    106     SMP_START_ENC,
    107     SMP_PAIRING_CMPL,
    108     SMP_DECIDE_ASSO_MODEL,
    109     SMP_SEND_APP_CBACK,
    110     SMP_CHECK_AUTH_REQ,
    111     SMP_PAIR_TERMINATE,
    112     SMP_ENC_CMPL,
    113     SMP_PROC_DISCARD,
    114     SMP_PROC_REL_DELAY,
    115     SMP_PROC_REL_DELAY_TOUT,
    116     SMP_DELAY_TERMINATE,
    117     SMP_SM_NO_ACTION
    118 };
    119 
    120 static const tSMP_ACT smp_sm_action[] =
    121 {
    122     smp_proc_sec_req,
    123     smp_send_pair_req,
    124     smp_send_pair_rsp,
    125     smp_send_confirm,
    126     smp_send_pair_fail,
    127     smp_send_init,
    128     smp_send_enc_info,
    129     smp_send_id_info,
    130     smp_send_ltk_reply,
    131     smp_proc_pair_cmd,
    132     smp_proc_pair_fail,
    133     smp_proc_confirm,
    134     smp_proc_init,
    135     smp_proc_enc_info,
    136     smp_proc_master_id,
    137     smp_proc_id_info,
    138     smp_proc_id_addr,
    139     smp_proc_srk_info,
    140     smp_proc_sec_grant,
    141     smp_proc_sl_key,
    142     smp_proc_compare,
    143     smp_proc_io_rsp,
    144     smp_generate_compare,
    145     smp_generate_confirm,
    146     smp_generate_stk,
    147     smp_key_distribution,
    148     smp_start_enc,
    149     smp_pairing_cmpl,
    150     smp_decide_asso_model,
    151     smp_send_app_cback,
    152     smp_check_auth_req,
    153     smp_pair_terminate,
    154     smp_enc_cmpl,
    155     smp_proc_discard,
    156     smp_proc_release_delay,
    157     smp_proc_release_delay_tout,
    158     smp_delay_terminate,
    159 };
    160 /************ SMP Master FSM State/Event Indirection Table **************/
    161 static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
    162 {
    163 /* state name:           Idle WaitApp SecReq Pair   Wait Confirm Init Enc   Bond  Rel
    164                                Rsp    Pend   ReqRsp Cfm              Pend  Pend   Delay    */
    165 /* PAIR_REQ           */{ 0,    0,     0,      0,     0,   0,    0,   0,    0,     0   },
    166 /* PAIR_RSP           */{ 0,    0,     0,      1,     0,   0,    0,   0,    0,     0   },
    167 /* CONFIRM            */{ 0,    0,     0,      0,     0,   1,    0,   0,    0,     0   },
    168 /* INIT               */{ 0,    0,     0,      0,     0,   0,    1,   0,    0,     0   },
    169 /* PAIR_FAIL          */{ 0,    0x81,  0,      0x81,  0x81,0x81, 0x81,0,    0,     0   },
    170 /* ENC_INFO           */{ 0,    0,     0,      0,     0,   0,    0,   0,    1,     0   },
    171 /* MASTER_ID          */{ 0,    0,     0,      0,     0,   0,    0,   0,    4,     0   },
    172 /* ID_INFO            */{ 0,    0,     0,      0,     0,   0,    0,   0,    2,     0   },
    173 /* ID_ADDR            */{ 0,    0,     0,      0,     0,   0,    0,   0,    5,     0   },
    174 /* SIGN_INFO          */{ 0,    0,     0,      0,     0,   0,    0,   0,    3,     0   },
    175 /* SEC_REQ            */{ 2,    0,     0,      0,     0,   0,    0,   0,    0,     0   },
    176 /* KEY_READY          */{ 0,    3,     0,      3,     1,   0,    2,   1,    6,     0   },
    177 /* ENC_CMPL           */{ 0,    0,     0,      0,     0,   0,    0,   2,    0,     0   },
    178 /* L2C_CONN           */{ 1,    0,     0,      0,     0,   0,    0,   0,    0,     0   },
    179 /* L2C_DISC           */{ 0x83,	0x83,  0,      0x83,  0x83,0x83, 0x83,0x83, 0x83,  3   },
    180 /* IO_RSP             */{ 0,    2,     0,      0,     0,   0,    0,   0,    0,     0   },
    181 /* SEC_GRANT          */{ 0,    1,     0,      0,     0,   0,    0,   0,    0,     0   },
    182 /* TK_REQ             */{ 0,    0,     0,      2,     0,   0,    0,   0,    0,     0   },
    183 /* AUTH_CMPL          */{ 0,    0x82,  0,      0x82,  0x82,0x82, 0x82,0x82, 0x82,  0   },
    184 /* ENC_REQ            */{ 0,    4,     0,      0,     0,   0,    3,   0,    0,     0   },
    185 /* BOND_REQ           */{ 0,    0,     0,      0,     0,   0,    0,   3,    0,     0   },
    186 /* DISCARD_SEC_REQ    */{ 0,    5,     0,      0,     0,   0,    0,   3,    0,     0   },
    187 /* RELEASE_DELAY      */{ 0,    0,     0,      0,     0,   0,    0,   0,    0,     1   },
    188 /* RELEASE_DELAY_TOUT */{ 0,    0,     0,      0,     0,   0,    0,   0,    0,     2   },
    189 };
    190 
    191 static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] = {
    192 /* Event       			Action                              Next State */
    193 /* PAIR_FAIL */          {SMP_PROC_PAIR_FAIL,       SMP_PROC_REL_DELAY_TOUT,    SMP_ST_IDLE},
    194 /* AUTH_CMPL */          {SMP_SEND_PAIR_FAIL,      SMP_PAIRING_CMPL,      SMP_ST_RELEASE_DELAY},
    195 /* L2C_DISC  */          {SMP_PAIR_TERMINATE,      SMP_SM_NO_ACTION,      SMP_ST_IDLE}
    196 };
    197 
    198 static const UINT8 smp_ma_idle_table[][SMP_SM_NUM_COLS] = {
    199 /* Event       Action                   Next State */
    200 /* L2C_CONN */      {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_ST_WAIT_APP_RSP},
    201 /* SEC_REQ  */      {SMP_PROC_SEC_REQ,       SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}
    202 };
    203 
    204 static const UINT8 smp_ma_wait_app_rsp_table[][SMP_SM_NUM_COLS] = {
    205 /* Event       			                                 Action          Next State */
    206 /* SEC_GRANT            */ { SMP_PROC_SEC_GRANT,   SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
    207 /* IO_RSP               */ { SMP_SEND_PAIR_REQ,    SMP_SM_NO_ACTION,   SMP_ST_PAIR_REQ_RSP},
    208 /* KEY_READY            */ { SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION,   SMP_ST_WAIT_CONFIRM},/* TK ready */
    209 /* ENC_REQ              */ { SMP_START_ENC,        SMP_SM_NO_ACTION,   SMP_ST_ENC_PENDING},/* start enc mode setup */
    210 /* DISCARD_SEC_REQ      */ { SMP_PROC_DISCARD,     SMP_SM_NO_ACTION,   SMP_ST_IDLE}
    211 };
    212 
    213 static const UINT8 smp_ma_pair_req_rsp_table [][SMP_SM_NUM_COLS] = {
    214 /* Event       		Action              Next State */
    215 /* PAIR_RSP */ { SMP_PROC_PAIR_CMD,     SMP_DECIDE_ASSO_MODEL,  SMP_ST_PAIR_REQ_RSP},
    216 /* TK_REQ   */ { SMP_SEND_APP_CBACK,    SMP_SM_NO_ACTION,       SMP_ST_WAIT_APP_RSP},
    217 /* KEY_READY */{ SMP_GENERATE_CONFIRM,  SMP_SM_NO_ACTION,       SMP_ST_WAIT_CONFIRM} /* TK ready */
    218 };
    219 
    220 static const UINT8 smp_ma_wait_confirm_table[][SMP_SM_NUM_COLS] = {
    221 /* Event       			Action          Next State */
    222 /* KEY_READY*/ {SMP_SEND_CONFIRM,       SMP_SM_NO_ACTION,       SMP_ST_CONFIRM}/* CONFIRM ready */
    223 };
    224 
    225 static const UINT8 smp_ma_confirm_table [][SMP_SM_NUM_COLS] = {
    226 /* Event       			Action          Next State */
    227 /* CONFIRM  */ { SMP_PROC_CONFIRM,      SMP_SEND_INIT,          SMP_ST_RAND}
    228 };
    229 
    230 static const UINT8 smp_ma_init_table [][SMP_SM_NUM_COLS] = {
    231 /* Event       			Action          Next State */
    232 /* INIT     */ { SMP_PROC_INIT,         SMP_GENERATE_COMPARE,    SMP_ST_RAND},
    233 /* KEY_READY*/ { SMP_PROC_COMPARE,      SMP_SM_NO_ACTION,   SMP_ST_RAND},  /* Compare ready */
    234 /* ENC_REQ  */ { SMP_GENERATE_STK,      SMP_SM_NO_ACTION,   SMP_ST_ENC_PENDING}
    235 };
    236 static const UINT8 smp_ma_enc_pending_table[][SMP_SM_NUM_COLS] = {
    237 /* Event       			Action          Next State */
    238 /* KEY_READY */ { SMP_START_ENC,        SMP_SM_NO_ACTION,   SMP_ST_ENC_PENDING},  /* STK ready */
    239 /* ENCRYPTED */ { SMP_CHECK_AUTH_REQ,   SMP_SM_NO_ACTION,   SMP_ST_ENC_PENDING},
    240 /* BOND_REQ  */ { SMP_KEY_DISTRIBUTE,   SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING}
    241 };
    242 static const UINT8 smp_ma_bond_pending_table[][SMP_SM_NUM_COLS] = {
    243 /* Event       			Action          Next State */
    244 /* ENC_INFO */ { SMP_PROC_ENC_INFO,     SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING},
    245 /* ID_INFO  */ { SMP_PROC_ID_INFO,      SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING},
    246 /* SIGN_INFO*/ { SMP_PROC_SRK_INFO,     SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING},
    247 /* MASTER_ID*/ { SMP_PROC_MASTER_ID,    SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING},
    248 /* ID_ADDR  */ { SMP_PROC_ID_ADDR,      SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING},
    249 /* KEY_READY */ {SMP_SEND_SECU_INFO,    SMP_SM_NO_ACTION,   SMP_ST_BOND_PENDING}   /* LTK ready */
    250 };
    251 
    252 static const UINT8 smp_ma_rel_delay_table[][SMP_SM_NUM_COLS] = {
    253 /* Event       Action                   Next State */
    254 /* RELEASE_DELAY*/       {SMP_PROC_REL_DELAY,      SMP_SM_NO_ACTION,      SMP_ST_RELEASE_DELAY},
    255 /* RELEASE_DELAY_TOUT*/  {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION,      SMP_ST_IDLE},
    256 /* L2C_DISC*/            {SMP_DELAY_TERMINATE,     SMP_SM_NO_ACTION,     SMP_ST_IDLE}
    257 };
    258 
    259 
    260 /************ SMP Slave FSM State/Event Indirection Table **************/
    261 static const UINT8 smp_sl_entry_map[][SMP_ST_MAX] =
    262 {
    263 /* state name:            Idle Wait   SecReq Pair   Wait Confirm Init Enc   Bond  Rel
    264                                AppRsp Pend   ReqRsp Cfm              Pend  Pend   Delay   */
    265 /* PAIR_REQ */           { 2,    0,    1,      0,     0,   0,    0,   0,    0,     0       },
    266 /* PAIR_RSP */           { 0,    0,    0,      0,     0,   0,    0,   0,    0,     0       },
    267 /* CONFIRM  */           { 0,    4,    0,      1,     1,   0,    0,   0,    0,     0       },
    268 /* INIT     */           { 0,    0,    0,      0,     0,   1,    2,   0,    0,     0       },
    269 /* PAIR_FAIL*/           { 0,    0x81, 0x81,   0x81,  0x81,0x81, 0x81,0x81, 0,     0       },
    270 /* ENC_INFO */           { 0,    0,    0,      0,     0,   0,    0,   0,    3,     0       },
    271 /* MASTER_ID*/           { 0,    0,    0,      0,     0,   0,    0,   0,    5,     0       },
    272 /* ID_INFO  */           { 0,    0,    0,      0,     0,   0,    0,   0,    4,     0       },
    273 /* ID_ADDR  */           { 0,    0,    0,      0,     0,   0,    0,   0,    6,     0       },
    274 /* SIGN_INFO*/           { 0,    0,    0,      0,     0,   0,    0,   0,    2,     0       },
    275 /* SEC_REQ  */           { 0,    0,    0,      0,     0,   0,    0,   0,    0,     0       },
    276 
    277 /* KEY_READY*/           { 0,    3,    0,      3,     2,   2,    1,   2,    1,     0       },
    278 /* ENC_CMPL */           { 0,    0,    2,      0,     0,   0,    0,   3,    0,     0       },
    279 /* L2C_CONN */           { 1,    0,    0,      0,     0,   0,    0,   0,    0,     0       },
    280 /* L2C_DISC */           { 0,    0x83, 0x83,   0x83,  0x83,0x83, 0x83,0x83, 0x83,  2       },
    281 /* IO_RSP   */           { 0,    1,    0,      0,     0,   0,    0,   0,    0,     0       },
    282 /* SEC_GRANT*/           { 0,    2,    0,      0,     0,   0,    0,   0,    0,     0       },
    283 
    284 /* TK_REQ   */           { 0,    0,    0,      2,     0,   0,    0,   0,    0,     0       },
    285 /* AUTH_CMPL*/           { 0,    0x82, 0x82,   0x82,  0x82,0x82, 0x82,0x82, 0x82,  0       },
    286 /* ENC_REQ  */           { 0,    0,    0,      0,     0,   0,    0,   1,    0,     0       },
    287 /* BOND_REQ */           { 0,    0,    0,      0,     0,   0,    0,   4,    0,     0       },
    288 /* DISCARD_SEC_REQ    */ { 0,    0,    0,      0,     0,   0,    0,   0,    0,     0       },
    289 /* RELEASE_DELAY      */ { 0,    0,    0,      0,     0,   0,    0,   0,    0,     1       },
    290 /* RELEASE_DELAY_TOUT */ { 0,    0,    0,      0,     0,   0,    0,   0,    0,     2       },
    291 };
    292 
    293 static const UINT8 smp_sl_idle_table[][SMP_SM_NUM_COLS] = {
    294 /* Event       			Action                              Next State */
    295 /* L2C_CONN */      {SMP_SEND_APP_CBACK,  SMP_SM_NO_ACTION,       SMP_ST_WAIT_APP_RSP},
    296 /* PAIR_REQ */      {SMP_PROC_PAIR_CMD,   SMP_SEND_APP_CBACK,     SMP_ST_WAIT_APP_RSP}
    297 };
    298 
    299 static const UINT8 smp_sl_wait_app_rsp_table [][SMP_SM_NUM_COLS] = {
    300 /* Event       			Action              Next State */
    301 /* IO_RSP    */ {SMP_PROC_IO_RSP,       SMP_SM_NO_ACTION,       SMP_ST_PAIR_REQ_RSP},
    302 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT,    SMP_SEND_APP_CBACK,     SMP_ST_WAIT_APP_RSP},
    303 /* KEY_READY */ {SMP_PROC_SL_KEY,       SMP_SM_NO_ACTION,       SMP_ST_WAIT_APP_RSP},/* TK ready */
    304 /* CONFIRM   */ {SMP_PROC_CONFIRM,      SMP_SM_NO_ACTION,       SMP_ST_CONFIRM}
    305 };
    306 
    307 static const UINT8 smp_sl_sec_request_table[][SMP_SM_NUM_COLS] = {
    308 /* Event       			Action          Next State */
    309 /* PAIR_REQ */{SMP_PROC_PAIR_CMD,       SMP_SEND_PAIR_RSP,      SMP_ST_PAIR_REQ_RSP},
    310 /* ENCRYPTED*/{SMP_ENC_CMPL,        SMP_SM_NO_ACTION,       SMP_ST_PAIR_REQ_RSP},
    311 };
    312 
    313 static const UINT8 smp_sl_pair_req_rsp_table[][SMP_SM_NUM_COLS] = {
    314 /* Event       			Action                   		Next State */
    315 /* CONFIRM  */ {SMP_PROC_CONFIRM,       SMP_SM_NO_ACTION,   SMP_ST_CONFIRM},
    316 /* TK_REQ   */ {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_ST_WAIT_APP_RSP},
    317 /* KEY_READY */{SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,   SMP_ST_PAIR_REQ_RSP} /* TK/Confirm ready */
    318 
    319 };
    320 
    321 static const UINT8 smp_sl_wait_confirm_table[][SMP_SM_NUM_COLS] = {
    322 /* Event       			Action                   			Next State */
    323 /* CONFIRM  */ {SMP_PROC_CONFIRM,       SMP_SEND_CONFIRM,   SMP_ST_CONFIRM},
    324 /* KEY_READY*/ {SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,   SMP_ST_WAIT_CONFIRM}
    325 };
    326 static const UINT8 smp_sl_confirm_table [][SMP_SM_NUM_COLS] = {
    327 /* Event       			Action                   		Next State */
    328 /* INIT_EVT */{ SMP_PROC_INIT,          SMP_GENERATE_COMPARE,   SMP_ST_RAND},
    329 /* KEY_READY*/ {SMP_PROC_SL_KEY,        SMP_SM_NO_ACTION,       SMP_ST_CONFIRM} /* TK/Confirm ready */
    330 };
    331 static const UINT8 smp_sl_init_table [][SMP_SM_NUM_COLS] = {
    332 /* Event       			Action                   		        Next State */
    333 /* KEY_READY */ {SMP_PROC_COMPARE,      SMP_SM_NO_ACTION,       SMP_ST_RAND},   /* compare match */
    334 /* INIT_EVT  */ {SMP_SEND_INIT,         SMP_SM_NO_ACTION,       SMP_ST_ENC_PENDING}
    335 };
    336 static const UINT8 smp_sl_enc_pending_table[][SMP_SM_NUM_COLS] = {
    337 /* Event       			Action                   		Next State */
    338 /* ENC_REQ   */ {SMP_GENERATE_STK,      SMP_SM_NO_ACTION,       SMP_ST_ENC_PENDING},
    339 /* KEY_READY */ {SMP_SEND_LTK_REPLY,    SMP_SM_NO_ACTION,       SMP_ST_ENC_PENDING},/* STK ready */
    340 /* ENCRYPTED */ {SMP_CHECK_AUTH_REQ,    SMP_SM_NO_ACTION,       SMP_ST_ENC_PENDING},
    341 /* BOND_REQ  */ {SMP_KEY_DISTRIBUTE,    SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING}
    342 };
    343 static const UINT8 smp_sl_bond_pending_table[][SMP_SM_NUM_COLS] = {
    344 /* Event       			Action                   		Next State */
    345 /* KEY_READY */ {SMP_SEND_SECU_INFO,    SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING},   /* LTK ready */
    346 /* SIGN_INFO */ {SMP_PROC_SRK_INFO,     SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING},   /* rev SRK */
    347 /* ENC_INFO */ { SMP_PROC_ENC_INFO,     SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING},
    348 /* ID_INFO  */ { SMP_PROC_ID_INFO,      SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING},
    349 /* MASTER_ID*/ { SMP_PROC_MASTER_ID,    SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING},
    350 /* ID_ADDR  */ { SMP_PROC_ID_ADDR,      SMP_SM_NO_ACTION,       SMP_ST_BOND_PENDING}
    351 
    352 };
    353 
    354 static const UINT8 smp_sl_rel_delay_table[][SMP_SM_NUM_COLS] = {
    355 /* Event       Action                   Next State */
    356 /* RELEASE_DELAY*/       {SMP_PROC_REL_DELAY,      SMP_SM_NO_ACTION,      SMP_ST_RELEASE_DELAY},
    357 /* RELEASE_DELAY_TOUT*/  {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION,      SMP_ST_IDLE}
    358 };
    359 
    360 static const tSMP_SM_TBL smp_state_table[][2] = {
    361     {smp_ma_idle_table,          smp_sl_idle_table},                  /* SMP_ST_IDLE*/
    362     {smp_ma_wait_app_rsp_table,  smp_sl_wait_app_rsp_table},           /* SMP_ST_WAIT_APP_RSP */
    363     {NULL,                       smp_sl_sec_request_table},            /* SMP_ST_SEC_REQ_PENDING */
    364     {smp_ma_pair_req_rsp_table,  smp_sl_pair_req_rsp_table},           /* SMP_ST_PAIR_REQ_RSP */
    365     {smp_ma_wait_confirm_table,  smp_sl_wait_confirm_table},           /* SMP_ST_WAIT_CONFIRM */
    366     {smp_ma_confirm_table,       smp_sl_confirm_table},                /* SMP_ST_CONFIRM */
    367     {smp_ma_init_table,          smp_sl_init_table},                   /* SMP_ST_RAND */
    368     {smp_ma_enc_pending_table,   smp_sl_enc_pending_table},            /* SMP_ST_ENC_PENDING */
    369     {smp_ma_bond_pending_table,  smp_sl_bond_pending_table},           /* SMP_ST_BOND_PENDING */
    370     {smp_ma_rel_delay_table,     smp_sl_rel_delay_table}               /* SMP_ST_RELEASE_DELAY */
    371 };
    372 
    373 typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_ST_MAX];
    374 static const tSMP_ENTRY_TBL smp_entry_table[] ={
    375     smp_ma_entry_map,
    376     smp_sl_entry_map
    377 };
    378 
    379 #if SMP_DYNAMIC_MEMORY == FALSE
    380 tSMP_CB  smp_cb;
    381 #endif
    382 #define SMP_ALL_TBL_MASK        0x80
    383 
    384 
    385 /*******************************************************************************
    386 ** Function     smp_set_state
    387 ** Returns      None
    388 *******************************************************************************/
    389 void smp_set_state(tSMP_STATE state)
    390 {
    391     if (state < SMP_ST_MAX)
    392     {
    393         SMP_TRACE_DEBUG4( "State change: %s(%d) ==> %s(%d)",
    394                           smp_get_state_name(smp_cb.state), smp_cb.state,
    395                           smp_get_state_name(state), state );
    396         smp_cb.state = state;
    397     }
    398     else
    399     {
    400         SMP_TRACE_DEBUG1("smp_set_state invalid state =%d", state );
    401     }
    402 }
    403 
    404 /*******************************************************************************
    405 ** Function     smp_get_state
    406 ** Returns      The smp state
    407 *******************************************************************************/
    408 tSMP_STATE smp_get_state(void)
    409 {
    410     return smp_cb.state;
    411 }
    412 
    413 
    414 /*******************************************************************************
    415 **
    416 ** Function     smp_sm_event
    417 **
    418 ** Description  Handle events to the state machine. It looks up the entry
    419 **              in the smp_entry_table array.
    420 **              If it is a valid entry, it gets the state table.Set the next state,
    421 **              if not NULL state.Execute the action function according to the
    422 **              state table. If the state returned by action function is not NULL
    423 **              state, adjust the new state to the returned state.If (api_evt != MAX),
    424 **              call callback function.
    425 **
    426 ** Returns      void.
    427 **
    428 *******************************************************************************/
    429 void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
    430 {
    431     UINT8           curr_state = p_cb->state;
    432     tSMP_SM_TBL     state_table;
    433     UINT8           action, entry, i;
    434     tSMP_ENTRY_TBL  entry_table =  smp_entry_table[p_cb->role];
    435 
    436     SMP_TRACE_EVENT0("main smp_sm_event");
    437     if (curr_state >= SMP_ST_MAX)
    438     {
    439         SMP_TRACE_DEBUG1( "Invalid state: %d", curr_state) ;
    440         return;
    441     }
    442 
    443     SMP_TRACE_DEBUG5( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
    444                       (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
    445                       p_cb->state, smp_get_event_name(event), event) ;
    446 
    447     /* look up the state table for the current state */
    448     /* lookup entry /w event & curr_state */
    449     /* If entry is ignore, return.
    450      * Otherwise, get state table (according to curr_state or all_state) */
    451     if ((event < SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
    452     {
    453         if (entry & SMP_ALL_TBL_MASK)
    454         {
    455             entry &= ~SMP_ALL_TBL_MASK;
    456             state_table = smp_all_table;
    457         }
    458         else
    459             state_table = smp_state_table[curr_state][p_cb->role];
    460     }
    461     else
    462     {
    463         SMP_TRACE_DEBUG4( "Ignore event [%s (%d)] in state [%s (%d)]",
    464                           smp_get_event_name(event), event, smp_get_state_name(curr_state), curr_state);
    465         return;
    466     }
    467 
    468     /* Get possible next state from state table. */
    469 
    470     smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);
    471 
    472     /* If action is not ignore, clear param, exec action and get next state.
    473      * The action function may set the Param for cback.
    474      * Depending on param, call cback or free buffer. */
    475     /* execute action */
    476     /* execute action functions */
    477     for (i = 0; i < SMP_NUM_ACTIONS; i++)
    478     {
    479         if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
    480         {
    481             (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
    482         }
    483         else
    484         {
    485             break;
    486         }
    487     }
    488     SMP_TRACE_DEBUG1( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
    489 }
    490 
    491 
    492 /*******************************************************************************
    493 ** Function     smp_get_state_name
    494 ** Returns      The smp state name.
    495 *******************************************************************************/
    496 const char * smp_get_state_name(tSMP_STATE state)
    497 {
    498     const char * p_str = smp_state_name[SMP_ST_MAX];
    499 
    500     if (state < SMP_ST_MAX)
    501     {
    502         p_str = smp_state_name[state];
    503     }
    504     return p_str;
    505 }
    506 /*******************************************************************************
    507 ** Function     smp_get_event_name
    508 ** Returns      The smp event name.
    509 *******************************************************************************/
    510 const char * smp_get_event_name(tSMP_EVENT event)
    511 {
    512     const char * p_str = smp_event_name[SMP_MAX_EVT - 1];
    513 
    514     if (event < SMP_MAX_EVT)
    515     {
    516         p_str = smp_event_name[event- 1];
    517     }
    518     return p_str;
    519 }
    520 #endif
    521 
    522