adapter: Implement ExperimentalFeatures property
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 17 Aug 2021 00:54:03 +0000 (17:54 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:36 +0000 (19:08 +0530)
This implements ExperimentalFeatures property which indicates the list
of UUIDs that represents the experimental features currently enabled.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/adapter.c

index af32848..779f638 100644 (file)
@@ -116,6 +116,30 @@ static const struct mgmt_blocked_key_info blocked_keys[] = {
                 0x22, 0x8e, 0x07, 0x56, 0xb4, 0xe8, 0x5f, 0x01}},
 };
 
+/* d4992530-b9ec-469f-ab01-6c481c47da1c */
+static const uint8_t debug_uuid[16] = {
+       0x1c, 0xda, 0x47, 0x1c, 0x48, 0x6c, 0x01, 0xab,
+       0x9f, 0x46, 0xec, 0xb9, 0x30, 0x25, 0x99, 0xd4,
+};
+
+/* 671b10b5-42c0-4696-9227-eb28d1b049d6 */
+static const uint8_t le_simult_central_peripheral_uuid[16] = {
+       0xd6, 0x49, 0xb0, 0xd1, 0x28, 0xeb, 0x27, 0x92,
+       0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67,
+};
+
+/* 330859bc-7506-492d-9370-9a6f0614037f */
+static const uint8_t quality_report_uuid[16] = {
+       0x7f, 0x03, 0x14, 0x06, 0x6f, 0x9a, 0x70, 0x93,
+       0x2d, 0x49, 0x06, 0x75, 0xbc, 0x59, 0x08, 0x33,
+};
+
+/* 15c0a148-c273-11ea-b3de-0242ac130004 */
+static const uint8_t rpa_resolution_uuid[16] = {
+       0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
+       0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15,
+};
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 #define ADV_DATA_MAX_LENGTH 31
 #define SCAN_RESPONSE_DATA_LENGTH_MAX 31
@@ -377,8 +401,7 @@ struct btd_adapter {
 #endif
        bool is_default;                /* true if adapter is default one */
 
-       bool le_simult_roles_supported;
-       bool quality_report_supported;
+       struct queue *exps;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        bool le_2m_phy_supported;
        bool le_coded_phy_supported;
@@ -7548,7 +7571,8 @@ static gboolean property_get_roles(const GDBusPropertyTable *property,
                dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &str);
        }
 
-       if (adapter->le_simult_roles_supported) {
+       if (queue_find(adapter->exps, NULL,
+                               le_simult_central_peripheral_uuid)) {
                const char *str = "central-peripheral";
                dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &str);
        }
@@ -7558,6 +7582,48 @@ static gboolean property_get_roles(const GDBusPropertyTable *property,
        return TRUE;
 }
 
+static void property_append_experimental(void *data, void *user_data)
+{
+       uint8_t *feature = data;
+       DBusMessageIter *iter = user_data;
+       uint128_t value;
+       bt_uuid_t uuid;
+       char str[MAX_LEN_UUID_STR + 1];
+       char *ptr;
+
+       bswap_128(feature, &value);
+       bt_uuid128_create(&uuid, value);
+       bt_uuid_to_string(&uuid, str, sizeof(str));
+
+       ptr = str;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
+}
+
+static gboolean property_get_experimental(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct btd_adapter *adapter = user_data;
+       DBusMessageIter entry;
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+                                       DBUS_TYPE_STRING_AS_STRING, &entry);
+
+       queue_foreach(adapter->exps, property_append_experimental, &entry);
+
+       dbus_message_iter_close_container(iter, &entry);
+
+       return TRUE;
+}
+
+static gboolean property_experimental_exits(const GDBusPropertyTable *property,
+                                                               void *data)
+{
+       struct btd_adapter *adapter = data;
+
+       return !queue_isempty(adapter->exps);
+}
+
 static DBusMessage *remove_device(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
 {
@@ -8339,6 +8405,8 @@ static const GDBusPropertyTable adapter_properties[] = {
        { "Modalias", "s", property_get_modalias, NULL,
                                        property_exists_modalias },
        { "Roles", "as", property_get_roles },
+       { "ExperimentalFeatures", "as", property_get_experimental, NULL,
+                                       property_experimental_exits },
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        { "Connectable", "b", property_get_connectable,
                                        property_set_connectable },
@@ -10467,6 +10535,7 @@ static void adapter_free(gpointer user_data)
 
        g_queue_foreach(adapter->auths, free_service_auth, NULL);
        g_queue_free(adapter->auths);
+       queue_destroy(adapter->exps, NULL);
 
        /*
         * Unregister all handlers for this specific index since
@@ -11523,6 +11592,7 @@ static struct btd_adapter *btd_adapter_new(uint16_t index)
        DBG("Discoverable timeout: %u seconds", adapter->discoverable_timeout);
        DBG("Pairable timeout: %u seconds", adapter->pairable_timeout);
        adapter->auths = g_queue_new();
+       adapter->exps = queue_new();
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
@@ -15663,38 +15733,22 @@ static bool set_blocked_keys(struct btd_adapter *adapter)
        .func = _func, \
 }
 
-/* d4992530-b9ec-469f-ab01-6c481c47da1c */
-static const uint8_t debug_uuid[16] = {
-       0x1c, 0xda, 0x47, 0x1c, 0x48, 0x6c, 0x01, 0xab,
-       0x9f, 0x46, 0xec, 0xb9, 0x30, 0x25, 0x99, 0xd4,
-};
-
-/* 671b10b5-42c0-4696-9227-eb28d1b049d6 */
-static const uint8_t le_simult_central_peripheral_uuid[16] = {
-       0xd6, 0x49, 0xb0, 0xd1, 0x28, 0xeb, 0x27, 0x92,
-       0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67,
-};
-
-/* 330859bc-7506-492d-9370-9a6f0614037f */
-static const uint8_t quality_report_uuid[16] = {
-       0x7f, 0x03, 0x14, 0x06, 0x6f, 0x9a, 0x70, 0x93,
-       0x2d, 0x49, 0x06, 0x75, 0xbc, 0x59, 0x08, 0x33,
-};
-
-/* 15c0a148-c273-11ea-b3de-0242ac130004 */
-static const uint8_t rpa_resolution_uuid[16] = {
-       0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
-       0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15,
-};
-
 static void set_exp_debug_complete(uint8_t status, uint16_t len,
                                        const void *param, void *user_data)
 {
-       if (status != 0)
+       struct btd_adapter *adapter = user_data;
+       uint8_t action = btd_opts.experimental ? 0x01 : 0x00;
+
+       if (status != 0) {
                error("Set Experimental Debug failed with status 0x%02x (%s)",
                                                status, mgmt_errstr(status));
-       else
-               DBG("Experimental Debug successfully set");
+               return;
+       }
+
+       DBG("Experimental Debug successfully set");
+
+       if (action)
+               queue_push_tail(adapter->exps, (void *)debug_uuid);
 }
 
 static void exp_debug_func(struct btd_adapter *adapter, uint32_t flags)
@@ -15703,8 +15757,11 @@ static void exp_debug_func(struct btd_adapter *adapter, uint32_t flags)
        uint8_t action = btd_opts.experimental ? 0x01 : 0x00;
 
        /* If already set don't attempt to set it again */
-       if (action == (flags & BIT(0)))
+       if (action == (flags & BIT(0))) {
+               if (action)
+                       queue_push_tail(adapter->exps, (void *)debug_uuid);
                return;
+       }
 
        memset(&cp, 0, sizeof(cp));
        memcpy(cp.uuid, debug_uuid, 16);
@@ -15721,25 +15778,33 @@ static void exp_debug_func(struct btd_adapter *adapter, uint32_t flags)
 static void le_simult_central_peripheral_func(struct btd_adapter *adapter,
                                                        uint32_t flags)
 {
-       adapter->le_simult_roles_supported = flags & 0x01;
+       if (flags & 0x01)
+               queue_push_tail(adapter->exps,
+                               (void *)le_simult_central_peripheral_uuid);
 }
 
 static void quality_report_func(struct btd_adapter *adapter, uint32_t flags)
 {
-       adapter->quality_report_supported = le32_to_cpu(flags) & 0x01;
-
-       btd_info(adapter->dev_id, "quality_report_supported %d",
-                       adapter->quality_report_supported);
+       if (flags & 0x01)
+               queue_push_tail(adapter->exps, (void *)quality_report_uuid);
 }
 
 static void set_rpa_resolution_complete(uint8_t status, uint16_t len,
                                        const void *param, void *user_data)
 {
-       if (status != 0)
+       struct btd_adapter *adapter = user_data;
+       uint8_t action = btd_opts.experimental ? 0x01 : 0x00;
+
+       if (status != 0) {
                error("Set RPA Resolution failed with status 0x%02x (%s)",
                                                status, mgmt_errstr(status));
-       else
-               DBG("RPA Resolution successfully set");
+               return;
+       }
+
+       DBG("RPA Resolution successfully set");
+
+       if (action)
+               queue_push_tail(adapter->exps, (void *)rpa_resolution_uuid);
 }
 
 static void rpa_resolution_func(struct btd_adapter *adapter, uint32_t flags)
@@ -15748,8 +15813,12 @@ static void rpa_resolution_func(struct btd_adapter *adapter, uint32_t flags)
        uint8_t action = btd_opts.experimental ? 0x01 : 0x00;
 
        /* If already set don't attempt to set it again */
-       if (action == (flags & BIT(0)))
+       if (action == (flags & BIT(0))) {
+               if (action)
+                       queue_push_tail(adapter->exps,
+                                               (void *)rpa_resolution_uuid);
                return;
+       }
 
        memset(&cp, 0, sizeof(cp));
        memcpy(cp.uuid, rpa_resolution_uuid, 16);