From ef4913459d23d4702e9286eada286781ec448be6 Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Wed, 28 Jul 2021 13:23:53 +0900 Subject: [PATCH] Fix gatt service uuid duplicated registration issue Change-Id: I33aa85aa436badf16d82226fcd69d7e65f85ce9d Signed-off-by: Wootak Jung --- bt-service/services/gatt/bt-service-gatt.c | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/bt-service/services/gatt/bt-service-gatt.c b/bt-service/services/gatt/bt-service-gatt.c index 9380e3e..bf93e24 100644 --- a/bt-service/services/gatt/bt-service-gatt.c +++ b/bt-service/services/gatt/bt-service-gatt.c @@ -205,6 +205,11 @@ typedef struct { static GSList *list_gatt_info = NULL; +typedef struct { + int service_handle; + char *service_uuid; +} bt_service_handle_uuid_info_t; + /* App Information structure */ typedef struct { int adv_handle; @@ -218,6 +223,7 @@ typedef struct { int scan_rsp_len; gboolean is_initialized; GSList *service_handles; + GSList *service_handle_uuids; /* List of bt_service_handle_uuid_info_t */ int client_id; /* GATT Client instance ID */ bluetooth_device_address_t address; /* Remote BLE Device Address */ gboolean is_watcher_enabled; @@ -680,6 +686,64 @@ void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, } } +static gboolean __bt_check_service_uuid_registered(const char *service_uuid) +{ + int k; + BT_DBG(""); + bt_service_app_info_t *info = NULL; + GSList *l; + bt_service_handle_uuid_info_t *uuid_info = NULL; + + for (k = 1; k < MAX_APPS_SUPPORTED; k++) { + info = &numapps[k]; + + for (l = info->service_handle_uuids; l != NULL; l = g_slist_next(l)) { + uuid_info = l->data; + if (!uuid_info) + continue; + if (!g_strcmp0(uuid_info->service_uuid, service_uuid)) { + BT_INFO("Same Service UUID is registered"); + return true; + } + } + } + + return false; +} + +static void __bt_remove_service_uuid(int service_handle) +{ + int k; + BT_DBG(""); + bt_service_app_info_t *info = NULL; + GSList *l; + bt_service_handle_uuid_info_t *uuid_info = NULL; + bool removed = false; + + for (k = 1; k < MAX_APPS_SUPPORTED; k++) { + info = &numapps[k]; + + for (l = info->service_handle_uuids; l != NULL;) { + uuid_info = l->data; + l = g_slist_next(l); + if (!uuid_info) + continue; + if (uuid_info->service_handle == service_handle) { + BT_INFO("Removed Service handle [%d] Service UUID [%s]", + uuid_info->service_handle, uuid_info->service_uuid); + info->service_handle_uuids = g_slist_remove(info->service_handle_uuids, uuid_info); + g_free(uuid_info->service_uuid); + g_free(uuid_info); + removed = true; + break; + } + } + + if (removed) + break; + } +} + static int __bt_unregister_gatt_client_instance(int client_if) { int ret = OAL_STATUS_SUCCESS; @@ -770,6 +834,8 @@ static void __bt_remove_all_service_handles(bt_service_app_info_t *app_info) continue; } else { app_info->service_handles = g_slist_remove(app_info->service_handles, handle); + /* Remove Service UUID from the list */ + __bt_remove_service_uuid(*handle); g_free(handle); handle = NULL; count = g_slist_length(app_info->service_handles); @@ -1364,11 +1430,17 @@ static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event) /* Add Service Handle */ if (svc_handle > 0) { + bt_service_handle_uuid_info_t *uuid_info; handle = g_malloc0(sizeof(int)); *handle = svc_handle; numapps[k].service_handles = g_slist_append(numapps[k].service_handles, handle); count = g_slist_length(numapps[k].service_handles); BT_INFO("Added Service handle [%d] to list..current count [%d]", svc_handle, count); + /* Add Service UUID to the list */ + uuid_info = g_malloc0(sizeof(bt_service_handle_uuid_info_t)); + uuid_info->service_handle = svc_handle; + uuid_info->service_uuid = g_strdup(uuid_str); + numapps[k].service_handle_uuids = g_slist_append(numapps[k].service_handle_uuids, uuid_info); } break; } @@ -2618,6 +2690,10 @@ int _bt_gatt_server_add_service(char *sender, int service_type, svc_data.is_prmry = service_type; svc_data.id.inst_id = instance_id; + /* Check Service UUID duplication */ + if (__bt_check_service_uuid_registered(svc_uuid)) + return BLUETOOTH_ERROR_INTERNAL; + BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id); _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid); @@ -2745,6 +2821,8 @@ int _bt_gatt_server_delete_service(char *sender, int service_handle, int instanc if (handle && *handle == service_handle) { BT_INFO("Remove Service handle [%d]", *handle); info->service_handles = g_slist_remove(info->service_handles, handle); + /* Remove Service UUID from the list */ + __bt_remove_service_uuid(*handle); g_free(handle); handle = NULL; } -- 2.7.4