Revert "Use FindDevice to get device object path" partially 09/157009/2
authorSeungyoun Ju <sy39.ju@samsung.com>
Fri, 20 Oct 2017 11:49:36 +0000 (20:49 +0900)
committerPyun DoHyun <dh79.pyun@samsung.com>
Tue, 24 Oct 2017 00:03:38 +0000 (00:03 +0000)
This partially reverts commit 30314c18fea269785f2c25d6f7dcd765008ad7a7

[Problem] Application couldn't make BREDR connection when remote device
 supports BREDR and LE both.
[Cause & Measure] Wrong device object path is used for BREDR connection.
 When a remote device supports BREDR/LE, bluez has two
 device object which has same bdaddr but different bdaddr_type. In this
 case, FindDevice call returns the first searched device's object path.
 To solve this issue, instead of FindDevice call,
 object path should be constructed from address.

Change-Id: Idf6190b749249de28ed5cc50ef9e44438c214339
Signed-off-by: Seungyoun Ju <sy39.ju@samsung.com>
bt-service/bt-service-common.c

index 0874e84..385910c 100644 (file)
@@ -660,30 +660,57 @@ int _bt_set_non_blocking_tty(int sk)
        return BLUETOOTH_ERROR_NONE;
 }
 
+static char *__bt_extract_device_path(GVariantIter *iter, char *address)
+{
+       char *object_path = NULL;
+       char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
+
+       /* Parse the signature: oa{sa{sv}}} */
+       while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
+                       NULL)) {
+               if (!object_path) {
+                       BT_ERR("Unable to get object path");
+                       return NULL;
+               }
+               _bt_convert_device_path_to_address(object_path, device_address);
+               if (g_strcmp0(address, device_address) == 0)
+                       return g_strdup(object_path);
+
+       }
+
+       BT_ERR("Unable to get object path");
+       return NULL;
+}
+
 char *_bt_get_device_object_path(char *address)
 {
        char *object_path = NULL;
+       GDBusConnection *conn;
+       GDBusProxy *manager_proxy;
        GVariant *result = NULL;
-       GDBusProxy *proxy;
-       GError *error = NULL;
+       GVariantIter *iter = NULL;
 
-       proxy = _bt_get_adapter_proxy();
-       retv_if(proxy == NULL, NULL);
+       conn = _bt_gdbus_get_system_gconn();
+       retv_if(conn == NULL, NULL);
+
+       manager_proxy = _bt_get_manager_proxy();
+       retv_if(manager_proxy == NULL, NULL);
 
-       result = g_dbus_proxy_call_sync(proxy, "FindDevice",
-                               g_variant_new("(s)", address),
+       result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+                               NULL,
                                G_DBUS_CALL_FLAGS_NONE,
-                               -1, NULL, &error);
-       if (result == NULL) {
-               if (error) {
-                       BT_ERR("FindDevice Fail: %s", error->message);
-                       g_clear_error(&error);
-               }
+                               -1,
+                               NULL,
+                               NULL);
+       if (!result) {
+               BT_ERR("Can't get managed objects");
                return NULL;
        }
 
-       g_variant_get(result, "(o)", &object_path);
-
+       /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
+       g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+       object_path = __bt_extract_device_path(iter, address);
+       g_variant_iter_free(iter);
        g_variant_unref(result);
        return object_path;
 }