Fix gatt service uuid duplicated registration issue 68/261868/2 accepted/tizen/unified/20210803.123909 submit/tizen/20210801.230254
authorWootak Jung <wootak.jung@samsung.com>
Wed, 28 Jul 2021 04:23:53 +0000 (13:23 +0900)
committerWootak Jung <wootak.jung@samsung.com>
Wed, 28 Jul 2021 06:01:36 +0000 (15:01 +0900)
Change-Id: I33aa85aa436badf16d82226fcd69d7e65f85ce9d
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
bt-service/services/gatt/bt-service-gatt.c

index 9380e3e..bf93e24 100644 (file)
@@ -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;
                                }