From 15f22304d24c6f71475ad558b6ea23ee0db432b5 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 30 Apr 2018 11:34:35 +0200 Subject: [PATCH] att_db: add lookup of 128 bit UUIDs --- src/ble/att_db.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ble/att_db.h | 10 ++++++ 2 files changed, 90 insertions(+) diff --git a/src/ble/att_db.c b/src/ble/att_db.c index 101e6c08b..eed1e985b 100644 --- a/src/ble/att_db.c +++ b/src/ble/att_db.c @@ -1247,6 +1247,86 @@ uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uui return 0; } +// returns 1 if service found. only primary service. +int gatt_server_get_get_handle_range_for_service_with_uuid128(const uint8_t * uuid128, uint16_t * start_handle, uint16_t * end_handle){ + uint16_t in_group = 0; + uint16_t prev_handle = 0; + + uint8_t attribute_value[16]; + int attribute_len = sizeof(attribute_value); + reverse_128(uuid128, attribute_value); + + att_iterator_t it; + att_iterator_init(&it); + while (att_iterator_has_next(&it)){ + att_iterator_fetch_next(&it); + int new_service_started = att_iterator_match_uuid16(&it, GATT_PRIMARY_SERVICE_UUID) || att_iterator_match_uuid16(&it, GATT_SECONDARY_SERVICE_UUID); + + // close current tag, if within a group and a new service definition starts or we reach end of att db + if (in_group && + (it.handle == 0 || new_service_started)){ + *end_handle = prev_handle; + return 1; + } + + // keep track of previous handle + prev_handle = it.handle; + + // check if found + if (it.handle && new_service_started && attribute_len == it.value_len && memcmp(attribute_value, it.value, it.value_len) == 0){ + *start_handle = it.handle; + in_group = 1; + } + } + return 0; +} + +// returns 0 if not found +uint16_t gatt_server_get_value_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128){ + uint8_t attribute_value[16]; + reverse_128(uuid128, attribute_value); + att_iterator_t it; + att_iterator_init(&it); + while (att_iterator_has_next(&it)){ + att_iterator_fetch_next(&it); + if (it.handle && it.handle < start_handle) continue; + if (it.handle > end_handle) break; // (1) + if (it.handle == 0) break; + if (att_iterator_match_uuid(&it, attribute_value, 16)) return it.handle; + } + return 0; +} + +// returns 0 if not found +uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128){ + uint8_t attribute_value[16]; + reverse_128(uuid128, attribute_value); + att_iterator_t it; + att_iterator_init(&it); + int characteristic_found = 0; + while (att_iterator_has_next(&it)){ + att_iterator_fetch_next(&it); + if (it.handle && it.handle < start_handle) continue; + if (it.handle > end_handle) break; // (1) + if (it.handle == 0) break; + if (att_iterator_match_uuid(&it, attribute_value, 16)){ + characteristic_found = 1; + continue; + } + if (att_iterator_match_uuid16(&it, GATT_PRIMARY_SERVICE_UUID) + || att_iterator_match_uuid16(&it, GATT_SECONDARY_SERVICE_UUID) + || att_iterator_match_uuid16(&it, GATT_CHARACTERISTICS_UUID)){ + if (characteristic_found) break; + continue; + } + if (att_iterator_match_uuid16(&it, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION)){ + return it.handle; + } + } + return 0; +} + + // 1-item cache to optimize query during write_callback static void att_persistent_ccc_cache(att_iterator_t * it){ att_persistent_ccc_handle = it->handle; diff --git a/src/ble/att_db.h b/src/ble/att_db.h index 330d09daa..013626393 100644 --- a/src/ble/att_db.h +++ b/src/ble/att_db.h @@ -235,6 +235,16 @@ uint16_t gatt_server_get_value_handle_for_characteristic_with_uuid16(uint16_t st // returns 0 if not found uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t uuid16); + +// returns 1 if service found. only primary service. +int gatt_server_get_get_handle_range_for_service_with_uuid128(const uint8_t * uuid128, uint16_t * start_handle, uint16_t * end_handle); + +// returns 0 if not found +uint16_t gatt_server_get_value_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128); + +// returns 0 if not found +uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128); + // non-user functionality for att_server /*