+static char *__netconfig_get_preferred_ipv6_address(char *profile)
+{
+ GVariant *message = NULL, *variant = NULL, *next = NULL;
+ GVariantIter *iter = NULL, *sub_iter = NULL, *service = NULL;
+ gchar *obj_path;
+ gchar *key = NULL;
+ gchar *sub_key = NULL;
+ gchar *preferred_address6 = NULL;
+ gboolean found_profile = 0;
+
+ message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
+ "GetServices", NULL);
+ if (message == NULL) {
+ ERR("Failed to get service informations");
+ goto done;
+ }
+
+ g_variant_get(message, "(a(oa{sv}))", &service);
+ if (service == NULL) {
+ ERR("Failed to get services iter");
+ goto done;
+ }
+
+ while (g_variant_iter_loop(service, "(oa{sv})", &obj_path, &iter)) {
+ if (g_strcmp0(obj_path, profile) == 0) {
+ g_free(obj_path);
+ found_profile = 1;
+ break;
+ }
+ }
+
+ if (iter == NULL || found_profile == 0) {
+ ERR("Profile %s doesn't exist", profile);
+ goto done;
+ }
+
+ while (g_variant_iter_loop(iter, "{sv}", &key, &next)) {
+ const gchar *value = NULL;
+ if (g_strcmp0(key, "IPv6") == 0) {
+ g_variant_get(next, "a{sv}", &sub_iter);
+ if (sub_iter == NULL)
+ continue;
+ while (g_variant_iter_loop(sub_iter, "{sv}", &sub_key, &variant)) {
+ if (g_strcmp0(sub_key, "Address") == 0) {
+ value = g_variant_get_string(variant, NULL);
+ if (!preferred_address6)
+ preferred_address6 = g_strdup(value);
+ }
+ }
+ g_variant_iter_free(sub_iter);
+ }
+ }
+
+done:
+ if (message)
+ g_variant_unref(message);
+
+ if (iter)
+ g_variant_iter_free(iter);
+
+ if (service)
+ g_variant_iter_free(service);
+
+ return preferred_address6;
+}
+