From 8ad4dfff8d17b112c397ad9b2983a9d1de48f100 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Sun, 20 Jun 2021 22:46:36 +0200 Subject: [PATCH] l2cap: track minimal security level --- src/gap.h | 7 +++++++ src/hci.c | 4 ++++ src/hci.h | 1 + src/l2cap.c | 21 ++++++++++++++++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/gap.h b/src/gap.h index 839de5f4e..281a359c0 100644 --- a/src/gap.h +++ b/src/gap.h @@ -278,6 +278,13 @@ void gap_set_secure_connections_only_mode(bool enable); */ bool gap_get_secure_connections_only_mode(void); +/** + * @brief Set minimal security level for registered services + * @param security_level + * @note Called by L2CAP based on registered services + */ +void gap_set_minimal_service_security_level(gap_security_level_t security_level); + /** * @brief Register filter for rejecting classic connections. Callback will return 1 accept connection, 0 on reject. */ diff --git a/src/hci.c b/src/hci.c index 23dabb334..11ef344dd 100644 --- a/src/hci.c +++ b/src/hci.c @@ -3509,6 +3509,10 @@ gap_security_level_t gap_get_security_level(void){ return hci_stack->gap_security_level; } +void gap_set_minimal_service_security_level(gap_security_level_t security_level){ + hci_stack->gap_minimal_service_security_level = security_level; +} + void gap_set_secure_connections_only_mode(bool enable){ hci_stack->gap_secure_connections_only_mode = enable; } diff --git a/src/hci.h b/src/hci.h index e38f06ce9..758c1ed06 100644 --- a/src/hci.h +++ b/src/hci.h @@ -857,6 +857,7 @@ typedef struct { uint8_t gap_required_encyrption_key_size; uint16_t link_supervision_timeout; gap_security_level_t gap_security_level; + gap_security_level_t gap_minimal_service_security_level; gap_security_mode_t gap_security_mode; uint32_t inquiry_lap; // GAP_IAC_GENERAL_INQUIRY or GAP_IAC_LIMITED_INQUIRY diff --git a/src/l2cap.c b/src/l2cap.c index a0fa3d6d5..3a4734e63 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -3832,6 +3832,20 @@ static inline l2cap_service_t * l2cap_get_service(uint16_t psm){ return l2cap_get_service_internal(&l2cap_services, psm); } +static void l2cap_update_minimal_security_level(void){ + // update minimal service security level + gap_security_level_t minimal_level = LEVEL_1; + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, &l2cap_services); + while (btstack_linked_list_iterator_has_next(&it)){ + l2cap_service_t * service = (l2cap_service_t *) btstack_linked_list_iterator_next(&it); + if (service->required_security_level > minimal_level){ + minimal_level = service->required_security_level; + }; + } + gap_set_minimal_service_security_level(minimal_level); +} + uint8_t l2cap_register_service(btstack_packet_handler_t service_packet_handler, uint16_t psm, uint16_t mtu, gap_security_level_t security_level){ log_info("L2CAP_REGISTER_SERVICE psm 0x%x mtu %u", psm, mtu); @@ -3858,12 +3872,15 @@ uint8_t l2cap_register_service(btstack_packet_handler_t service_packet_handler, // add to services list btstack_linked_list_add(&l2cap_services, (btstack_linked_item_t *) service); - + + l2cap_update_minimal_security_level(); + #ifndef ENABLE_EXPLICIT_CONNECTABLE_MODE_CONTROL // enable page scan gap_connectable_control(1); #endif + return ERROR_CODE_SUCCESS; } @@ -3876,6 +3893,8 @@ uint8_t l2cap_unregister_service(uint16_t psm){ btstack_linked_list_remove(&l2cap_services, (btstack_linked_item_t *) service); btstack_memory_l2cap_service_free(service); + l2cap_update_minimal_security_level(); + #ifndef ENABLE_EXPLICIT_CONNECTABLE_MODE_CONTROL // disable page scan when no services registered if (btstack_linked_list_empty(&l2cap_services)) {