gatt_client: extract gatt_client_handle_reencryption_complete and gatt_client_handle_disconnection_complete

This commit is contained in:
Matthias Ringwald 2021-12-11 17:57:48 +01:00
parent 291a91035e
commit 78c4542a56

View File

@ -1176,6 +1176,67 @@ static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint
emit_gatt_complete_event(gatt_client, att_error_code);
}
static void gatt_client_handle_reencryption_complete(const uint8_t * packet){
hci_con_handle_t con_handle = sm_event_reencryption_complete_get_handle(packet);
gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
if (gatt_client == NULL) return;
// update security level
gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
gatt_client->reencryption_result = sm_event_reencryption_complete_get_status(packet);
gatt_client->reencryption_active = false;
gatt_client->wait_for_authentication_complete = 0;
if (gatt_client->gatt_client_state == P_READY) return;
switch (sm_event_reencryption_complete_get_status(packet)){
case ERROR_CODE_SUCCESS:
log_info("re-encryption success, retry operation");
break;
case ERROR_CODE_AUTHENTICATION_FAILURE:
case ERROR_CODE_PIN_OR_KEY_MISSING:
#if defined(ENABLE_GATT_CLIENT_PAIRING) && !defined(ENABLE_LE_PROACTIVE_AUTHENTICATION)
if (gatt_client_required_security_level == LEVEL_0) {
// re-encryption failed for reactive authentication with pairing and we have a pending client request
// => try to resolve it by deleting bonding information if we started pairing before
// delete bonding information
int le_device_db_index = sm_le_device_index(gatt_client->con_handle);
btstack_assert(le_device_db_index >= 0);
log_info("reactive auth with pairing: delete bonding and start pairing");
#ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
hci_remove_le_device_db_entry_from_resolving_list((uint16_t) le_device_db_index);
#endif
le_device_db_remove(le_device_db_index);
// trigger pairing again
sm_request_pairing(gatt_client->con_handle);
break;
}
#endif
// report bonding information missing
gatt_client_handle_transaction_complete(gatt_client);
emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
break;
default:
// report bonding information missing
gatt_client_handle_transaction_complete(gatt_client);
emit_gatt_complete_event(gatt_client, gatt_client->pending_error_code);
break;
}
}
static void gatt_client_handle_disconnection_complete(const uint8_t * packet){
log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
hci_con_handle_t con_handle = little_endian_read_16(packet,3);
gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
if (gatt_client == NULL) return;
gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
gatt_client_timeout_stop(gatt_client);
btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
btstack_memory_gatt_client_free(gatt_client);
}
static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(channel); // ok: handling own l2cap events
UNUSED(size); // ok: there is no channel
@ -1186,15 +1247,7 @@ static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t chann
gatt_client_t * gatt_client;
switch (hci_event_packet_get_type(packet)) {
case HCI_EVENT_DISCONNECTION_COMPLETE:
log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
con_handle = little_endian_read_16(packet,3);
gatt_client = gatt_client_get_context_for_handle(con_handle);
if (gatt_client == NULL) break;
gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
gatt_client_timeout_stop(gatt_client);
btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
btstack_memory_gatt_client_free(gatt_client);
gatt_client_handle_disconnection_complete(packet);
break;
// Pairing complete (with/without bonding=storing of pairing information)
@ -1236,52 +1289,7 @@ static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t chann
// re-encryption complete
case SM_EVENT_REENCRYPTION_COMPLETE:
con_handle = sm_event_reencryption_complete_get_handle(packet);
gatt_client = gatt_client_get_context_for_handle(con_handle);
if (gatt_client == NULL) break;
// update security level
gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
gatt_client->reencryption_result = sm_event_reencryption_complete_get_status(packet);
gatt_client->reencryption_active = false;
gatt_client->wait_for_authentication_complete = 0;
if (gatt_client->gatt_client_state == P_READY) break;
switch (sm_event_reencryption_complete_get_status(packet)){
case ERROR_CODE_SUCCESS:
log_info("re-encryption success, retry operation");
break;
case ERROR_CODE_AUTHENTICATION_FAILURE:
case ERROR_CODE_PIN_OR_KEY_MISSING:
#if defined(ENABLE_GATT_CLIENT_PAIRING) && !defined(ENABLE_LE_PROACTIVE_AUTHENTICATION)
if (gatt_client_required_security_level == LEVEL_0) {
// re-encryption failed for reactive authentication with pairing and we have a pending client request
// => try to resolve it by deleting bonding information if we started pairing before
// delete bonding information
int le_device_db_index = sm_le_device_index(gatt_client->con_handle);
btstack_assert(le_device_db_index >= 0);
log_info("reactive auth with pairing: delete bonding and start pairing");
#ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
hci_remove_le_device_db_entry_from_resolving_list((uint16_t) le_device_db_index);
#endif
le_device_db_remove(le_device_db_index);
// trigger pairing again
sm_request_pairing(gatt_client->con_handle);
break;
}
#endif
// report bonding information missing
gatt_client_handle_transaction_complete(gatt_client);
emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
break;
default:
// report bonding information missing
gatt_client_handle_transaction_complete(gatt_client);
emit_gatt_complete_event(gatt_client, gatt_client->pending_error_code);
break;
}
gatt_client_handle_reencryption_complete(packet);
break;
default:
break;