Ejemplo n.º 1
0
static GVariant *
gkd_secret_create_encode_result (GkdSecretPrompt *base)
{
    GkdSecretCreate *self = GKD_SECRET_CREATE (base);
    const gchar *path;

    path = self->result_path ? self->result_path : "/";
    return g_variant_new_variant (g_variant_new_object_path (path));
}
Ejemplo n.º 2
0
void bluez_unregister_watcher(GDBusConnection* conn, const gchar* service_path)
{
    GError* error = NULL;

    GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez",
                                                       service_path,
                                                       "org.bluez.Characteristic",
                                                       "UnregisterCharacteristicsWatcher");
    if(call_message == NULL)
    {
        printf("g_dbus_message_new_method_call failed\n");

        return;
    }

    gchar path[255];
    g_snprintf(path, 255, "/test/bluez/%d", getpid());

    GVariant* variant_addr = g_variant_new_object_path(path);
    GVariant* variant_body = g_variant_new_tuple(&variant_addr, 1);

    g_dbus_message_set_body(call_message, variant_body);

    GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn,
                                                                          call_message,
                                                                          G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                                                          -1,
                                                                          NULL,
                                                                          NULL,
                                                                          &error);
    if(reply_message == NULL)
    {
        printf("g_dbus_connection_send_message_with_reply_sync failed\n");

        return;
    }

    if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR)
    {
        printf("Error occured\n");

        g_dbus_message_to_gerror(reply_message, &error);
        g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message);

        g_error_free(error);

        return;
    }

    // cleanup
    g_object_unref(call_message);
    g_object_unref(reply_message);
}
Ejemplo n.º 3
0
GVariant *getTrackId() {
  GVariant *value = NULL;
  if (!mpris_data) {
    return NULL;
  }

  g_mutex_lock(&mutex);
  if (mpris_data->trackid) {
    value = g_variant_new_object_path(mpris_data->trackid);
  }
  g_mutex_unlock(&mutex);
  return value;
}
Ejemplo n.º 4
0
static void
fill_device_props (NMDevice *device,
                   GVariantBuilder *dev_builder,
                   GVariantBuilder *proxy_builder,
                   GVariantBuilder *ip4_builder,
                   GVariantBuilder *ip6_builder,
                   GVariant **dhcp4_props,
                   GVariant **dhcp6_props)
{
	NMProxyConfig *proxy_config;
	NMIP4Config *ip4_config;
	NMIP6Config *ip6_config;
	NMDhcp4Config *dhcp4_config;
	NMDhcp6Config *dhcp6_config;

	/* If the action is for a VPN, send the VPN's IP interface instead of the device's */
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_IP_INTERFACE,
	                       g_variant_new_string (nm_device_get_ip_iface (device)));
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_INTERFACE,
	                       g_variant_new_string (nm_device_get_iface (device)));
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_TYPE,
	                       g_variant_new_uint32 (nm_device_get_device_type (device)));
	g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_STATE,
	                       g_variant_new_uint32 (nm_device_get_state (device)));
	if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (device)))
		g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH,
		                       g_variant_new_object_path (nm_exported_object_get_path (NM_EXPORTED_OBJECT (device))));

	proxy_config = nm_device_get_proxy_config (device);
	if (proxy_config)
		dump_proxy_to_props (proxy_config, proxy_builder);

	ip4_config = nm_device_get_ip4_config (device);
	if (ip4_config)
		dump_ip4_to_props (ip4_config, ip4_builder);

	ip6_config = nm_device_get_ip6_config (device);
	if (ip6_config)
		dump_ip6_to_props (ip6_config, ip6_builder);

	dhcp4_config = nm_device_get_dhcp4_config (device);
	if (dhcp4_config)
		*dhcp4_props = nm_dhcp4_config_get_options (dhcp4_config);

	dhcp6_config = nm_device_get_dhcp6_config (device);
	if (dhcp6_config)
		*dhcp6_props = nm_dhcp6_config_get_options (dhcp6_config);
}
Ejemplo n.º 5
0
GVariant * CAGattCharacteristicGetProperties(
    GattCharacteristic1 * characteristic)
{
    /**
     * Create a variant containing the @c GattCharacteristic1
     * properties, of the form @c a{sa{sv}}.
     *
     * @note We don't care about the "Value" property here since it is
     *       automatically made available by BlueZ on the client
     *       side.
     *
     * @todo Should we care about "Notifying" property here?
     */

    /*
      Populate the property table, and create the variant to be
      embedded in the results of the
      org.freedesktop.Dbus.ObjectManager.GetManagedObjects() method
      call.
    */
    CADBusSkeletonProperty const properties[] = {
        { "UUID",
          g_variant_new_string(
              gatt_characteristic1_get_uuid(characteristic)) },
        { "Service",
          g_variant_new_object_path(
              gatt_characteristic1_get_service(characteristic)) },
        { "Flags",
          g_variant_new_strv(
              gatt_characteristic1_get_flags(characteristic),
              -1) },
        { "Descriptors",
          g_variant_new_objv(
              gatt_characteristic1_get_descriptors(characteristic),
              -1) }
    };

    return
        CAMakePropertyDictionary(
            BLUEZ_GATT_CHARACTERISTIC_INTERFACE,
            properties,
            sizeof(properties) / sizeof(properties[0]));
}
Ejemplo n.º 6
0
GVariant * CAGattDescriptorGetProperties(GattDescriptor1 * descriptor)
{
    /**
     * Create a variant containing the @c GattDescriptor1 properties,
     * of the form @c a{sa{sv}}.
     *
     * @note We don't care about the "Value" property here since it is
     *       automatically made available by BlueZ on the client
     *       side.
     */

    /*
      Populate the property table, and create the variant to be
      embedded in the results of the
      org.freedesktop.Dbus.ObjectManager.GetManagedObjects() method
      call.
    */
    CADBusSkeletonProperty const properties[] = {
        { "UUID",
          g_variant_new_string(
              gatt_descriptor1_get_uuid(descriptor)) },
        { "Characteristic",
          g_variant_new_object_path(
              gatt_descriptor1_get_characteristic(descriptor)) },
        { "Flags",
          g_variant_new_strv(
              gatt_descriptor1_get_flags(descriptor),
              -1) }
    };

    return
        CAMakePropertyDictionary(
            BLUEZ_GATT_DESCRIPTOR_INTERFACE,
            properties,
            sizeof(properties) / sizeof(properties[0]));
}
Ejemplo n.º 7
0
static gboolean
_dispatcher_call (DispatcherAction action,
                  gboolean blocking,
                  NMSettingsConnection *settings_connection,
                  NMConnection *applied_connection,
                  NMDevice *device,
                  NMConnectivityState connectivity_state,
                  const char *vpn_iface,
                  NMProxyConfig *vpn_proxy_config,
                  NMIP4Config *vpn_ip4_config,
                  NMIP6Config *vpn_ip6_config,
                  DispatcherFunc callback,
                  gpointer user_data,
                  guint *out_call_id)
{
	GVariant *connection_dict;
	GVariantBuilder connection_props;
	GVariantBuilder device_props;
	GVariantBuilder device_proxy_props;
	GVariantBuilder device_ip4_props;
	GVariantBuilder device_ip6_props;
	GVariant *device_dhcp4_props = NULL;
	GVariant *device_dhcp6_props = NULL;
	GVariantBuilder vpn_proxy_props;
	GVariantBuilder vpn_ip4_props;
	GVariantBuilder vpn_ip6_props;
	DispatchInfo *info = NULL;
	gboolean success = FALSE;
	GError *error = NULL;
	static guint request_counter = 0;
	guint reqid = ++request_counter;

	if (!dispatcher_proxy)
		return FALSE;

	/* Wrapping protection */
	if (G_UNLIKELY (!reqid))
		reqid = ++request_counter;

	g_assert (!blocking || (!callback && !user_data));

	_ensure_requests ();

	/* All actions except 'hostname' and 'connectivity-change' require a device */
	if (   action == DISPATCHER_ACTION_HOSTNAME
	    || action == DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
		_LOGD ("(%u) dispatching action '%s'%s",
		       reqid, action_to_string (action),
		       blocking
		           ? " (blocking)"
		           : (callback ? " (with callback)" : ""));
	} else {
		g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);

		_LOGD ("(%u) (%s) dispatching action '%s'%s",
		       reqid,
		       vpn_iface ? vpn_iface : nm_device_get_iface (device),
		       action_to_string (action),
		       blocking
		           ? " (blocking)"
		           : (callback ? " (with callback)" : ""));
	}

	if (!_get_monitor_by_action(action)->has_scripts) {
		if (blocking == FALSE && (out_call_id || callback)) {
			info = g_malloc0 (sizeof (*info));
			info->action = action;
			info->request_id = reqid;
			info->callback = callback;
			info->user_data = user_data;
			info->idle_id = g_idle_add (dispatcher_idle_cb, info);
			_LOGD ("(%u) simulate request; no scripts in %s",  reqid, _get_monitor_by_action(action)->dir);
		} else
			_LOGD ("(%u) ignoring request; no scripts in %s", reqid, _get_monitor_by_action(action)->dir);
		success = TRUE;
		goto done;
	}

	if (applied_connection)
		connection_dict = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
	else
		connection_dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);

	g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT);
	if (settings_connection) {
		const char *connection_path;
		const char *filename;

		connection_path = nm_connection_get_path (NM_CONNECTION (settings_connection));
		if (connection_path) {
			g_variant_builder_add (&connection_props, "{sv}",
			                       NMD_CONNECTION_PROPS_PATH,
			                       g_variant_new_object_path (connection_path));
		}
		filename = nm_settings_connection_get_filename (settings_connection);
		if (filename) {
			g_variant_builder_add (&connection_props, "{sv}",
			                       NMD_CONNECTION_PROPS_FILENAME,
			                       g_variant_new_string (filename));
		}
		if (nm_settings_connection_get_nm_generated_assumed (settings_connection)) {
			g_variant_builder_add (&connection_props, "{sv}",
			                       NMD_CONNECTION_PROPS_EXTERNAL,
			                       g_variant_new_boolean (TRUE));
		}
	}

	g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&device_proxy_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&vpn_proxy_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT);
	g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);

	/* hostname and connectivity-change actions don't send device data */
	if (   action != DISPATCHER_ACTION_HOSTNAME
	    && action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
		fill_device_props (device,
		                   &device_props,
		                   &device_proxy_props,
		                   &device_ip4_props,
		                   &device_ip6_props,
		                   &device_dhcp4_props,
		                   &device_dhcp6_props);
		if (vpn_ip4_config || vpn_ip6_config) {
			fill_vpn_props (vpn_proxy_config,
			                vpn_ip4_config,
			                vpn_ip6_config,
			                &vpn_proxy_props,
			                &vpn_ip4_props,
			                &vpn_ip6_props);
		}
	}

	if (!device_dhcp4_props)
		device_dhcp4_props = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
	if (!device_dhcp6_props)
		device_dhcp6_props = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));

	/* Send the action to the dispatcher */
	if (blocking) {
		GVariant *ret;
		GVariantIter *results;

		ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action",
		                                g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)",
		                                               action_to_string (action),
		                                               connection_dict,
		                                               &connection_props,
		                                               &device_props,
		                                               &device_proxy_props,
		                                               &device_ip4_props,
		                                               &device_ip6_props,
		                                               device_dhcp4_props,
		                                               device_dhcp6_props,
		                                               nm_connectivity_state_to_string (connectivity_state),
		                                               vpn_iface ? vpn_iface : "",
		                                               &vpn_proxy_props,
		                                               &vpn_ip4_props,
		                                               &vpn_ip6_props,
		                                               nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)),
		                                G_VARIANT_TYPE ("(a(sus))"),
		                                G_DBUS_CALL_FLAGS_NONE, CALL_TIMEOUT,
		                                NULL, &error);
		if (ret) {
			g_variant_get (ret, "(a(sus))", &results);
			dispatcher_results_process (reqid, action, results);
			g_variant_iter_free (results);
			g_variant_unref (ret);
			success = TRUE;
		} else {
			g_dbus_error_strip_remote_error (error);
			_LOGW ("(%u) failed: %s", reqid, error->message);
			g_clear_error (&error);
			success = FALSE;
		}
	} else {
		info = g_malloc0 (sizeof (*info));
		info->action = action;
		info->request_id = reqid;
		info->callback = callback;
		info->user_data = user_data;
		g_dbus_proxy_call (dispatcher_proxy, "Action",
		                   g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)",
		                                  action_to_string (action),
		                                  connection_dict,
		                                  &connection_props,
		                                  &device_props,
		                                  &device_proxy_props,
		                                  &device_ip4_props,
		                                  &device_ip6_props,
		                                  device_dhcp4_props,
		                                  device_dhcp6_props,
		                                  nm_connectivity_state_to_string (connectivity_state),
		                                  vpn_iface ? vpn_iface : "",
		                                  &vpn_proxy_props,
		                                  &vpn_ip4_props,
		                                  &vpn_ip6_props,
		                                  nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)),
		                   G_DBUS_CALL_FLAGS_NONE, CALL_TIMEOUT,
		                   NULL, dispatcher_done_cb, info);
		success = TRUE;
	}

	g_variant_unref (device_dhcp4_props);
	g_variant_unref (device_dhcp6_props);

done:
	if (success && info) {
		/* Track the request in case of cancelation */
		g_hash_table_insert (requests, GUINT_TO_POINTER (info->request_id), info);
		if (out_call_id)
			*out_call_id = info->request_id;
	} else if (out_call_id)
		*out_call_id = 0;

	return success;
}
Ejemplo n.º 8
0
static GVariant *
gconf_settings_backend_simple_gconf_value_type_to_gvariant (GConfValue         *gconf_value,
                                                            const GVariantType *expected_type)
{
  /* Note: it's guaranteed that the types are compatible */
  GVariant *variant = NULL;

  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
    variant = g_variant_new_boolean (gconf_value_get_bool (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > 255)
        return NULL;
      variant = g_variant_new_byte (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < G_MINSHORT || value > G_MAXSHORT)
        return NULL;
      variant = g_variant_new_int16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > G_MAXUSHORT)
        return NULL;
      variant = g_variant_new_uint16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
    variant = g_variant_new_int32 (gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint32 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
    variant = g_variant_new_int64 ((gint64) gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint64 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_handle (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
    variant = g_variant_new_double (gconf_value_get_float (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
    variant = g_variant_new_string (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
    variant = g_variant_new_object_path (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
    variant = g_variant_new_signature (gconf_value_get_string (gconf_value));

  return variant;
}
Ejemplo n.º 9
0
GVariant *
g_settings_set_mapping (const GValue       *value,
                        const GVariantType *expected_type,
                        gpointer            user_data)
{
  gchar *type_string;

  if (G_VALUE_HOLDS_BOOLEAN (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
        return g_variant_new_boolean (g_value_get_boolean (value));
    }

  else if (G_VALUE_HOLDS_CHAR (value)  ||
           G_VALUE_HOLDS_UCHAR (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
        {
          if (G_VALUE_HOLDS_CHAR (value))
            return g_variant_new_byte (g_value_get_char (value));
          else
            return g_variant_new_byte (g_value_get_uchar (value));
        }
    }

  else if (G_VALUE_HOLDS_INT (value)   ||
           G_VALUE_HOLDS_INT64 (value))
    return g_settings_set_mapping_int (value, expected_type);

  else if (G_VALUE_HOLDS_DOUBLE (value))
    return g_settings_set_mapping_float (value, expected_type);

  else if (G_VALUE_HOLDS_UINT (value)  ||
           G_VALUE_HOLDS_UINT64 (value))
    return g_settings_set_mapping_unsigned_int (value, expected_type);

  else if (G_VALUE_HOLDS_STRING (value))
    {
      if (g_value_get_string (value) == NULL)
        return NULL;
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
        return g_variant_new_string (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
        return g_variant_new_bytestring (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
        return g_variant_new_object_path (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
        return g_variant_new_signature (g_value_get_string (value));
    }

  else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
    {
      if (g_value_get_boxed (value) == NULL)
        return NULL;
      return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
                                 -1);
    }

  else if (G_VALUE_HOLDS_ENUM (value))
    {
      GEnumValue *enumval;
      GEnumClass *eclass;

      /* GParamSpecEnum holds a ref on the class so we just peek... */
      eclass = g_type_class_peek (G_VALUE_TYPE (value));
      enumval = g_enum_get_value (eclass, g_value_get_enum (value));

      if (enumval)
        return g_variant_new_string (enumval->value_nick);
      else
        return NULL;
    }

  else if (G_VALUE_HOLDS_FLAGS (value))
    {
      GVariantBuilder builder;
      GFlagsValue *flagsval;
      GFlagsClass *fclass;
      guint flags;

      fclass = g_type_class_peek (G_VALUE_TYPE (value));
      flags = g_value_get_flags (value);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
      while (flags)
        {
          flagsval = g_flags_get_first_value (fclass, flags);

          if (flagsval == NULL)
            {
              g_variant_builder_clear (&builder);
              return NULL;
            }

          g_variant_builder_add (&builder, "s", flagsval->value_nick);
          flags &= ~flagsval->value;
        }

      return g_variant_builder_end (&builder);
    }

  type_string = g_variant_type_dup_string (expected_type);
  g_critical ("No GSettings bind handler for type \"%s\".", type_string);
  g_free (type_string);

  return NULL;
}
Ejemplo n.º 10
0
static GVariant *
dconf_dbus_to_gv (DBusMessageIter  *iter,
                  GError          **error)
{
  gint arg_type;

  arg_type = dbus_message_iter_get_arg_type (iter);

  switch (dbus_message_iter_get_arg_type (iter))
    {
     case DBUS_TYPE_BOOLEAN:
      {
        dbus_bool_t value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_boolean (value);
      }

     case DBUS_TYPE_BYTE:
      {
        guchar value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_byte (value);
      }

     case DBUS_TYPE_INT16:
      {
        gint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int16 (value);
      }

     case DBUS_TYPE_UINT16:
      {
        guint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint16 (value);
      }

     case DBUS_TYPE_INT32:
      {
        gint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int32 (value);
      }

     case DBUS_TYPE_UINT32:
      {
        guint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint32 (value);
      }

     case DBUS_TYPE_INT64:
      {
        gint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int64 (value);
      }

     case DBUS_TYPE_UINT64:
      {
        guint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint64 (value);
      }

     case DBUS_TYPE_DOUBLE:
      {
        gdouble value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_double (value);
      }

     case DBUS_TYPE_STRING:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_string (value);
      }

     case DBUS_TYPE_OBJECT_PATH:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_object_path (value);
      }

     case DBUS_TYPE_SIGNATURE:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_signature (value);
      }

     case DBUS_TYPE_VARIANT:
       {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (&sub);
        builder = g_variant_builder_new (G_VARIANT_TYPE_VARIANT);
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
       }

     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_STRUCT:
     case DBUS_TYPE_DICT_ENTRY:
      {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (iter);
        builder = g_variant_builder_new (G_VARIANT_TYPE (type));
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
      }

     default:
       g_set_error (error,
                    G_DBUS_ERROR,
                    G_DBUS_ERROR_CONVERSION_FAILED,
                    _("Error serializing D-Bus message to GVariant. Unsupported arg type `%c' (%d)"),
                    arg_type,
                    arg_type);
      goto fail;
    }

  g_assert_not_reached ();

 fail:
  return NULL;
}
Ejemplo n.º 11
0
/**
 * g_dbus_gvalue_to_gvariant:
 * @gvalue: A #GValue to convert to a #GVariant
 * @type: A #GVariantType
 *
 * Converts a #GValue to a #GVariant of the type indicated by the @type
 * parameter.
 *
 * The conversion is using the following rules:
 *
 * - #G_TYPE_STRING: 's', 'o', 'g' or 'ay'
 * - #G_TYPE_STRV: 'as', 'ao' or 'aay'
 * - #G_TYPE_BOOLEAN: 'b'
 * - #G_TYPE_UCHAR: 'y'
 * - #G_TYPE_INT: 'i', 'n'
 * - #G_TYPE_UINT: 'u', 'q'
 * - #G_TYPE_INT64 'x'
 * - #G_TYPE_UINT64: 't'
 * - #G_TYPE_DOUBLE: 'd'
 * - #G_TYPE_VARIANT: Any #GVariantType
 *
 * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type
 * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType
 * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not
 * in the table above.
 *
 * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is
 * %NULL, the empty #GVariant instance (never %NULL) for @type is
 * returned (e.g. 0 for scalar types, the empty string for string types,
 * '/' for object path types, the empty array for any array type and so on).
 *
 * See the g_dbus_gvariant_to_gvalue() function for how to convert a
 * #GVariant to a #GValue.
 *
 * Returns: A #GVariant (never floating) of #GVariantType @type holding
 *     the data from @gvalue or %NULL in case of failure. Free with
 *     g_variant_unref().
 *
 * Since: 2.30
 */
GVariant *
g_dbus_gvalue_to_gvariant (const GValue       *gvalue,
                           const GVariantType *type)
{
  GVariant *ret;
  const gchar *s;
  const gchar * const *as;
  const gchar *empty_strv[1] = {NULL};

  g_return_val_if_fail (gvalue != NULL, NULL);
  g_return_val_if_fail (type != NULL, NULL);

  ret = NULL;

  /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this
   * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the
   * gdbus-codegen(1) tool.
   */
  if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
    {
      ret = g_value_dup_variant (gvalue);
    }
  else
    {
      switch (g_variant_type_peek_string (type)[0])
        {
        case G_VARIANT_CLASS_BOOLEAN:
          ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
          break;

        case G_VARIANT_CLASS_BYTE:
          ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
          break;

        case G_VARIANT_CLASS_INT16:
          ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT16:
          ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT32:
          ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT32:
          ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT64:
          ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT64:
          ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
          break;

        case G_VARIANT_CLASS_DOUBLE:
          ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
          break;

        case G_VARIANT_CLASS_STRING:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_string (s));
          break;

        case G_VARIANT_CLASS_OBJECT_PATH:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "/";
          ret = g_variant_ref_sink (g_variant_new_object_path (s));
          break;

        case G_VARIANT_CLASS_SIGNATURE:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_signature (s));
          break;

        case G_VARIANT_CLASS_ARRAY:
          switch (g_variant_type_peek_string (type)[1])
            {
            case G_VARIANT_CLASS_BYTE:
              s = g_value_get_string (gvalue);
              if (s == NULL)
                s = "";
              ret = g_variant_ref_sink (g_variant_new_bytestring (s));
              break;

            case G_VARIANT_CLASS_STRING:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
              break;

            case G_VARIANT_CLASS_OBJECT_PATH:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_objv (as, -1));
              break;

            case G_VARIANT_CLASS_ARRAY:
              switch (g_variant_type_peek_string (type)[2])
                {
                case G_VARIANT_CLASS_BYTE:
                  as = g_value_get_boxed (gvalue);
                  if (as == NULL)
                    as = empty_strv;
                  ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
                  break;

                default:
                  ret = g_value_dup_variant (gvalue);
                  break;
                }
              break;

            default:
              ret = g_value_dup_variant (gvalue);
              break;
            }
          break;

        case G_VARIANT_CLASS_HANDLE:
        case G_VARIANT_CLASS_VARIANT:
        case G_VARIANT_CLASS_MAYBE:
        case G_VARIANT_CLASS_TUPLE:
        case G_VARIANT_CLASS_DICT_ENTRY:
          ret = g_value_dup_variant (gvalue);
          break;
        }
    }

  /* Could be that the GValue is holding a NULL GVariant - in that case,
   * we return an "empty" GVariant instead of a NULL GVariant
   */
  if (ret == NULL)
    {
      GVariant *untrusted_empty;
      untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL);
      ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
      g_variant_unref (untrusted_empty);
    }

  g_assert (!g_variant_is_floating (ret));

  return ret;
}
Ejemplo n.º 12
0
static GVariant *
parse_json (JsonNode *node,
            const GVariantType *type,
            GError **error)
{
  const GVariantType *element_type;
  const gchar *str;

  if (!g_variant_type_is_definite (type))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Indefinite type '%.*s' is not supported",
                   (int)g_variant_type_get_string_length (type),
                   g_variant_type_peek_string (type));
      return NULL;
    }

  if (g_variant_type_is_basic (type))
    {
      if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error))
            return g_variant_new_boolean (json_node_get_boolean (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_byte (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, NULL))
            return g_variant_new_double (json_node_get_int (node));
          else if (check_type (node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error))
            return g_variant_new_double (json_node_get_double (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            return g_variant_new_string (json_node_get_string (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_object_path (str))
                return g_variant_new_object_path (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid object path '%s'", str);
                  return NULL;
                }
            }
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_signature (str))
                return g_variant_new_signature (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid signature '%s'", str);
                  return NULL;
                }
            }
        }
      else
        {
          parse_not_supported (type, error);
        }
    }
  else if (g_variant_type_is_variant (type))
    {
      return parse_json_variant (node, error);
    }
  else if (g_variant_type_is_array (type))
    {
      element_type = g_variant_type_element (type);
      if (g_variant_type_is_dict_entry (element_type))
        return parse_json_dictionary (node, element_type, error);
      else
        return parse_json_array (node, element_type, error);
    }
  else if (g_variant_type_is_tuple (type))
    {
      return parse_json_tuple (node, g_variant_type_first (type), error);
    }
  else
    {
      parse_not_supported (type, error);
    }

  return NULL;
}