static void
add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
	NMSupplicantInterface *self;
	NMSupplicantInterfacePrivate *priv;
	gs_unref_variant GVariant *reply = NULL;
	gs_free_error GError *error = NULL;
	GHashTable *blobs;
	GHashTableIter iter;
	const char *blob_name;
	GByteArray *blob_data;

	reply = _nm_dbus_proxy_call_finish (proxy, result,
	                                    G_VARIANT_TYPE ("(o)"),
	                                    &error);
	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		return;

	self = NM_SUPPLICANT_INTERFACE (user_data);
	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);

	g_free (priv->net_path);
	priv->net_path = NULL;

	if (error) {
		g_dbus_error_strip_remote_error (error);
		nm_log_warn (LOGD_SUPPLICANT, "Adding network to supplicant failed: %s.", error->message);
		emit_error_helper (self, error);
		return;
	}

	g_variant_get (reply, "(o)", &priv->net_path);

	/* Send blobs first; otherwise jump to selecting the network */
	blobs = nm_supplicant_config_get_blobs (priv->cfg);
	priv->blobs_left = g_hash_table_size (blobs);

	g_hash_table_iter_init (&iter, blobs);
	while (g_hash_table_iter_next (&iter, (gpointer) &blob_name, (gpointer) &blob_data)) {
		g_dbus_proxy_call (priv->iface_proxy,
		                   "AddBlob",
		                   g_variant_new ("(s@ay)",
		                                  blob_name,
		                                  g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
		                                                             blob_data->data, blob_data->len, 1)),
		                   G_DBUS_CALL_FLAGS_NONE,
		                   -1,
		                   priv->assoc_cancellable,
		                   (GAsyncReadyCallback) add_blob_cb,
		                   self);
	}

	call_select_network (self);
}
static void
add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
	NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
	NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
	GError *err = NULL;
	guint tmp;

	priv->blobs_left--;

	if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
		nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message);
		emit_error_helper (info->interface, err);
		g_error_free (err);
	} else
		call_select_network (info->interface);
}
static void
add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
	NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
	NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
	GError *err = NULL;
	GHashTable *blobs;
	GHashTableIter iter;
	gpointer name, data;
	DBusGProxyCall *call;
	NMSupplicantInfo *blob_info;

	g_free (priv->net_path);
	priv->net_path = NULL;

	if (!dbus_g_proxy_end_call (proxy, call_id, &err,
	                            DBUS_TYPE_G_OBJECT_PATH, &priv->net_path,
	                            G_TYPE_INVALID)) {
		nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.",
		             err->message);
		emit_error_helper (info->interface, err);
		g_error_free (err);
		return;
	}

	/* Send blobs first; otherwise jump to sending the config settings */
	blobs = nm_supplicant_config_get_blobs (priv->cfg);
	priv->blobs_left = g_hash_table_size (blobs);
	g_hash_table_iter_init (&iter, blobs);
	while (g_hash_table_iter_next (&iter, &name, &data)) {
		blob_info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
		call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddBlob",
			                            add_blob_cb,
			                            blob_info,
			                            nm_supplicant_info_destroy,
			                            DBUS_TYPE_STRING, name,
			                            DBUS_TYPE_G_UCHAR_ARRAY, blobs,
			                            G_TYPE_INVALID);
		nm_supplicant_info_set_call (blob_info, call);
	}

	call_select_network (info->interface);
}
static void
add_blob_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
	NMSupplicantInterface *self;
	NMSupplicantInterfacePrivate *priv;
	gs_unref_variant GVariant *reply = NULL;
	gs_free_error GError *err = NULL;

	reply = g_dbus_proxy_call_finish (proxy, result, &err);
	if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		return;

	self = NM_SUPPLICANT_INTERFACE (user_data);
	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);

	priv->blobs_left--;
	if (reply)
		call_select_network (self);
	else {
		g_dbus_error_strip_remote_error (err);
		nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message);
		emit_error_helper (self, err);
	}
}