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
26const 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
48const 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
93const char *smp_get_event_name(tSMP_EVENT event);
94const 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
101typedef const UINT8(*tSMP_SM_TBL)[SMP_SM_NUM_COLS];
102
103enum
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
169static 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 **************/
235static 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
281static 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
289static 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
300static 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
321static 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
332static 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
338static 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
344static 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
352static 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
360static 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
373static 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
380static 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
391static 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
397static 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
403static 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
413static 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};
421static 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
432static 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 **************/
441static 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
487static 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
495static 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
516static 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
523static 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
535static 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
542static 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
551static 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
558static 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
566static 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
579static 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
586static 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
597static 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
605static 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
613static 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
626static 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};
636static 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
652static 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
659static 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
713typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_STATE_MAX];
714static 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
721tSMP_CB  smp_cb;
722#endif
723#define SMP_ALL_TBL_MASK        0x80
724
725/*******************************************************************************
726** Function     smp_set_state
727** Returns      None
728*******************************************************************************/
729void 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*******************************************************************************/
748tSMP_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*******************************************************************************/
768void 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*******************************************************************************/
835const 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*******************************************************************************/
850const 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