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 26 const 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 35 const 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 65 const char *smp_get_br_event_name(tSMP_BR_EVENT event); 66 const 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 72 typedef const UINT8 (*tSMP_BR_SM_TBL)[SMP_BR_SM_NUM_COLS]; 73 74 enum 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 96 static 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 117 static 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 **************/ 126 static 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 157 static 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 164 static 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 170 static 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 177 static 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 185 static 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 216 static 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 222 static 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 230 static 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 238 static 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 253 typedef const UINT8 (*tSMP_BR_ENTRY_TBL)[SMP_BR_STATE_MAX]; 254 255 static 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 *******************************************************************************/ 267 void 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 *******************************************************************************/ 286 tSMP_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 *******************************************************************************/ 295 const 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 *******************************************************************************/ 308 const 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 *******************************************************************************/ 333 void 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