diff --git a/ChangeLog b/ChangeLog index 2f69b21588..08ffdb4864 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2007-03-26 Tambet Ingo + * libnm-glib/nm-vpn-connection.h: + * libnm-glib/nm-vpn-connection.c: Implement. + + * libnm-glib/nm-client.c: Add VPN support. + * src/vpn-manager/nm-dbus-vpn.c (dbus_message_handler): Implement DBUS message handler for VPN. diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 7bb194462f..c83438deea 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -21,7 +21,8 @@ libnminclude_HEADERS = \ nm-device-802-3-ethernet.h \ nm-device-802-11-wireless.h \ nm-access-point.h \ - nm-ip4-config.h + nm-ip4-config.h \ + nm-vpn-connection.h libnm_glib_la_SOURCES = \ nm-client.c \ @@ -33,6 +34,8 @@ libnm_glib_la_SOURCES = \ nm-ip4-config.c \ nm-utils.c \ nm-utils.h \ + nm-vpn-connection.c \ + nm-marshal-main.c \ $(BUILT_SOURCES) libnm_glib_la_LDFLAGS = $(GLIB_LIBS) $(DBUS_LIBS) @@ -44,6 +47,20 @@ AM_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) libnm_glib_test_SOURCES = libnm-glib-test.c libnm_glib_test_LDADD = $(GLIB_LIBS) $(DBUS_LIBS) $(top_builddir)/libnm-glib/libnm-glib.la +nm-marshal.h: Makefile.am nm-marshal.list + $(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --header > \ + xgen-gmh \ + && (cmp -s xgen-gmh nm-marshal.h || cp xgen-gmh nm-marshal.h) \ + && rm -f xgen-gmh xgen-gmh~ + +nm-marshal.c: Makefile.am nm-marshal.list + $(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --body > \ + xgen-gmc \ + && cp xgen-gmc nm-marshal.c \ + && rm -f xgen-gmc xgen-gmc~ + +nm-marshal-main.c: nm-marshal.c nm-marshal.h + nm-client-bindings.h: $(top_srcdir)/introspection/nm-manager.xml dbus-binding-tool --prefix=nm_client --mode=glib-client --output=nm-client-bindings.h $(top_srcdir)/introspection/nm-manager.xml @@ -65,7 +82,7 @@ pkgconfig_DATA = libnm-glib.pc DISTCLEANFILES = libnm-glib.pc -EXTRA_DIST = libnm-glib.pc.in +EXTRA_DIST = libnm-glib.pc.in nm-marshal.list CLEANFILES = \ $(BUILT_SOURCES) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index c08cae8cb8..08b74f648d 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -4,6 +4,8 @@ #include "nm-device-802-3-ethernet.h" #include "nm-device-802-11-wireless.h" #include "nm-utils.h" +#include "nm-device-private.h" +#include "nm-marshal.h" #include "nm-client-bindings.h" @@ -17,6 +19,11 @@ typedef struct { NMState state; gboolean have_device_list; GHashTable *devices; + + DBusGProxy *vpn_proxy; + NMVPNActStage vpn_state; + gboolean have_vpn_connection_list; + GSList *vpn_connection_list; } NMClientPrivate; enum { @@ -25,6 +32,10 @@ enum { DEVICE_REMOVED, STATE_CHANGE, + VPN_CONNECTION_ADDED, + VPN_CONNECTION_REMOVED, + VPN_STATE_CHANGE, + LAST_SIGNAL }; @@ -40,6 +51,8 @@ static void client_state_change_proxy (DBusGProxy *proxy, guint state, gpointer static void client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data); static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data); +static void setup_vpn_proxy (NMClient *client, DBusGConnection *connection); + static void nm_client_init (NMClient *client) { @@ -49,6 +62,8 @@ nm_client_init (NMClient *client) priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); + + priv->vpn_state = NM_VPN_ACT_STAGE_UNKNOWN; } static void @@ -124,6 +139,35 @@ nm_client_class_init (NMClientClass *client_class) G_TYPE_NONE, 1, G_TYPE_UINT); + signals[VPN_CONNECTION_ADDED] = + g_signal_new ("vpn-connection-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, vpn_connection_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + signals[VPN_CONNECTION_REMOVED] = + g_signal_new ("vpn-connection-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, vpn_connection_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + signals[VPN_STATE_CHANGE] = + g_signal_new ("vpn-state-change", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, state_change), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); } static void @@ -201,6 +245,7 @@ nm_client_new (void) NULL, NULL); + setup_vpn_proxy (client, connection); setup_bus_listener (client, connection); return client; @@ -348,6 +393,28 @@ nm_client_get_devices (NMClient *client) return list; } +NMDevice * +nm_client_get_device_by_path (NMClient *client, const char *object_path) +{ + GSList *devices; + GSList *iter; + NMDevice *device = NULL; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (object_path, NULL); + + devices = nm_client_get_devices (client); + for (iter = devices; iter; iter = iter->next) { + if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), object_path)) { + device = NM_DEVICE (iter->data); + break; + } + } + g_slist_free (devices); + + return device; +} + gboolean nm_client_wireless_get_enabled (NMClient *client) { @@ -415,3 +482,204 @@ nm_client_sleep (NMClient *client, gboolean sleep) } } +/* VPN */ + +/* + * This "best" state is the summary of all states from all connections and + * available for convenience. + * For the exact state, each connection has it's own state which' changes + * are also signalled. + */ +static NMVPNActStage +nm_client_get_best_vpn_state (NMClient *client) +{ + GSList *iter; + NMVPNActStage state; + NMVPNActStage best_state = NM_VPN_ACT_STAGE_UNKNOWN; + + for (iter = nm_client_get_vpn_connections (client); iter; iter = iter->next) { + state = nm_vpn_connection_get_state (NM_VPN_CONNECTION (iter->data)); + if (state > best_state && state < NM_VPN_ACT_STAGE_FAILED) + best_state = state; + } + + return best_state; +} + +static void +proxy_vpn_state_change (DBusGProxy *proxy, char *connection_name, NMVPNActStage state, gpointer user_data) +{ + NMClient *client = NM_CLIENT (user_data); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + NMVPNConnection *connection; + NMVPNActStage best_state; + + connection = nm_client_get_vpn_connection_by_name (client, connection_name); + if (connection) + nm_vpn_connection_set_state (connection, state); + + best_state = nm_client_get_best_vpn_state (client); + if (best_state != priv->vpn_state) { + priv->vpn_state = state; + g_signal_emit (client, signals[VPN_STATE_CHANGE], 0, best_state); + } +} + +static void +proxy_vpn_connection_added (DBusGProxy *proxy, char *name, gpointer user_data) +{ + NMClient *client = NM_CLIENT (user_data); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + NMVPNConnection *connection; + + connection = nm_vpn_connection_new (proxy, name); + if (connection) { + priv->vpn_connection_list = g_slist_append (priv->vpn_connection_list, connection); + g_signal_emit (client, signals[VPN_CONNECTION_ADDED], 0, connection); + } +} + +static void +proxy_vpn_connection_removed (DBusGProxy *proxy, char *name, gpointer user_data) +{ + NMClient *client = NM_CLIENT (user_data); + NMVPNConnection *connection; + + connection = nm_client_get_vpn_connection_by_name (client, name); + if (connection) + nm_client_remove_vpn_connection (client, connection); +} + +static void +proxy_vpn_connection_update (DBusGProxy *proxy, char *name, gpointer user_data) +{ + NMClient *client = NM_CLIENT (user_data); + NMVPNConnection *connection; + + connection = nm_client_get_vpn_connection_by_name (client, name); + if (connection) + nm_vpn_connection_update (connection); +} + +static void +setup_vpn_proxy (NMClient *client, DBusGConnection *connection) +{ + DBusGProxy *proxy; + + proxy = dbus_g_proxy_new_for_name (connection, + NM_DBUS_SERVICE, + NM_DBUS_PATH_VPN, + NM_DBUS_INTERFACE_VPN); + + dbus_g_object_register_marshaller (nm_marshal_VOID__STRING_INT, + G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID); + + dbus_g_proxy_add_signal (proxy, "VPNConnectionStateChange", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, "VPNConnectionStateChange", + G_CALLBACK (proxy_vpn_state_change), + client, NULL); + + dbus_g_proxy_add_signal (proxy, "VPNConnectionAdded", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, "VPNConnectionAdded", + G_CALLBACK (proxy_vpn_connection_added), + client, NULL); + + dbus_g_proxy_add_signal (proxy, "VPNConnectionRemoved", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, "VPNConnectionRemoved", + G_CALLBACK (proxy_vpn_connection_removed), + client, NULL); + + dbus_g_proxy_add_signal (proxy, "VPNConnectionUpdate", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, "VPNConnectionUpdate", + G_CALLBACK (proxy_vpn_connection_update), + client, NULL); + + NM_CLIENT_GET_PRIVATE (client)->vpn_proxy = proxy; +} + +static void +get_connections (NMClient *client) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + char **name; + char **vpn_names = NULL; + GError *err = NULL; + + if (!dbus_g_proxy_call (priv->vpn_proxy, "getVPNConnections", &err, + G_TYPE_INVALID, + G_TYPE_STRV, &vpn_names, + G_TYPE_INVALID)) { + g_warning ("Error while getting VPN connections: %s", err->message); + g_error_free (err); + return; + } + + for (name = vpn_names; *name; name++) + proxy_vpn_connection_added (priv->vpn_proxy, *name, client); + g_strfreev (vpn_names); +} + +GSList * +nm_client_get_vpn_connections (NMClient *client) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + priv = NM_CLIENT_GET_PRIVATE (client); + + if (!priv->have_vpn_connection_list) { + get_connections (client); + priv->have_vpn_connection_list = TRUE; + } + + return priv->vpn_connection_list; +} + +NMVPNConnection * +nm_client_get_vpn_connection_by_name (NMClient *client, const char *name) +{ + GSList *iter; + + for (iter = nm_client_get_vpn_connections (client); iter; iter = iter->next) { + NMVPNConnection *connection = NM_VPN_CONNECTION (iter->data); + + if (!strcmp (nm_vpn_connection_get_name (connection), name)) + return connection; + } + + return NULL; +} + +void +nm_client_remove_vpn_connection (NMClient *client, NMVPNConnection *connection) +{ + NMClientPrivate *priv; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); + + /* Note that the connection isn't removed from NetworkManager, it's + because it doesn't have DBUS API for that right now. */ + + priv = NM_CLIENT_GET_PRIVATE (client); + + priv->vpn_connection_list = g_slist_remove (priv->vpn_connection_list, connection); + g_signal_emit (client, signals[VPN_CONNECTION_REMOVED], 0, connection); + g_object_unref (connection); +} + +NMVPNActStage +nm_client_get_vpn_state (NMClient *client) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NM_VPN_ACT_STAGE_UNKNOWN); + + priv = NM_CLIENT_GET_PRIVATE (client); + + if (priv->vpn_state == NM_VPN_ACT_STAGE_UNKNOWN) + priv->vpn_state = nm_client_get_best_vpn_state (client); + + return priv->vpn_state; +} diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 24d63d16d0..dab013a322 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -5,8 +5,10 @@ #include #include #include -#include "NetworkManager.h" +#include +#include #include "nm-device.h" +#include "nm-vpn-connection.h" #define NM_TYPE_CLIENT (nm_client_get_type ()) #define NM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CLIENT, NMClient)) @@ -27,6 +29,10 @@ typedef struct { void (*device_added) (NMClient *client, NMDevice *device); void (*device_removed) (NMClient *client, NMDevice *device); void (*state_change) (NMClient *client, NMState state); + + void (*vpn_connection_added) (NMClient *client, NMVPNConnection *connection); + void (*vpn_connection_removed) (NMClient *client, NMVPNConnection *connection); + void (*vpn_state_change) (NMClient *client, NMVPNActStage state); } NMClientClass; GType nm_client_get_type (void); @@ -36,9 +42,23 @@ NMClient *nm_client_new (void); gboolean nm_client_manager_is_running (NMClient *client); GSList *nm_client_get_devices (NMClient *client); +NMDevice *nm_client_get_device_by_path (NMClient *client, + const char *object_path); + gboolean nm_client_wireless_get_enabled (NMClient *client); void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled); NMState nm_client_get_state (NMClient *client); void nm_client_sleep (NMClient *client, gboolean sleep); +/* VPN */ + +GSList *nm_client_get_vpn_connections (NMClient *client); +NMVPNConnection *nm_client_get_vpn_connection_by_name (NMClient *client, + const char *name); + +void nm_client_remove_vpn_connection (NMClient *client, + NMVPNConnection *connection); + +NMVPNActStage nm_client_get_vpn_state (NMClient *client); + #endif /* NM_CLIENT_H */ diff --git a/libnm-glib/nm-device-802-11-wireless.c b/libnm-glib/nm-device-802-11-wireless.c index f004acf091..ee5f944d96 100644 --- a/libnm-glib/nm-device-802-11-wireless.c +++ b/libnm-glib/nm-device-802-11-wireless.c @@ -199,7 +199,6 @@ get_network (NMDevice80211Wireless *device, const char *path, gboolean create_if NMAccessPoint * nm_device_802_11_wireless_get_active_network (NMDevice80211Wireless *device) { - GError *err = NULL; char *path; NMAccessPoint *ap = NULL; @@ -216,6 +215,16 @@ nm_device_802_11_wireless_get_active_network (NMDevice80211Wireless *device) return ap; } +NMAccessPoint * +nm_device_802_11_wireless_get_network_by_path (NMDevice80211Wireless *device, + const char *object_path) +{ + g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (device), NULL); + g_return_val_if_fail (object_path != NULL, NULL); + + return get_network (device, object_path, TRUE); +} + static void networks_to_slist (gpointer key, gpointer value, gpointer user_data) { diff --git a/libnm-glib/nm-device-802-11-wireless.h b/libnm-glib/nm-device-802-11-wireless.h index 17ddacb995..d64a469ce4 100644 --- a/libnm-glib/nm-device-802-11-wireless.h +++ b/libnm-glib/nm-device-802-11-wireless.h @@ -34,6 +34,9 @@ int nm_device_802_11_wireless_get_bitrate (NMDevice80211Wire guint32 nm_device_802_11_wireless_get_capabilities (NMDevice80211Wireless *device); NMAccessPoint *nm_device_802_11_wireless_get_active_network (NMDevice80211Wireless *device); +NMAccessPoint *nm_device_802_11_wireless_get_network_by_path (NMDevice80211Wireless *device, + const char *object_path); + GSList *nm_device_802_11_wireless_get_networks (NMDevice80211Wireless *device); void nm_device_802_11_wireless_activate (NMDevice80211Wireless *device, NMAccessPoint *ap, diff --git a/libnm-glib/nm-marshal.list b/libnm-glib/nm-marshal.list new file mode 100644 index 0000000000..75d5d82310 --- /dev/null +++ b/libnm-glib/nm-marshal.list @@ -0,0 +1 @@ +VOID:STRING,INT diff --git a/libnm-glib/nm-vpn-connection.c b/libnm-glib/nm-vpn-connection.c new file mode 100644 index 0000000000..b77152f8e0 --- /dev/null +++ b/libnm-glib/nm-vpn-connection.c @@ -0,0 +1,282 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#include +#include "nm-vpn-connection.h" + +G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) + +#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate)) + +typedef struct { + DBusGProxy *proxy; + char *name; + char *user_name; + char *service; + NMVPNActStage state; +} NMVPNConnectionPrivate; + +enum { + UPDATED, + STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +nm_vpn_connection_init (NMVPNConnection *connection) +{ + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + priv->state = NM_VPN_ACT_STAGE_UNKNOWN; +} + +static void +finalize (GObject *object) +{ + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + + g_free (priv->name); + g_free (priv->user_name); + g_free (priv->service); +} + +static void +nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (connection_class); + + g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate)); + + /* virtual methods */ + object_class->finalize = finalize; + + /* signals */ + signals[UPDATED] = + g_signal_new ("updated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVPNConnectionClass, updated), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + +} + +static gboolean +update_properties (NMVPNConnection *connection) +{ + NMVPNConnectionPrivate *priv; + char *name = NULL; + char *user_name = NULL; + char *service = NULL; + NMVPNActStage state; + GError *err = NULL; + + priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + if (!dbus_g_proxy_call (priv->proxy, "getVPNConnectionProperties", &err, + G_TYPE_STRING, priv->name, + G_TYPE_INVALID, + G_TYPE_STRING, &name, + G_TYPE_STRING, &user_name, + G_TYPE_STRING, &service, + G_TYPE_UINT, &state, + G_TYPE_INVALID)) { + g_warning ("Error while updating VPN connection: %s", err->message); + g_error_free (err); + return FALSE; + } + + g_free (priv->name); + g_free (priv->user_name); + g_free (priv->service); + + priv->name = name; + priv->user_name = user_name; + priv->service = service; + + nm_vpn_connection_set_state (connection, (NMVPNActStage) state); + + return TRUE; +} + +NMVPNConnection * +nm_vpn_connection_new (DBusGProxy *proxy, const char *name) +{ + GObject *object; + NMVPNConnectionPrivate *priv; + + g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); + g_return_val_if_fail (name != NULL, NULL); + + object = g_object_new (NM_TYPE_VPN_CONNECTION, NULL); + if (!object) + return NULL; + + priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + priv->proxy = proxy; + priv->name = g_strdup (name); + + if (!update_properties ((NMVPNConnection *) object)) { + g_object_unref (object); + return NULL; + } + + return (NMVPNConnection *) object; +} + +gboolean +nm_vpn_connection_update (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); + + if (update_properties (vpn)) { + g_signal_emit (vpn, signals[UPDATED], 0); + return TRUE; + } + + return FALSE; +} + +const char * +nm_vpn_connection_get_name (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL); + + return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->name; +} + +const char * +nm_vpn_connection_get_user_name (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL); + + return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->user_name; +} + +const char * +nm_vpn_connection_get_service (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL); + + return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->service; +} + +NMVPNActStage +nm_vpn_connection_get_state (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_ACT_STAGE_UNKNOWN); + + return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state; +} + +void +nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNActStage state) +{ + NMVPNConnectionPrivate *priv; + + g_return_if_fail (NM_IS_VPN_CONNECTION (vpn)); + + priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn); + if (priv->state != state) { + priv->state = state; + g_signal_emit (vpn, signals[STATE_CHANGED], 0, state); + } +} + +gboolean +nm_vpn_connection_is_activating (NMVPNConnection *vpn) +{ + NMVPNActStage state; + + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); + + state = nm_vpn_connection_get_state (vpn); + if (state == NM_VPN_ACT_STAGE_PREPARE || + state == NM_VPN_ACT_STAGE_CONNECT || + state == NM_VPN_ACT_STAGE_IP_CONFIG_GET) + return TRUE; + + return FALSE; +} + +gboolean +nm_vpn_connection_activate (NMVPNConnection *vpn, GSList *passwords) +{ + char **password_strings; + GSList *iter; + int i; + + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); + g_return_val_if_fail (passwords != NULL, FALSE); + + if (nm_vpn_connection_get_state (vpn) != NM_VPN_ACT_STAGE_DISCONNECTED) { + g_warning ("VPN connection is already connected or connecting"); + return FALSE; + } + + i = 0; + password_strings = g_new (char *, g_slist_length (passwords) + 1); + for (iter = passwords; iter; iter = iter->next) + password_strings[i++] = iter->data; + password_strings[i] = NULL; + + /* FIXME: This has to be ASYNC for now since NM will call back to get routes. + We should just pass the routes along with this call */ + dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy, + "activateVPNConnection", + G_TYPE_STRING, nm_vpn_connection_get_name (vpn), + G_TYPE_STRV, password_strings, + G_TYPE_INVALID, + G_TYPE_INVALID); + g_free (password_strings); + + return TRUE; +} + +gboolean +nm_vpn_connection_deactivate (NMVPNConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); + + if (nm_vpn_connection_get_state (vpn) != NM_VPN_ACT_STAGE_ACTIVATED && + !nm_vpn_connection_is_activating (vpn)) { + g_warning ("VPN connection isn't activated"); + return FALSE; + } + + dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy, + "deactivateVPNConnection", + G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} diff --git a/libnm-glib/nm-vpn-connection.h b/libnm-glib/nm-vpn-connection.h new file mode 100644 index 0000000000..ff7d0e32a4 --- /dev/null +++ b/libnm-glib/nm-vpn-connection.h @@ -0,0 +1,68 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#ifndef NM_VPN_CONNECTION_H +#define NM_VPN_CONNECTION_H + +#include +#include +#include +#include "NetworkManagerVPN.h" + +#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) +#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) +#define NM_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) +#define NM_IS_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION)) +#define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_CONNECTION)) +#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) + +typedef struct { + GObject parent; +} NMVPNConnection; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*updated) (NMVPNConnection *connection); + void (*state_changed) (NMVPNConnection *connection, NMVPNActStage state); +} NMVPNConnectionClass; + +GType nm_vpn_connection_get_type (void); + + +NMVPNConnection *nm_vpn_connection_new (DBusGProxy *proxy, const char *name); +gboolean nm_vpn_connection_update (NMVPNConnection *vpn); + +const char *nm_vpn_connection_get_name (NMVPNConnection *vpn); +const char *nm_vpn_connection_get_user_name (NMVPNConnection *vpn); +const char *nm_vpn_connection_get_service (NMVPNConnection *vpn); +NMVPNActStage nm_vpn_connection_get_state (NMVPNConnection *vpn); +gboolean nm_vpn_connection_is_activating (NMVPNConnection *vpn); + +gboolean nm_vpn_connection_activate (NMVPNConnection *vpn, + GSList *passwords); + +gboolean nm_vpn_connection_deactivate (NMVPNConnection *vpn); + +void nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNActStage state); + +#endif /* NM_VPN_CONNECTION_H */