core: add adapter and device allowed_uuid functions
authorYun-Hao Chung <howardchung@chromium.org>
Tue, 3 Aug 2021 11:43:07 +0000 (19:43 +0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:36 +0000 (19:08 +0530)
This implements functions in src/adapter.c and src/device.c for
plugins setting a list of allowed services.

Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/adapter.c
src/adapter.h
src/device.c
src/device.h

index 3c8beff..b44527b 100644 (file)
@@ -328,6 +328,7 @@ struct btd_adapter {
        struct btd_adv_monitor_manager *adv_monitor_manager;
 
        struct btd_battery_provider_manager *battery_provider_manager;
+       GHashTable *allowed_uuid_set;   /* Set of allowed service UUIDs */
 
        gboolean initialized;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
@@ -7793,6 +7794,92 @@ static DBusMessage *connect_device(DBusConnection *conn,
        return NULL;
 }
 
+static void update_device_allowed_services(void *data, void *user_data)
+{
+       struct btd_device *device = data;
+
+       btd_device_update_allowed_services(device);
+}
+
+static void add_uuid_to_uuid_set(void *data, void *user_data)
+{
+       bt_uuid_t *uuid = data;
+       GHashTable *uuid_set = user_data;
+
+       if (!uuid) {
+               error("Found NULL in UUID allowed list");
+               return;
+       }
+
+       g_hash_table_add(uuid_set, uuid);
+}
+
+static guint bt_uuid_hash(gconstpointer key)
+{
+       const bt_uuid_t *uuid = key;
+       bt_uuid_t uuid_128;
+       uint64_t *val;
+
+       if (!uuid)
+               return 0;
+
+       bt_uuid_to_uuid128(uuid, &uuid_128);
+       val = (uint64_t *)&uuid_128.value.u128;
+
+       return g_int64_hash(val) ^ g_int64_hash(val+1);
+}
+
+static gboolean bt_uuid_equal(gconstpointer v1, gconstpointer v2)
+{
+       const bt_uuid_t *uuid1 = v1;
+       const bt_uuid_t *uuid2 = v2;
+
+       if (!uuid1 || !uuid2)
+               return !uuid1 && !uuid2;
+
+       return bt_uuid_cmp(uuid1, uuid2) == 0;
+}
+
+bool btd_adapter_set_allowed_uuids(struct btd_adapter *adapter,
+                                                       struct queue *uuids)
+{
+       if (!adapter)
+               return false;
+
+       if (adapter->allowed_uuid_set)
+               g_hash_table_destroy(adapter->allowed_uuid_set);
+
+       adapter->allowed_uuid_set = g_hash_table_new(bt_uuid_hash,
+                                                               bt_uuid_equal);
+       if (!adapter->allowed_uuid_set) {
+               btd_error(adapter->dev_id,
+                                       "Failed to allocate allowed_uuid_set");
+               return false;
+       }
+
+       queue_foreach(uuids, add_uuid_to_uuid_set, adapter->allowed_uuid_set);
+       g_slist_foreach(adapter->devices, update_device_allowed_services, NULL);
+
+       return true;
+}
+
+bool btd_adapter_is_uuid_allowed(struct btd_adapter *adapter,
+                                                       const char *uuid_str)
+{
+       bt_uuid_t uuid;
+
+       if (!adapter || !adapter->allowed_uuid_set)
+               return true;
+
+       if (bt_string_to_uuid(&uuid, uuid_str)) {
+               btd_error(adapter->dev_id,
+                               "Failed to parse UUID string '%s'", uuid_str);
+               return false;
+       }
+
+       return !g_hash_table_size(adapter->allowed_uuid_set) ||
+               g_hash_table_contains(adapter->allowed_uuid_set, &uuid);
+}
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 static DBusMessage *adapter_unpair_device(DBusConnection *conn,
@@ -10409,6 +10496,7 @@ static void adapter_free(gpointer user_data)
        g_free(adapter->stored_alias);
        g_free(adapter->current_alias);
        free(adapter->modalias);
+       g_hash_table_destroy(adapter->allowed_uuid_set);
        g_free(adapter);
 }
 
index e9b4cfe..c3cbc22 100644 (file)
@@ -65,7 +65,7 @@ typedef enum {
 
 struct btd_adapter;
 struct btd_device;
-
+struct queue;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 typedef enum {
        BLUETOOTH_A2DP_SOURCE_ROLE = 0,
@@ -178,6 +178,8 @@ void adapter_service_remove(struct btd_adapter *adapter, uint32_t handle);
 
 struct agent *adapter_get_agent(struct btd_adapter *adapter);
 
+bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid);
+
 struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
 void btd_adapter_unref(struct btd_adapter *adapter);
 
@@ -342,6 +344,10 @@ enum kernel_features {
 
 bool btd_has_kernel_features(uint32_t feature);
 
+bool btd_adapter_set_allowed_uuids(struct btd_adapter *adapter,
+                                               struct queue *uuids);
+bool btd_adapter_is_uuid_allowed(struct btd_adapter *adapter,
+                                               const char *uuid_str);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 void adapter_send_event(const char *event);
 
index 929d913..ccaa732 100644 (file)
@@ -2479,6 +2479,56 @@ static int service_prio_cmp(gconstpointer a, gconstpointer b)
        return p2->priority - p1->priority;
 }
 
+bool btd_device_all_services_allowed(struct btd_device *dev)
+{
+       GSList *l;
+       struct btd_adapter *adapter = dev->adapter;
+       struct btd_service *service;
+       struct btd_profile *profile;
+
+       for (l = dev->services; l != NULL; l = g_slist_next(l)) {
+               service = l->data;
+               profile = btd_service_get_profile(service);
+
+               if (!profile || !profile->auto_connect)
+                       continue;
+
+               if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid))
+                       return false;
+       }
+
+       return true;
+}
+
+void btd_device_update_allowed_services(struct btd_device *dev)
+{
+       struct btd_adapter *adapter = dev->adapter;
+       struct btd_service *service;
+       struct btd_profile *profile;
+       GSList *l;
+       bool is_allowed;
+       char addr[18];
+
+       /* If service discovery is ongoing, let the service discovery complete
+        * callback call this function.
+        */
+       if (dev->browse) {
+               ba2str(&dev->bdaddr, addr);
+               DBG("service discovery of %s is ongoing. Skip updating allowed "
+                                                       "services", addr);
+               return;
+       }
+
+       for (l = dev->services; l != NULL; l = g_slist_next(l)) {
+               service = l->data;
+               profile = btd_service_get_profile(service);
+
+               is_allowed = btd_adapter_is_uuid_allowed(adapter,
+                                                       profile->remote_uuid);
+               btd_service_set_allowed(service, is_allowed);
+       }
+}
+
 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
 {
        struct btd_service *service;
@@ -2490,8 +2540,12 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
 
        if (uuid) {
                service = find_connectable_service(dev, uuid);
-               if (service)
+               if (!service)
+                       return dev->pending;
+
+               if (btd_service_is_allowed(service))
                        return g_slist_prepend(dev->pending, service);
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
                else if ((service == NULL) &&
                                        (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
@@ -2539,6 +2593,11 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
                if (!p->auto_connect)
                        continue;
 
+               if (!btd_service_is_allowed(service)) {
+                       info("service %s is blocked", p->remote_uuid);
+                       continue;
+               }
+
                if (g_slist_find(dev->pending, service))
                        continue;
 
@@ -3325,6 +3384,7 @@ static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
 
        browse_request_complete(req, browse_type, bdaddr_type, err);
 #endif
+       btd_device_update_allowed_services(dev);
        device_resolved_drivers(dev->adapter, dev);
 }
 
index 2379d92..8bc91d0 100644 (file)
@@ -255,5 +255,7 @@ uint32_t btd_device_get_current_flags(struct btd_device *dev);
 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
                              uint32_t current_flags);
 
+bool btd_device_all_services_allowed(struct btd_device *dev);
+void btd_device_update_allowed_services(struct btd_device *dev);
 void btd_device_init(void);
 void btd_device_cleanup(void);