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