mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-10 15:40:11 +00:00
sm: fixes stall in initiator role when responder does not send any keys
This commit is contained in:
parent
102b7a9c1b
commit
5243c6c843
137
ble/sm.c
137
ble/sm.c
@ -1715,6 +1715,72 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
}
|
||||
}
|
||||
|
||||
static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){
|
||||
int le_db_index = -1;
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){
|
||||
// lookup device based on IRK
|
||||
int i;
|
||||
for (i=0; i < le_device_db_count(); i++){
|
||||
sm_key_t irk;
|
||||
bd_addr_t address;
|
||||
int address_type;
|
||||
le_device_db_info(i, &address_type, address, irk);
|
||||
if (memcmp(irk, setup->sm_peer_irk, 16) == 0){
|
||||
log_info("sm: device found for IRK, updating");
|
||||
le_db_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if not found, add to db
|
||||
if (le_db_index < 0) {
|
||||
le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk);
|
||||
}
|
||||
}
|
||||
|
||||
// if no IRK available, lookup via public address if possible
|
||||
log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address));
|
||||
if (le_db_index < 0 && setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC){
|
||||
int i;
|
||||
for (i=0; i < le_device_db_count(); i++){
|
||||
bd_addr_t address;
|
||||
int address_type;
|
||||
le_device_db_info(i, &address_type, address, NULL);
|
||||
log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address));
|
||||
if (address_type == BD_ADDR_TYPE_LE_PUBLIC && memcmp(address, setup->sm_peer_address, 6) == 0){
|
||||
log_info("sm: device found for public address, updating");
|
||||
le_db_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if not found, add to db
|
||||
if (le_db_index < 0) {
|
||||
le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk);
|
||||
}
|
||||
}
|
||||
|
||||
if (le_db_index >= 0){
|
||||
le_device_db_local_counter_set(le_db_index, 0);
|
||||
|
||||
// store CSRK
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){
|
||||
log_info("sm: store remote CSRK");
|
||||
le_device_db_csrk_set(le_db_index, setup->sm_peer_csrk);
|
||||
le_device_db_remote_counter_set(le_db_index, 0);
|
||||
}
|
||||
|
||||
// store encryption information
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION
|
||||
&& setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION){
|
||||
log_info("sm: set encryption information (key size %u, authenticatd %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated);
|
||||
le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk,
|
||||
sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED);
|
||||
}
|
||||
}
|
||||
|
||||
// keep le_db_index
|
||||
sm_conn->sm_le_db_index = le_db_index;
|
||||
}
|
||||
|
||||
static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
||||
sm_connection_t * sm_conn;
|
||||
@ -1835,7 +1901,13 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
} else {
|
||||
// master
|
||||
sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS;
|
||||
if (sm_key_distribution_all_received(sm_conn)){
|
||||
// skip receiving keys as there are none
|
||||
sm_key_distribution_handle_all_received(sm_conn);
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -2131,69 +2203,8 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
||||
}
|
||||
// done with key distribution?
|
||||
if (sm_key_distribution_all_received(sm_conn)){
|
||||
int le_db_index = -1;
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){
|
||||
// lookup device based on IRK
|
||||
int i;
|
||||
for (i=0; i < le_device_db_count(); i++){
|
||||
sm_key_t irk;
|
||||
bd_addr_t address;
|
||||
int address_type;
|
||||
le_device_db_info(i, &address_type, address, irk);
|
||||
if (memcmp(irk, setup->sm_peer_irk, 16) == 0){
|
||||
log_info("sm: device found for IRK, updating");
|
||||
le_db_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if not found, add to db
|
||||
if (le_db_index < 0) {
|
||||
le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk);
|
||||
}
|
||||
}
|
||||
|
||||
// if no IRK available, lookup via public address if possible
|
||||
log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address));
|
||||
if (le_db_index < 0 && setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC){
|
||||
int i;
|
||||
for (i=0; i < le_device_db_count(); i++){
|
||||
bd_addr_t address;
|
||||
int address_type;
|
||||
le_device_db_info(i, &address_type, address, NULL);
|
||||
log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address));
|
||||
if (address_type == BD_ADDR_TYPE_LE_PUBLIC && memcmp(address, setup->sm_peer_address, 6) == 0){
|
||||
log_info("sm: device found for public address, updating");
|
||||
le_db_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if not found, add to db
|
||||
if (le_db_index < 0) {
|
||||
le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk);
|
||||
}
|
||||
}
|
||||
|
||||
if (le_db_index >= 0){
|
||||
le_device_db_local_counter_set(le_db_index, 0);
|
||||
|
||||
// store CSRK
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){
|
||||
log_info("sm: store remote CSRK");
|
||||
le_device_db_csrk_set(le_db_index, setup->sm_peer_csrk);
|
||||
le_device_db_remote_counter_set(le_db_index, 0);
|
||||
}
|
||||
|
||||
// store encryption information
|
||||
if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION
|
||||
&& setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION){
|
||||
log_info("sm: set encryption information (key size %u, authenticatd %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated);
|
||||
le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk,
|
||||
sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED);
|
||||
}
|
||||
}
|
||||
|
||||
// keep le_db_index
|
||||
sm_conn->sm_le_db_index = le_db_index;
|
||||
sm_key_distribution_handle_all_received(sm_conn);
|
||||
|
||||
if (sm_conn->sm_role){
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user