sm: extract helper functions from sm_run

This commit is contained in:
Matthias Ringwald 2020-04-08 19:17:50 +02:00
parent c80ea152d7
commit d7f1c72e38

View File

@ -44,6 +44,7 @@
#include "ble/core.h"
#include "ble/sm.h"
#include "bluetooth_company_id.h"
#include "btstack_bool.h"
#include "btstack_crypto.h"
#include "btstack_debug.h"
#include "btstack_event.h"
@ -1831,24 +1832,8 @@ static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_con
}
#endif
static void sm_run(void){
btstack_linked_list_iterator_t it;
// assert that stack has already bootet
if (hci_get_state() != HCI_STATE_WORKING) return;
// assert that we can send at least commands
if (!hci_can_send_command_packet_now()) return;
// pause until IR/ER are ready
if (sm_persistent_keys_random_active) return;
//
// non-connection related behaviour
//
// distributed key generation
// distributed key generation
static bool sm_run_dpkg(void){
switch (dkg_state){
case DKG_CALC_IRK:
// already busy?
@ -1858,7 +1843,7 @@ static void sm_run(void){
sm_d1_d_prime(1, 0, sm_aes128_plaintext); // plaintext = d1 prime
sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_irk, sm_handle_encryption_result_dkg_irk, NULL);
return;
return true;
}
break;
case DKG_CALC_DHK:
@ -1869,38 +1854,46 @@ static void sm_run(void){
sm_d1_d_prime(3, 0, sm_aes128_plaintext); // plaintext = d1 prime
sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_dhk, sm_handle_encryption_result_dkg_dhk, NULL);
return;
return true;
}
break;
default:
break;
}
return false;
}
// random address updates
// random address updates
static bool sm_run_rau(void){
switch (rau_state){
case RAU_GET_RANDOM:
rau_state = RAU_W4_RANDOM;
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_address, 6, &sm_handle_random_result_rau, NULL);
return;
return true;
case RAU_GET_ENC:
// already busy?
if (sm_aes128_state == SM_AES128_IDLE) {
sm_ah_r_prime(sm_random_address, sm_aes128_plaintext);
sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_irk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_rau, NULL);
return;
return true;
}
break;
case RAU_SET_ADDRESS:
log_info("New random address: %s", bd_addr_to_str(sm_random_address));
rau_state = RAU_IDLE;
hci_send_cmd(&hci_le_set_random_address, sm_random_address);
return;
return true;
default:
break;
}
return false;
}
// CSRK Lookup
static bool sm_run_csrk(void){
btstack_linked_list_iterator_t it;
// CSRK Lookup
// -- if csrk lookup ready, find connection that require csrk lookup
if (sm_address_resolution_idle()){
hci_connections_get_iterator(&it);
@ -1964,7 +1957,7 @@ static void sm_run(void){
sm_address_resolution_ah_calculation_active = 1;
sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_aes128_key, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_address_resolution, NULL);
return;
return true;
}
if (sm_address_resolution_test >= le_device_db_max_count()){
@ -1972,23 +1965,28 @@ static void sm_run(void){
sm_address_resolution_handle_event(ADDRESS_RESOLUTION_FAILED);
}
}
return false;
}
// SC OOB
static bool sm_run_oob(void){
#ifdef ENABLE_LE_SECURE_CONNECTIONS
switch (sm_sc_oob_state){
case SM_SC_OOB_W2_CALC_CONFIRM:
if (!sm_cmac_ready()) break;
sm_sc_oob_state = SM_SC_OOB_W4_CONFIRM;
f4_engine(NULL, ec_q, ec_q, sm_sc_oob_random, 0);
return;
return true;
default:
break;
}
#endif
return false;
}
// assert that we can send at least commands - cmd might have been sent by crypto engine
if (!hci_can_send_command_packet_now()) return;
// handle basic actions that don't requires the full context
// handle basic actions that don't requires the full context
static bool sm_run_basic(void){
btstack_linked_list_iterator_t it;
hci_connections_get_iterator(&it);
while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){
hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
@ -1998,7 +1996,7 @@ static void sm_run(void){
case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY:
sm_connection->sm_engine_state = SM_RESPONDER_IDLE;
hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle);
return;
return true;
#ifdef ENABLE_LE_SECURE_CONNECTIONS
case SM_SC_RECEIVED_LTK_REQUEST:
@ -2007,7 +2005,7 @@ static void sm_run(void){
log_info("LTK Request: ediv & random are empty, but no stored LTK (IRK Lookup Failed)");
sm_connection->sm_engine_state = SM_RESPONDER_IDLE;
hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle);
return;
return true;
default:
break;
}
@ -2017,14 +2015,12 @@ static void sm_run(void){
break;
}
}
return false;
}
//
// active connection handling
// -- use loop to handle next connection if lock on setup context is released
while (true) {
static void sm_run_activate_connection(void){
// Find connections that requires setup context and make active if no other is locked
btstack_linked_list_iterator_t it;
hci_connections_get_iterator(&it);
while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){
hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
@ -2146,13 +2142,58 @@ static void sm_run(void){
log_info("sm: connection 0x%04x locked setup context as %s, state %u", sm_active_connection_handle, sm_connection->sm_role ? "responder" : "initiator", sm_connection->sm_engine_state);
}
}
}
static void sm_run(void){
// assert that stack has already bootet
if (hci_get_state() != HCI_STATE_WORKING) return;
// assert that we can send at least commands
if (!hci_can_send_command_packet_now()) return;
// pause until IR/ER are ready
if (sm_persistent_keys_random_active) return;
bool done;
//
// non-connection related behaviour
//
done = sm_run_dpkg();
if (done) return;
done = sm_run_rau();
if (done) return;
done = sm_run_csrk();
if (done) return;
done = sm_run_oob();
if (done) return;
// assert that we can send at least commands - cmd might have been sent by crypto engine
if (!hci_can_send_command_packet_now()) return;
// handle basic actions that don't requires the full context
done = sm_run_basic();
if (done) return;
//
// active connection handling
// -- use loop to handle next connection if lock on setup context is released
while (true) {
sm_run_activate_connection();
if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return;
//
// active connection handling
//
if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return;
sm_connection_t * connection = sm_get_connection_for_handle(sm_active_connection_handle);
if (!connection) {
log_info("no connection for handle 0x%04x", sm_active_connection_handle);