1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 #include "bt_target.h"
21 #if SMP_INCLUDED == TRUE
23 #include <cutils/log.h>
27 const char *const smp_state_name [] =
30 "SMP_STATE_WAIT_APP_RSP",
31 "SMP_STATE_SEC_REQ_PENDING",
32 "SMP_STATE_PAIR_REQ_RSP",
33 "SMP_STATE_WAIT_CONFIRM",
36 "SMP_STATE_PUBLIC_KEY_EXCH",
37 "SMP_STATE_SEC_CONN_PHS1_START",
38 "SMP_STATE_WAIT_COMMITMENT",
39 "SMP_STATE_WAIT_NONCE",
40 "SMP_STATE_SEC_CONN_PHS2_START",
41 "SMP_STATE_WAIT_DHK_CHECK",
42 "SMP_STATE_DHK_CHECK",
43 "SMP_STATE_ENCRYPTION_PENDING",
44 "SMP_STATE_BOND_PENDING",
45 "SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA",
49 const char *const smp_event_name [] =
62 "PAIR_PUBLIC_KEY_EVT",
63 "PAIR_DHKEY_CHECK_EVT",
64 "PAIR_KEYPRESS_NOTIFICATION_EVT",
65 "PAIR_COMMITMENT_EVT",
76 "DISCARD_SEC_REQ_EVT",
77 "PUBLIC_KEY_EXCHANGE_REQ_EVT",
78 "LOCAL_PUBLIC_KEY_CRTD_EVT",
79 "BOTH_PUBLIC_KEYS_RCVD_EVT",
80 "SEC_CONN_DHKEY_COMPLETE_EVT",
81 "HAVE_LOCAL_NONCE_EVT",
82 "SEC_CONN_PHASE1_CMPLT_EVT",
83 "SEC_CONN_CALC_NC_EVT",
84 "SEC_CONN_DISPLAY_NC_EVT",
86 "SEC_CONN_2_DHCK_CHECKS_PRESENT_EVT",
87 "SEC_CONN_KEY_READY_EVT",
88 "KEYPRESS_NOTIFICATION_EVT",
89 "SEC_CONN_OOB_DATA_EVT",
90 "CREATE_LOCAL_SEC_CONN_OOB_DATA_EVT",
94 const char *smp_get_event_name(tSMP_EVENT event);
95 const char *smp_get_state_name(tSMP_STATE state);
97 #define SMP_SM_IGNORE 0
98 #define SMP_NUM_ACTIONS 2
99 #define SMP_SME_NEXT_STATE 2
100 #define SMP_SM_NUM_COLS 3
102 typedef const UINT8(*tSMP_SM_TBL)[SMP_SM_NUM_COLS];
128 SMP_GENERATE_COMPARE,
129 SMP_GENERATE_CONFIRM,
134 SMP_DECIDE_ASSO_MODEL,
140 SMP_CREATE_PRIVATE_KEY,
141 SMP_USE_OOB_PRIVATE_KEY,
142 SMP_SEND_PAIR_PUBLIC_KEY,
143 SMP_PROCESS_PAIR_PUBLIC_KEY,
144 SMP_HAVE_BOTH_PUBLIC_KEYS,
145 SMP_START_SEC_CONN_PHASE1,
146 SMP_PROCESS_LOCAL_NONCE,
148 SMP_PROCESS_PAIRING_COMMITMENT,
149 SMP_PROCESS_PEER_NONCE,
150 SMP_CALCULATE_LOCAL_DHKEY_CHECK,
151 SMP_SEND_DHKEY_CHECK,
152 SMP_PROCESS_DHKEY_CHECK,
153 SMP_CALCULATE_PEER_DHKEY_CHECK,
154 SMP_MATCH_DHKEY_CHECKS,
155 SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER,
156 SMP_MOVE_TO_SEC_CONN_PHASE2,
157 SMP_PH2_DHKEY_CHECKS_ARE_PRESENT,
158 SMP_WAIT_FOR_BOTH_PUBLIC_KEYS,
159 SMP_START_PASSKEY_VERIFICATION,
160 SMP_SEND_KEYPRESS_NOTIFICATION,
161 SMP_PROCESS_KEYPRESS_NOTIFICATION,
162 SMP_PROCESS_SECURE_CONNECTION_OOB_DATA,
163 SMP_SET_LOCAL_OOB_KEYS,
164 SMP_SET_LOCAL_OOB_RAND_COMMITMENT,
170 static const tSMP_ACT smp_sm_action[] =
193 smp_process_io_response,
194 smp_generate_compare,
195 smp_generate_srand_mrand_confirm,
197 smp_key_distribution,
200 smp_decide_association_model,
206 smp_create_private_key,
207 smp_use_oob_private_key,
208 smp_send_pair_public_key,
209 smp_process_pairing_public_key,
210 smp_both_have_public_keys,
211 smp_start_secure_connection_phase1,
212 smp_process_local_nonce,
214 smp_process_pairing_commitment,
215 smp_process_peer_nonce,
216 smp_calculate_local_dhkey_check,
217 smp_send_dhkey_check,
218 smp_process_dhkey_check,
219 smp_calculate_peer_dhkey_check,
220 smp_match_dhkey_checks,
221 smp_calculate_numeric_comparison_display_number,
222 smp_move_to_secure_connections_phase2,
223 smp_phase_2_dhkey_checks_are_present,
224 smp_wait_for_both_public_keys,
225 smp_start_passkey_verification,
226 smp_send_keypress_notification,
227 smp_process_keypress_notification,
228 smp_process_secure_connection_oob_data,
229 smp_set_local_oob_keys,
230 smp_set_local_oob_random_commitment,
235 /************ SMP Master FSM State/Event Indirection Table **************/
236 static const UINT8 smp_master_entry_map[][SMP_STATE_MAX] =
238 /* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc
239 Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */
240 /* PAIR_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
241 /* PAIR_RSP */{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
242 /* CONFIRM */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
243 /* RAND */{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
244 /* PAIR_FAIL */{ 0, 0x81, 0, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0x81, 0 },
245 /* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
246 /* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 },
247 /* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 },
248 /* ID_ADDR */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 },
249 /* SIGN_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 },
250 /* SEC_REQ */{ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
251 /* PAIR_PUBLIC_KEY */{ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
252 /* PAIR_DHKEY_CHCK */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
253 /* PAIR_KEYPR_NOTIF */{ 0, 8, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0 },
254 /* PAIR_COMMITM */{ 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0 },
255 /* KEY_READY */{ 0, 3, 0, 3, 1, 0, 2, 0, 4, 0, 0, 0, 0, 0, 1, 6, 0 },
256 /* ENC_CMPL */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 },
257 /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
258 /* L2C_DISC */{ 3, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0 },
259 /* IO_RSP */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
260 /* SEC_GRANT */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
261 /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
262 /* AUTH_CMPL */{ 4, 0x82, 0, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0 },
263 /* ENC_REQ */{ 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 },
264 /* BOND_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
265 /* DISCARD_SEC_REQ */{ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
266 /* PUBL_KEY_EXCH_REQ */{ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
267 /* LOC_PUBL_KEY_CRTD */{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
268 /* BOTH_PUBL_KEYS_RCVD */{ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
269 /* SC_DHKEY_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
270 /* HAVE_LOC_NONCE */{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2 },
271 /* SC_PHASE1_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
272 /* SC_CALC_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
273 /* SC_DSPL_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 },
274 /* SC_NC_OK */{ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
275 /* SC_2_DHCK_CHKS_PRES */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
276 /* SC_KEY_READY */{ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
277 /* KEYPR_NOTIF */{ 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
278 /* SC_OOB_DATA */{ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
279 /* CR_LOC_SC_OOB_DATA */{ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
282 static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] =
284 /* Event Action Next State */
285 /* PAIR_FAIL */ {SMP_PROC_PAIR_FAIL, SMP_PAIRING_CMPL, SMP_STATE_IDLE},
286 /* AUTH_CMPL */ {SMP_SEND_PAIR_FAIL, SMP_PAIRING_CMPL, SMP_STATE_IDLE},
287 /* L2C_DISC */ {SMP_PAIR_TERMINATE, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
290 static const UINT8 smp_master_idle_table[][SMP_SM_NUM_COLS] =
292 /* Event Action Next State */
293 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
294 /* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
295 /* L2C_DISC */ {SMP_IDLE_TERMINATE, SMP_SM_NO_ACTION, SMP_STATE_IDLE},
296 /* AUTH_CMPL */ {SMP_PAIRING_CMPL, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
297 /* CR_LOC_SC_OOB_DATA */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}
301 static const UINT8 smp_master_wait_for_app_response_table[][SMP_SM_NUM_COLS] =
303 /* Event Action Next State */
304 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
305 /* IO_RSP */ {SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP},
308 /* KEY_READY */ {SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM},
310 /* start enc mode setup */
311 /* ENC_REQ */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_STATE_ENCRYPTION_PENDING},
312 /* DISCARD_SEC_REQ */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
313 /* user confirms NC 'OK', i.e. phase 1 is completed */
314 /* SC_NC_OK */,{ SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START},
315 /* user-provided passkey is rcvd */
316 /* SC_KEY_READY */ { SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
317 /* PAIR_KEYPR_NOTIF */ { SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
318 /* KEYPR_NOTIF */ { SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
319 /* SC_OOB_DATA */ { SMP_USE_OOB_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}
322 static const UINT8 smp_master_pair_request_response_table[][SMP_SM_NUM_COLS] =
324 /* Event Action Next State */
325 /* PAIR_RSP */ { SMP_PROC_PAIR_CMD, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
326 /* TK_REQ */ { SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
329 /* KEY_READY */{ SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM}
330 /* PUBL_KEY_EXCH_REQ */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH}
333 static const UINT8 smp_master_wait_for_confirm_table[][SMP_SM_NUM_COLS] =
335 /* Event Action Next State */
336 /* KEY_READY*/ {SMP_SEND_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}/* CONFIRM ready */
339 static const UINT8 smp_master_confirm_table[][SMP_SM_NUM_COLS] =
341 /* Event Action Next State */
342 /* CONFIRM */ { SMP_PROC_CONFIRM, SMP_SEND_RAND, SMP_STATE_RAND}
345 static const UINT8 smp_master_rand_table[][SMP_SM_NUM_COLS] =
347 /* Event Action Next State */
348 /* RAND */ { SMP_PROC_RAND, SMP_GENERATE_COMPARE, SMP_STATE_RAND},
349 /* KEY_READY*/ { SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_STATE_RAND}, /* Compare ready */
350 /* ENC_REQ */ { SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}
353 static const UINT8 smp_master_public_key_exchange_table[][SMP_SM_NUM_COLS] =
355 /* Event Action Next State */
356 /* LOC_PUBL_KEY_CRTD */{ SMP_SEND_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
357 /* PAIR_PUBLIC_KEY */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
358 /* BOTH_PUBL_KEYS_RCVD */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
361 static const UINT8 smp_master_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] =
363 /* Event Action Next State */
364 /* SC_DHKEY_CMPLT */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
365 /* HAVE_LOC_NONCE */{ SMP_PROCESS_LOCAL_NONCE, SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT},
366 /* TK_REQ */{ SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
367 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display,*/
368 /* It's time to start commitment calculation */
369 /* KEY_READY */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
370 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START},
371 /* PAIR_COMMITM */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
374 static const UINT8 smp_master_wait_commitment_table[][SMP_SM_NUM_COLS] =
376 /* Event Action Next State */
377 /* PAIR_COMMITM */{ SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_RAND, SMP_STATE_WAIT_NONCE},
378 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT},
381 static const UINT8 smp_master_wait_nonce_table[][SMP_SM_NUM_COLS] =
383 /* Event Action Next State */
384 /* peer nonce is received */
385 /* RAND */{SMP_PROC_RAND, SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START},
386 /* NC model, time to calculate number for NC */
387 /* SC_CALC_NC */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE},
388 /* NC model, time to display calculated number for NC to the user */
389 /* SC_DSPL_NC */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
392 static const UINT8 smp_master_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] =
394 /* Event Action Next State */
395 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_SEND_DHKEY_CHECK, SMP_STATE_WAIT_DHK_CHECK},
398 static const UINT8 smp_master_wait_dhk_check_table[][SMP_SM_NUM_COLS] =
400 /* Event Action Next State */
401 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK},
404 static const UINT8 smp_master_dhk_check_table[][SMP_SM_NUM_COLS] =
406 /* Event Action Next State */
407 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check actually received from peer */
408 /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
409 /* locally calculated peer dhkey check is ready -> calculate STK, go to sending */
410 /* HCI LE Start Encryption command */
411 /* ENC_REQ */{SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
414 static const UINT8 smp_master_enc_pending_table[][SMP_SM_NUM_COLS] =
416 /* Event Action Next State */
418 /* KEY_READY */ { SMP_START_ENC, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
419 /* ENCRYPTED */ { SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
420 /* BOND_REQ */ { SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
422 static const UINT8 smp_master_bond_pending_table[][SMP_SM_NUM_COLS] =
424 /* Event Action Next State */
425 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
426 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
427 /* SIGN_INFO*/ { SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
428 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
429 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
430 /* KEY_READY */{SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} /* LTK ready */
433 static const UINT8 smp_master_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] =
435 /* Event Action Next State */
436 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA},
437 /* HAVE_LOC_NONCE */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
441 /************ SMP Slave FSM State/Event Indirection Table **************/
442 static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] =
444 /* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc
445 Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */
446 /* PAIR_REQ */{ 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
447 /* PAIR_RSP */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
448 /* CONFIRM */{ 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
449 /* RAND */{ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
450 /* PAIR_FAIL */{ 0, 0x81, 0x81, 0x81, 0x81,0x81, 0x81,0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0, 0 },
451 /* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 },
452 /* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 },
453 /* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 },
454 /* ID_ADDR */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 },
455 /* SIGN_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 },
456 /* SEC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
457 /* PAIR_PUBLIC_KEY */{ 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
458 /* PAIR_DHKEY_CHCK */{ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0 },
459 /* PAIR_KEYPR_NOTIF */{ 0, 9, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0 },
460 /* PAIR_COMMITM */{ 0, 8, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0 },
461 /* KEY_READY */{ 0, 3, 0, 3, 2, 2, 1, 0, 4, 0, 0, 0, 0, 0, 2, 1, 0 },
462 /* ENC_CMPL */{ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
463 /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
464 /* L2C_DISC */{ 0, 0x83, 0x83, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0 },
465 /* IO_RSP */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
466 /* SEC_GRANT */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
467 /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
468 /* AUTH_CMPL */{ 0, 0x82, 0x82, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0 },
469 /* ENC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
470 /* BOND_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 },
471 /* DISCARD_SEC_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
472 /* PUBL_KEY_EXCH_REQ */{ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
473 /* LOC_PUBL_KEY_CRTD */{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
474 /* BOTH_PUBL_KEYS_RCVD */{ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
475 /* SC_DHKEY_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
476 /* HAVE_LOC_NONCE */{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2 },
477 /* SC_PHASE1_CMPLT */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
478 /* SC_CALC_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
479 /* SC_DSPL_NC */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 },
480 /* SC_NC_OK */{ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
481 /* SC_2_DHCK_CHKS_PRES */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0 },
482 /* SC_KEY_READY */{ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
483 /* KEYPR_NOTIF */{ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
484 /* SC_OOB_DATA */{ 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
485 /* CR_LOC_SC_OOB_DATA */{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
488 static const UINT8 smp_slave_idle_table[][SMP_SM_NUM_COLS] =
490 /* Event Action Next State */
491 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
492 /* PAIR_REQ */ {SMP_PROC_PAIR_CMD, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP}
493 /* CR_LOC_SC_OOB_DATA */ ,{SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA}
496 static const UINT8 smp_slave_wait_for_app_response_table [][SMP_SM_NUM_COLS] =
498 /* Event Action Next State */
499 /* IO_RSP */ {SMP_PROC_IO_RSP, SMP_FAST_CONN_PARAM, SMP_STATE_PAIR_REQ_RSP},
500 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
503 /* KEY_READY */ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
504 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}
505 /* DHKey Check from master is received before phase 1 is completed - race */
506 /* PAIR_DHKEY_CHCK */,{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
507 /* user confirms NC 'OK', i.e. phase 1 is completed */
508 /* SC_NC_OK */ {SMP_MOVE_TO_SEC_CONN_PHASE2, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START},
509 /* user-provided passkey is rcvd */
510 /* SC_KEY_READY */ {SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
511 /* PAIR_COMMITM */ {SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
512 /* PAIR_KEYPR_NOTIF */ {SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_APP_RSP},
513 /* KEYPR_NOTIF */ {SMP_SEND_KEYPRESS_NOTIFICATION, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
514 /* SC_OOB_DATA */ {SMP_SEND_PAIR_RSP, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
517 static const UINT8 smp_slave_sec_request_table[][SMP_SM_NUM_COLS] =
519 /* Event Action Next State */
520 /* PAIR_REQ */{SMP_PROC_PAIR_CMD, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
521 /* ENCRYPTED*/{SMP_ENC_CMPL, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
524 static const UINT8 smp_slave_pair_request_response_table[][SMP_SM_NUM_COLS] =
526 /* Event Action Next State */
527 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM},
528 /* TK_REQ */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
530 /* TK/Confirm ready */
531 /* KEY_READY */{SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP}
532 /* PUBL_KEY_EXCH_REQ */,{ SMP_CREATE_PRIVATE_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
533 /* PAIR_PUBLIC_KEY */ { SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PAIR_REQ_RSP},
536 static const UINT8 smp_slave_wait_confirm_table[][SMP_SM_NUM_COLS] =
538 /* Event Action Next State */
539 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SEND_CONFIRM, SMP_STATE_CONFIRM},
540 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_WAIT_CONFIRM}
543 static const UINT8 smp_slave_confirm_table[][SMP_SM_NUM_COLS] =
545 /* Event Action Next State */
546 /* RAND */ {SMP_PROC_RAND, SMP_GENERATE_COMPARE, SMP_STATE_RAND},
548 /* TK/Confirm ready */
549 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_STATE_CONFIRM}
552 static const UINT8 smp_slave_rand_table[][SMP_SM_NUM_COLS] =
554 /* Event Action Next State */
555 /* KEY_READY */ {SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_STATE_RAND}, /* compare match */
556 /* RAND */ {SMP_SEND_RAND, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}
559 static const UINT8 smp_slave_public_key_exch_table[][SMP_SM_NUM_COLS] =
561 /* Event Action Next State */
562 /* LOC_PUBL_KEY_CRTD */{ SMP_WAIT_FOR_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
563 /* PAIR_PUBLIC_KEY */{ SMP_PROCESS_PAIR_PUBLIC_KEY, SMP_SM_NO_ACTION, SMP_STATE_PUBLIC_KEY_EXCH},
564 /* BOTH_PUBL_KEYS_RCVD */{ SMP_HAVE_BOTH_PUBLIC_KEYS, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
567 static const UINT8 smp_slave_sec_conn_phs1_start_table[][SMP_SM_NUM_COLS] =
569 /* Event Action Next State */
570 /* SC_DHKEY_CMPLT */{ SMP_START_SEC_CONN_PHASE1, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
571 /* HAVE_LOC_NONCE */{ SMP_PROCESS_LOCAL_NONCE,SMP_SM_NO_ACTION, SMP_STATE_WAIT_COMMITMENT},
572 /* TK_REQ */{ SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
573 /* SMP_MODEL_SEC_CONN_PASSKEY_DISP model, passkey is sent up to display, it's time to start */
574 /* commitment calculation */
575 /* KEY_READY */{ SMP_START_PASSKEY_VERIFICATION, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
576 /* PAIR_KEYPR_NOTIF */{ SMP_PROCESS_KEYPRESS_NOTIFICATION,SMP_SEND_APP_CBACK, SMP_STATE_SEC_CONN_PHS1_START},
577 /*COMMIT*/{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS1_START},
580 static const UINT8 smp_slave_wait_commitment_table[][SMP_SM_NUM_COLS] =
582 /* Event Action Next State */
583 /* PAIR_COMMITM */{SMP_PROCESS_PAIRING_COMMITMENT, SMP_SEND_COMMITMENT, SMP_STATE_WAIT_NONCE},
584 /* PAIR_KEYPR_NOTIF */{SMP_PROCESS_KEYPRESS_NOTIFICATION, SMP_SEND_APP_CBACK, SMP_STATE_WAIT_COMMITMENT},
587 static const UINT8 smp_slave_wait_nonce_table[][SMP_SM_NUM_COLS] =
589 /* Event Action Next State */
590 /* peer nonce is received */
591 /* RAND */{SMP_PROC_RAND, SMP_PROCESS_PEER_NONCE, SMP_STATE_SEC_CONN_PHS2_START},
592 /* NC model, time to calculate number for NC */
593 /* SC_CALC_NC */{SMP_CALCULATE_NUMERIC_COMPARISON_DISPLAY_NUMBER, SMP_SM_NO_ACTION, SMP_STATE_WAIT_NONCE},
594 /* NC model, time to display calculated number for NC to the user */
595 /* SC_DSPL_NC */{SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_STATE_WAIT_APP_RSP},
598 static const UINT8 smp_slave_sec_conn_phs2_start_table[][SMP_SM_NUM_COLS] =
600 /* Event Action Next State */
601 /* SC_PHASE1_CMPLT */{SMP_CALCULATE_LOCAL_DHKEY_CHECK, SMP_PH2_DHKEY_CHECKS_ARE_PRESENT, SMP_STATE_WAIT_DHK_CHECK},
602 /* DHKey Check from master is received before slave DHKey calculation is completed - race */
603 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_SEC_CONN_PHS2_START},
606 static const UINT8 smp_slave_wait_dhk_check_table[][SMP_SM_NUM_COLS] =
608 /* Event Action Next State */
609 /* PAIR_DHKEY_CHCK */{SMP_PROCESS_DHKEY_CHECK, SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_STATE_DHK_CHECK},
610 /* DHKey Check from master was received before slave came to this state */
611 /* SC_2_DHCK_CHKS_PRES */{SMP_CALCULATE_PEER_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
614 static const UINT8 smp_slave_dhk_check_table[][SMP_SM_NUM_COLS] =
616 /* Event Action Next State */
618 /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check */
619 /* actually received from peer */
620 /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK},
622 /* dhkey checks match -> send local dhkey check to master, go to wait for HCI LE */
623 /* Long Term Key Request Event */
624 /* PAIR_DHKEY_CHCK */{SMP_SEND_DHKEY_CHECK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
627 static const UINT8 smp_slave_enc_pending_table[][SMP_SM_NUM_COLS] =
629 /* Event Action Next State */
630 /* ENC_REQ */ {SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
633 /* KEY_READY */ {SMP_SEND_LTK_REPLY, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
634 /* ENCRYPTED */ {SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING},
635 /* BOND_REQ */ {SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
637 static const UINT8 smp_slave_bond_pending_table[][SMP_SM_NUM_COLS] =
639 /* Event Action Next State */
642 /* KEY_READY */{ SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
645 /* SIGN_INFO */{ SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
646 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
647 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
648 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING},
649 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}
653 static const UINT8 smp_slave_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] =
655 /* Event Action Next State */
656 /* LOC_PUBL_KEY_CRTD */ {SMP_SET_LOCAL_OOB_KEYS, SMP_SM_NO_ACTION, SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA},
657 /* HAVE_LOC_NONCE */ {SMP_SET_LOCAL_OOB_RAND_COMMITMENT, SMP_SM_NO_ACTION, SMP_STATE_IDLE}
660 static const tSMP_SM_TBL smp_state_table[][2] =
663 {smp_master_idle_table, smp_slave_idle_table},
665 /* SMP_STATE_WAIT_APP_RSP */
666 {smp_master_wait_for_app_response_table, smp_slave_wait_for_app_response_table},
668 /* SMP_STATE_SEC_REQ_PENDING */
669 {NULL, smp_slave_sec_request_table},
671 /* SMP_STATE_PAIR_REQ_RSP */
672 {smp_master_pair_request_response_table, smp_slave_pair_request_response_table},
674 /* SMP_STATE_WAIT_CONFIRM */
675 {smp_master_wait_for_confirm_table, smp_slave_wait_confirm_table},
677 /* SMP_STATE_CONFIRM */
678 {smp_master_confirm_table, smp_slave_confirm_table},
681 {smp_master_rand_table, smp_slave_rand_table},
683 /* SMP_STATE_PUBLIC_KEY_EXCH */
684 {smp_master_public_key_exchange_table,smp_slave_public_key_exch_table},
686 /* SMP_STATE_SEC_CONN_PHS1_START */
687 {smp_master_sec_conn_phs1_start_table, smp_slave_sec_conn_phs1_start_table},
689 /* SMP_STATE_WAIT_COMMITMENT */
690 {smp_master_wait_commitment_table, smp_slave_wait_commitment_table},
692 /* SMP_STATE_WAIT_NONCE */
693 {smp_master_wait_nonce_table, smp_slave_wait_nonce_table},
695 /* SMP_STATE_SEC_CONN_PHS2_START */
696 {smp_master_sec_conn_phs2_start_table, smp_slave_sec_conn_phs2_start_table},
698 /* SMP_STATE_WAIT_DHK_CHECK */
699 {smp_master_wait_dhk_check_table, smp_slave_wait_dhk_check_table},
701 /* SMP_STATE_DHK_CHECK */
702 {smp_master_dhk_check_table, smp_slave_dhk_check_table},
704 /* SMP_STATE_ENCRYPTION_PENDING */
705 {smp_master_enc_pending_table, smp_slave_enc_pending_table},
707 /* SMP_STATE_BOND_PENDING */
708 {smp_master_bond_pending_table, smp_slave_bond_pending_table},
710 /* SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA */
711 {smp_master_create_local_sec_conn_oob_data, smp_slave_create_local_sec_conn_oob_data}
714 typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_STATE_MAX];
715 static const tSMP_ENTRY_TBL smp_entry_table[] =
717 smp_master_entry_map,
721 #if SMP_DYNAMIC_MEMORY == FALSE
724 #define SMP_ALL_TBL_MASK 0x80
726 /*******************************************************************************
727 ** Function smp_set_state
729 *******************************************************************************/
730 void smp_set_state(tSMP_STATE state)
732 if (state < SMP_STATE_MAX)
734 SMP_TRACE_DEBUG( "State change: %s(%d) ==> %s(%d)",
735 smp_get_state_name(smp_cb.state), smp_cb.state,
736 smp_get_state_name(state), state );
737 smp_cb.state = state;
741 SMP_TRACE_DEBUG("smp_set_state invalid state =%d", state );
745 /*******************************************************************************
746 ** Function smp_get_state
747 ** Returns The smp state
748 *******************************************************************************/
749 tSMP_STATE smp_get_state(void)
754 /*******************************************************************************
756 ** Function smp_sm_event
758 ** Description Handle events to the state machine. It looks up the entry
759 ** in the smp_entry_table array.
760 ** If it is a valid entry, it gets the state table.Set the next state,
761 ** if not NULL state.Execute the action function according to the
762 ** state table. If the state returned by action function is not NULL
763 ** state, adjust the new state to the returned state.If (api_evt != MAX),
764 ** call callback function.
768 *******************************************************************************/
769 void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
771 UINT8 curr_state = p_cb->state;
772 tSMP_SM_TBL state_table;
773 UINT8 action, entry, i;
775 if (p_cb->role >= 2) {
776 SMP_TRACE_DEBUG("Invalid role: %d", p_cb->role);
777 android_errorWriteLog(0x534e4554, "74121126");
781 tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role];
783 SMP_TRACE_EVENT("main smp_sm_event");
784 if (curr_state >= SMP_STATE_MAX)
786 SMP_TRACE_DEBUG( "Invalid state: %d", curr_state) ;
790 SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
791 (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
792 p_cb->state, smp_get_event_name(event), event) ;
794 /* look up the state table for the current state */
795 /* lookup entry /w event & curr_state */
796 /* If entry is ignore, return.
797 * Otherwise, get state table (according to curr_state or all_state) */
798 if ((event <= SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
800 if (entry & SMP_ALL_TBL_MASK)
802 entry &= ~SMP_ALL_TBL_MASK;
803 state_table = smp_all_table;
806 state_table = smp_state_table[curr_state][p_cb->role];
810 SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
811 smp_get_event_name(event), event, smp_get_state_name(curr_state),
816 /* Get possible next state from state table. */
818 smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);
820 /* If action is not ignore, clear param, exec action and get next state.
821 * The action function may set the Param for cback.
822 * Depending on param, call cback or free buffer. */
824 /* execute action functions */
825 for (i = 0; i < SMP_NUM_ACTIONS; i++)
827 if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
829 (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
836 SMP_TRACE_DEBUG( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
839 /*******************************************************************************
840 ** Function smp_get_state_name
841 ** Returns The smp state name.
842 *******************************************************************************/
843 const char * smp_get_state_name(tSMP_STATE state)
845 const char *p_str = smp_state_name[SMP_STATE_MAX];
847 if (state < SMP_STATE_MAX)
849 p_str = smp_state_name[state];
854 /*******************************************************************************
855 ** Function smp_get_event_name
856 ** Returns The smp event name.
857 *******************************************************************************/
858 const char * smp_get_event_name(tSMP_EVENT event)
860 const char *p_str = smp_event_name[SMP_MAX_EVT];
862 if (event <= SMP_MAX_EVT)
864 p_str = smp_event_name[event- 1];