[PATCH 01/15] modem-manager: split the `NMModem' object



The `NMModem' object is split into two objects now:

 * The new `NMModemGeneric' object contains all the implementation specific to
   the old ModemManager interface.

 * The `NMModem' object keeps all the generic stuff; e.g. it doesn't even depend
   on dbus-glib for anything. Several properties in `NMModem' are also now set
   as non-construct-only, as we know that the new ModemManager only knows some
   of the stuff once a bearer has been created, not once a modem is available.

See src/modem-manager/README for more information.
---
 src/modem-manager/Makefile.am        |   2 +
 src/modem-manager/README             |  36 +++
 src/modem-manager/nm-modem-cdma.c    |  10 +-
 src/modem-manager/nm-modem-cdma.h    |   6 +-
 src/modem-manager/nm-modem-generic.c | 437 +++++++++++++++++++++++++++++++++++
 src/modem-manager/nm-modem-generic.h |  54 +++++
 src/modem-manager/nm-modem-gsm.c     |  10 +-
 src/modem-manager/nm-modem-gsm.h     |   6 +-
 src/modem-manager/nm-modem-types.h   |   4 -
 src/modem-manager/nm-modem.c         | 377 ++++--------------------------
 src/modem-manager/nm-modem.h         |  14 +-
 11 files changed, 606 insertions(+), 350 deletions(-)
 create mode 100644 src/modem-manager/README
 create mode 100644 src/modem-manager/nm-modem-generic.c
 create mode 100644 src/modem-manager/nm-modem-generic.h

diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am
index b9cc764..192ed2e 100644
--- a/src/modem-manager/Makefile.am
+++ b/src/modem-manager/Makefile.am
@@ -15,6 +15,8 @@ noinst_LTLIBRARIES = libmodem-manager.la
 libmodem_manager_la_SOURCES = \
 	nm-modem.c \
 	nm-modem.h \
+	nm-modem-generic.c \
+	nm-modem-generic.h \
 	nm-modem-cdma.c \
 	nm-modem-cdma.h \
 	nm-modem-gsm.c \
diff --git a/src/modem-manager/README b/src/modem-manager/README
new file mode 100644
index 0000000..eba36ba
--- /dev/null
+++ b/src/modem-manager/README
@@ -0,0 +1,36 @@
+
+ModemManager integration is organized as follows:
+
+
+Common source
+********************************************************************************
+
+ * nm-modem.[h|c]:
+      Defines the basic `NMModem' object. The core NetworkManager implementation
+      will use this interface exclusively, regardless of the real final type of
+      the modem object.
+
+
+ModemManager 0.4/0.5/0.6 integration
+********************************************************************************
+
+ * nm-modem-types.h:
+      Defines helper types to use with the (old) ModemManager DBus API.
+
+ * nm-modem-generic.[h|c]:
+      Defines the `NMModemGeneric' object. All modem objects based on the old
+      ModemManager interface are subclasses of this one.
+
+ * nm-modem-gsm.[h|c]:
+      Defines the `NMModemGsm' object, which is a subclass of `NMModemGeneric'.
+      This object handles 3GPP-specific (GSM, UMTS, HSPA, LTE) modems.
+
+ * nm-modem-cdma.[h|c]:
+      Defines the `NMModemCdma' object, which is a subclass of `NMModemGeneric'.
+      This object handles 3GPP2-specific modems (CDMA, EV-DO).
+
+ * nm-modem-manager.[h|c]:
+      Defines the `NMModemManager' object, which takes care of listening to
+      signals from the DBus inteface notifying about added or removed modems.
+      It also takes care of creating proper `NMModemGsm' or `NMModemCdma'
+      objects from the information retrieved from the DBus interface.
diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c
index 54a0e31..b02c193 100644
--- a/src/modem-manager/nm-modem-cdma.c
+++ b/src/modem-manager/nm-modem-cdma.c
@@ -37,7 +37,7 @@
 #include "NetworkManagerUtils.h"
 #include "nm-logging.h"
 
-G_DEFINE_TYPE (NMModemCdma, nm_modem_cdma, NM_TYPE_MODEM)
+G_DEFINE_TYPE (NMModemCdma, nm_modem_cdma, NM_TYPE_MODEM_GENERIC)
 
 #define NM_MODEM_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_CDMA, NMModemCdmaPrivate))
 
@@ -111,7 +111,7 @@ do_connect (NMModemCdma *self)
 	NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (self);
 	DBusGProxy *proxy;
 
-	proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_SIMPLE);
+	proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_DBUS_INTERFACE_MODEM_SIMPLE);
 	priv->call = dbus_g_proxy_begin_call_with_timeout (proxy,
 	                                                   "Connect", stage1_prepare_done,
 	                                                   self, NULL, 120000,
@@ -179,7 +179,7 @@ act_stage1_prepare (NMModem *modem,
 		if (enabled)
 			do_connect (self);
 		else {
-			proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM);
+			proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_DBUS_INTERFACE_MODEM);
 			dbus_g_proxy_begin_call_with_timeout (proxy,
 			                                      "Enable", stage1_enable_done,
 			                                      modem, NULL, 20000,
@@ -319,12 +319,12 @@ deactivate (NMModem *modem, NMDevice *device)
 	if (priv->call) {
 		DBusGProxy *proxy;
 
-		proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE);
+		proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_DBUS_INTERFACE_MODEM_SIMPLE);
 		dbus_g_proxy_cancel_call (proxy, priv->call);
 		priv->call = NULL;
 	}
 
-	NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate (modem, device);	
+	NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate (modem, device);
 }
 
 /*****************************************************************************/
diff --git a/src/modem-manager/nm-modem-cdma.h b/src/modem-manager/nm-modem-cdma.h
index 496f06c..50d0cb2 100644
--- a/src/modem-manager/nm-modem-cdma.h
+++ b/src/modem-manager/nm-modem-cdma.h
@@ -22,7 +22,7 @@
 #ifndef NM_MODEM_CDMA_H
 #define NM_MODEM_CDMA_H
 
-#include <nm-modem.h>
+#include <nm-modem-generic.h>
 
 G_BEGIN_DECLS
 
@@ -40,11 +40,11 @@ typedef enum {
 } NMCdmaError;
 
 typedef struct {
-	NMModem parent;
+	NMModemGeneric parent;
 } NMModemCdma;
 
 typedef struct {
-	NMModemClass parent;
+	NMModemGenericClass parent;
 
 	/* Signals */
 	void (*signal_quality) (NMModemCdma *self, guint32 quality);
diff --git a/src/modem-manager/nm-modem-generic.c b/src/modem-manager/nm-modem-generic.c
new file mode 100644
index 0000000..33454da
--- /dev/null
+++ b/src/modem-manager/nm-modem-generic.c
@@ -0,0 +1,437 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include <string.h>
+#include "nm-modem-generic.h"
+#include "nm-system.h"
+#include "nm-dbus-manager.h"
+#include "nm-setting-connection.h"
+#include "nm-marshal.h"
+#include "nm-properties-changed-signal.h"
+#include "nm-modem-types.h"
+#include "nm-logging.h"
+#include "NetworkManagerUtils.h"
+#include "nm-device-private.h"
+#include "nm-dbus-glib-types.h"
+
+G_DEFINE_TYPE (NMModemGeneric, nm_modem_generic, NM_TYPE_MODEM)
+
+#define NM_MODEM_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GENERIC, NMModemGenericPrivate))
+
+typedef struct {
+	NMDBusManager *dbus_mgr;
+	DBusGProxy *proxy;
+	DBusGProxy *props_proxy;
+
+	DBusGProxyCall *call;
+} NMModemGenericPrivate;
+
+/*****************************************************************************/
+
+DBusGProxy *
+nm_modem_generic_get_proxy (NMModemGeneric *self,
+                            const char *interface)
+{
+
+	NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+	const char *current_iface;
+
+	g_return_val_if_fail (NM_IS_MODEM_GENERIC (self), NULL);
+
+	/* Default to the default interface. */
+	if (interface == NULL)
+		interface = MM_DBUS_INTERFACE_MODEM;
+
+	if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES))
+		return priv->props_proxy;
+
+	current_iface = dbus_g_proxy_get_interface (priv->proxy);
+	if (!current_iface || strcmp (current_iface, interface))
+		dbus_g_proxy_set_interface (priv->proxy, interface);
+
+	return priv->proxy;
+}
+
+/*****************************************************************************/
+/* Query/Update enabled state */
+
+static void
+update_mm_enabled (NMModem *self,
+                   gboolean new_enabled)
+{
+	if (nm_modem_get_mm_enabled (self) != new_enabled) {
+		g_object_set (self,
+		              NM_MODEM_ENABLED, new_enabled,
+		              NULL);
+	}
+}
+
+static void
+get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+	NMModem *self = NM_MODEM (user_data);
+	GError *error = NULL;
+	GValue value = { 0, };
+
+	if (!dbus_g_proxy_end_call (proxy, call_id, &error,
+	                            G_TYPE_VALUE, &value,
+	                            G_TYPE_INVALID)) {
+		nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s",
+		             error ? error->code : -1,
+		             error && error->message ? error->message : "(unknown)");
+		return;
+	}
+
+	if (G_VALUE_HOLDS_BOOLEAN (&value)) {
+		update_mm_enabled (self, g_value_get_boolean (&value));
+	} else
+		nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type");
+
+	g_value_unset (&value);
+}
+
+static void
+query_mm_enabled (NMModemGeneric *self)
+{
+	dbus_g_proxy_begin_call (NM_MODEM_GENERIC_GET_PRIVATE (self)->props_proxy,
+	                         "Get", get_mm_enabled_done,
+	                         self, NULL,
+	                         G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
+	                         G_TYPE_STRING, "Enabled",
+	                         G_TYPE_INVALID);
+}
+
+static void
+set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+	GError *error = NULL;
+
+	if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
+		nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s",
+		             error ? error->code : -1,
+		             error && error->message ? error->message : "(unknown)");
+	}
+
+	/* Update enabled/disabled state again */
+	query_mm_enabled (NM_MODEM_GENERIC (user_data));
+}
+
+static void
+set_mm_enabled (NMModem *self, gboolean enabled)
+{
+	/* FIXME: For now this just toggles the ModemManager enabled state.  In the
+	 * future we want to tie this into rfkill state instead so that the user can
+	 * toggle rfkill status of the WWAN modem.
+	 */
+	dbus_g_proxy_begin_call (nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self),
+	                                                     MM_DBUS_INTERFACE_MODEM),
+	                         "Enable", set_mm_enabled_done,
+	                         self, NULL,
+	                         G_TYPE_BOOLEAN, enabled,
+	                         G_TYPE_INVALID);
+	/* If we are disabling the modem, stop saying that it's enabled. */
+	if (!enabled)
+		update_mm_enabled (self, enabled);
+}
+
+/*****************************************************************************/
+/* IP method static */
+
+static char addr_to_string_buf[INET6_ADDRSTRLEN + 1];
+
+static const char *
+ip_address_to_string (guint32 numeric)
+{
+	struct in_addr temp_addr;
+
+	memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf));
+	temp_addr.s_addr = numeric;
+
+	if (inet_ntop (AF_INET, &temp_addr, addr_to_string_buf, INET_ADDRSTRLEN)) {
+		return addr_to_string_buf;
+	} else {
+		nm_log_warn (LOGD_VPN, "error converting IP4 address 0x%X",
+		             ntohl (temp_addr.s_addr));
+		return NULL;
+	}
+}
+
+static void
+static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+	NMModemGeneric *self = NM_MODEM_GENERIC (user_data);
+	NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+	GValueArray *ret_array = NULL;
+	GError *error = NULL;
+	NMIP4Config *config = NULL;
+
+	priv->call = NULL;
+
+	/* Returned value array is (uuuu): [IP, DNS1, DNS2, DNS3], all in
+	 * network byte order.
+	 */
+	if (dbus_g_proxy_end_call (proxy, call, &error,
+	                           G_TYPE_VALUE_ARRAY, &ret_array,
+	                           G_TYPE_INVALID)) {
+		NMIP4Address *addr;
+		int i;
+
+		config = nm_ip4_config_new ();
+
+		addr = nm_ip4_address_new ();
+
+		nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:",
+		             nm_modem_get_iface (NM_MODEM (self)));
+
+		/* IP address */
+		nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0)));
+		nm_ip4_address_set_prefix (addr, 32);
+		nm_ip4_config_take_address (config, addr);
+
+		nm_log_info (LOGD_MB, "  address %s/%d",
+		             ip_address_to_string (nm_ip4_address_get_address (addr)),
+		             nm_ip4_address_get_prefix (addr));
+
+		/* DNS servers */
+		for (i = 1; i < ret_array->n_values; i++) {
+			GValue *value = g_value_array_get_nth (ret_array, i);
+			guint32 tmp = g_value_get_uint (value);
+
+			if (tmp > 0) {
+				nm_ip4_config_add_nameserver (config, tmp);
+				nm_log_info (LOGD_MB, "  DNS %s", ip_address_to_string (tmp));
+			}
+		}
+		g_value_array_free (ret_array);
+	}
+
+	g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, NULL, config, error);
+	g_clear_error (&error);
+}
+
+static NMActStageReturn
+static_stage3_ip4_config_start (NMModem *self,
+                                NMActRequest *req,
+                                NMDeviceStateReason *reason)
+{
+	NMModemGenericPrivate *priv;
+
+	g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+	g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE);
+	g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
+	g_return_val_if_fail (reason !=	NULL, NM_ACT_STAGE_RETURN_FAILURE);
+
+	priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+
+	priv->call = dbus_g_proxy_begin_call (nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self),
+	                                                                  MM_DBUS_INTERFACE_MODEM),
+	                                      "GetIP4Config", static_stage3_done,
+	                                      self, NULL,
+	                                      G_TYPE_INVALID);
+
+	return NM_ACT_STAGE_RETURN_POSTPONE;
+}
+
+/*****************************************************************************/
+
+static void
+disconnect_done (DBusGProxy *proxy,
+                 DBusGProxyCall *call_id,
+                 gpointer user_data)
+{
+	GError *error = NULL;
+	gboolean warn = GPOINTER_TO_UINT (user_data);
+
+	if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) && warn) {
+		nm_log_info (LOGD_MB, "disconnect failed: (%d) %s",
+		             error ? error->code : -1,
+		             error && error->message ? error->message : "(unknown)");
+	}
+}
+
+static void
+disconnect (NMModem *self,
+            gboolean warn)
+{
+	dbus_g_proxy_begin_call (nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self),
+	                                                     MM_DBUS_INTERFACE_MODEM),
+	                         "Disconnect",
+	                         disconnect_done,
+	                         GUINT_TO_POINTER (warn),
+	                         NULL,
+	                         G_TYPE_INVALID);
+}
+
+/*****************************************************************************/
+
+static void
+deactivate (NMModem *self, NMDevice *device)
+{
+	NMModemGenericPrivate *priv;
+
+	g_assert (NM_IS_MODEM_GENERIC (self));
+	g_assert (NM_IS_DEVICE (device));
+
+	priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+
+	if (priv->call) {
+		dbus_g_proxy_cancel_call (priv->proxy, priv->call);
+		priv->call = NULL;
+	}
+
+	/* Chain up parent's */
+	NM_MODEM_CLASS (nm_modem_generic_parent_class)->deactivate (self, device);
+}
+
+/*****************************************************************************/
+
+static void
+modem_properties_changed (DBusGProxy *proxy,
+                          const char *interface,
+                          GHashTable *props,
+                          gpointer user_data)
+{
+	NMModemGeneric *self = NM_MODEM_GENERIC (user_data);
+	NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+	GValue *value;
+	NMModemState new_state;
+
+	if (strcmp (interface, MM_DBUS_INTERFACE_MODEM))
+		return;
+
+	value = g_hash_table_lookup (props, "Enabled");
+	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+		g_object_set (self,
+		              NM_MODEM_ENABLED, g_value_get_boolean (value),
+		              NULL);
+	}
+
+	value = g_hash_table_lookup (props, "IpMethod");
+	if (value && G_VALUE_HOLDS_UINT (value)) {
+		g_object_set (self,
+		              NM_MODEM_IP_METHOD, g_value_get_uint (value),
+		              NULL);
+	}
+
+	value = g_hash_table_lookup (props, "State");
+	if (value && G_VALUE_HOLDS_UINT (value)) {
+		new_state = g_value_get_uint (value);
+		if (new_state != nm_modem_get_state (NM_MODEM (self))) {
+			g_object_set (self,
+			              NM_MODEM_STATE, new_state,
+			              NULL);
+		}
+	}
+}
+
+/*****************************************************************************/
+
+static void
+nm_modem_generic_init (NMModemGeneric *self)
+{
+	NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self);
+
+	priv->dbus_mgr = nm_dbus_manager_get ();
+}
+
+static GObject*
+constructor (GType type,
+			 guint n_construct_params,
+			 GObjectConstructParam *construct_params)
+{
+	GObject *object;
+	NMModemGenericPrivate *priv;
+	DBusGConnection *bus;
+
+	object = G_OBJECT_CLASS (nm_modem_generic_parent_class)->constructor (type, n_construct_params, construct_params);
+	if (!object)
+		return NULL;
+
+	priv = NM_MODEM_GENERIC_GET_PRIVATE (object);
+
+	bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+	priv->proxy = dbus_g_proxy_new_for_name (bus,
+	                                         MM_DBUS_SERVICE,
+	                                         nm_modem_get_path (NM_MODEM (object)),
+	                                         MM_DBUS_INTERFACE_MODEM);
+
+	priv->props_proxy = dbus_g_proxy_new_for_name (bus,
+	                                               MM_DBUS_SERVICE,
+	                                               nm_modem_get_path (NM_MODEM (object)),
+	                                               DBUS_INTERFACE_PROPERTIES);
+	dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
+	                                   G_TYPE_NONE,
+	                                   G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+	                                   G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged",
+	                         G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+	                         G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged",
+	                             G_CALLBACK (modem_properties_changed),
+	                             object,
+	                             NULL);
+
+	query_mm_enabled (NM_MODEM_GENERIC (object));
+
+	return object;
+}
+
+static void
+dispose (GObject *object)
+{
+	NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (object);
+
+	if (priv->proxy) {
+		g_object_unref (priv->proxy);
+		priv->proxy = NULL;
+	}
+
+	if (priv->props_proxy) {
+		g_object_unref (priv->props_proxy);
+		priv->props_proxy = NULL;
+	}
+
+	if (priv->dbus_mgr) {
+		g_object_unref (priv->dbus_mgr);
+		priv->dbus_mgr = NULL;
+	}
+
+	G_OBJECT_CLASS (nm_modem_generic_parent_class)->dispose (object);
+}
+
+static void
+nm_modem_generic_class_init (NMModemGenericClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	NMModemClass *modem_class = NM_MODEM_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (NMModemGenericPrivate));
+
+	/* Virtual methods */
+	object_class->constructor = constructor;
+	object_class->dispose = dispose;
+
+	modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start;
+	modem_class->disconnect = disconnect;
+	modem_class->deactivate = deactivate;
+	modem_class->set_mm_enabled = set_mm_enabled;
+}
diff --git a/src/modem-manager/nm-modem-generic.h b/src/modem-manager/nm-modem-generic.h
new file mode 100644
index 0000000..5a9ee76
--- /dev/null
+++ b/src/modem-manager/nm-modem-generic.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_MODEM_GENERIC_H
+#define NM_MODEM_GENERIC_H
+
+#include <dbus/dbus-glib.h>
+#include <glib-object.h>
+#include "nm-modem.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_MODEM_GENERIC            (nm_modem_generic_get_type ())
+#define NM_MODEM_GENERIC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GENERIC, NMModemGeneric))
+#define NM_MODEM_GENERIC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_MODEM_GENERIC, NMModemGenericClass))
+#define NM_IS_MODEM_GENERIC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GENERIC))
+#define NM_IS_MODEM_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_MODEM_GENERIC))
+#define NM_MODEM_GENERIC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_MODEM_GENERIC, NMModemGenericClass))
+
+typedef struct {
+	NMModem parent;
+} NMModemGeneric;
+
+typedef struct {
+	NMModemClass parent;
+} NMModemGenericClass;
+
+GType nm_modem_generic_get_type (void);
+
+/* Protected */
+DBusGProxy *nm_modem_generic_get_proxy (NMModemGeneric *modem,
+                                        const gchar *interface);
+
+G_END_DECLS
+
+#endif /* NM_MODEM_GENERIC_H */
diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c
index 9d05c9c..feef908 100644
--- a/src/modem-manager/nm-modem-gsm.c
+++ b/src/modem-manager/nm-modem-gsm.c
@@ -77,7 +77,7 @@ typedef enum {
     MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP
 } MMModemGsmAllowedAuth;
 
-G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM)
+G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM_GENERIC)
 
 #define NM_MODEM_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GSM, NMModemGsmPrivate))
 
@@ -226,7 +226,7 @@ do_connect (NMModemGsm *self)
 	NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self);
 	DBusGProxy *proxy;
 
-	proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_SIMPLE);
+	proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_DBUS_INTERFACE_MODEM_SIMPLE);
 	dbus_g_proxy_begin_call_with_timeout (proxy,
 	                                      "Connect", stage1_prepare_done,
 	                                      self, NULL, 120000,
@@ -246,7 +246,7 @@ do_enable (NMModemGsm *self)
 	g_return_val_if_fail (NM_IS_MODEM_GSM (self), FALSE);
 
 	NM_MODEM_GSM_GET_PRIVATE (self)->enable_delay_id = 0;
-	proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM);
+	proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_DBUS_INTERFACE_MODEM);
 	dbus_g_proxy_begin_call_with_timeout (proxy,
 	                                      "Enable", stage1_enable_done,
 	                                      self, NULL, 20000,
@@ -299,7 +299,7 @@ handle_enable_pin_required (NMModemGsm *self)
 
 	/* If we do, send it */
 	if (pin) {
-		proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_GSM_CARD);
+		proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_DBUS_INTERFACE_MODEM_GSM_CARD);
 		dbus_g_proxy_begin_call_with_timeout (proxy,
 		                                      "SendPin", stage1_pin_done,
 		                                      self, NULL, 10000,
@@ -597,7 +597,7 @@ deactivate (NMModem *modem, NMDevice *device)
 	if (priv->call) {
 		DBusGProxy *proxy;
 
-		proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE);
+		proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_DBUS_INTERFACE_MODEM_SIMPLE);
 		dbus_g_proxy_cancel_call (proxy, priv->call);
 		priv->call = NULL;
 	}
diff --git a/src/modem-manager/nm-modem-gsm.h b/src/modem-manager/nm-modem-gsm.h
index 3afdf89..3846405 100644
--- a/src/modem-manager/nm-modem-gsm.h
+++ b/src/modem-manager/nm-modem-gsm.h
@@ -22,7 +22,7 @@
 #ifndef NM_MODEM_GSM_H
 #define NM_MODEM_GSM_H
 
-#include <nm-modem.h>
+#include <nm-modem-generic.h>
 
 G_BEGIN_DECLS
 
@@ -40,11 +40,11 @@ typedef enum {
 } NMGsmError;
 
 typedef struct {
-	NMModem parent;
+	NMModemGeneric parent;
 } NMModemGsm;
 
 typedef struct {
-	NMModemClass parent;
+	NMModemGenericClass parent;
 
 	/* Signals */
 	void (*signal_quality) (NMModemGsm *self, guint32 quality);
diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h
index e805cb2..b9f6e5b 100644
--- a/src/modem-manager/nm-modem-types.h
+++ b/src/modem-manager/nm-modem-types.h
@@ -35,10 +35,6 @@
 #define MM_MODEM_TYPE_GSM      1
 #define MM_MODEM_TYPE_CDMA     2
 
-#define MM_MODEM_IP_METHOD_PPP    0
-#define MM_MODEM_IP_METHOD_STATIC 1
-#define MM_MODEM_IP_METHOD_DHCP   2
-
 /* Errors */
 
 #define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed"
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 0efe6e4..e9f3092 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -50,22 +50,17 @@ enum {
 };
 
 typedef struct {
-	NMDBusManager *dbus_mgr;
-	DBusGProxy *proxy;
-	DBusGProxy *props_proxy;
-
 	char *path;
-	NMPPPManager *ppp_manager;
-	guint32 ip_method;
 	char *device;
 	char *iface;
+	guint32 ip_method;
+
+	NMPPPManager *ppp_manager;
 
 	NMActRequest *act_request;
 	guint32 secrets_tries;
 	guint32 secrets_id;
 
-	DBusGProxyCall *call;
-
 	gboolean mm_enabled;
 	guint32 mm_ip_timeout;
 	NMModemState state;
@@ -88,55 +83,35 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-static void
-update_mm_enabled (NMModem *self, gboolean new_enabled)
-{
-	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
-
-	if (priv->mm_enabled != new_enabled) {
-		priv->mm_enabled = new_enabled;
-		g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
-	}
-}
+/*****************************************************************************/
+/* Get/Set enabled/connected */
 
 gboolean
 nm_modem_get_mm_enabled (NMModem *self)
 {
-	g_return_val_if_fail (NM_IS_MODEM (self), TRUE);
-
 	return NM_MODEM_GET_PRIVATE (self)->mm_enabled;
 }
 
-NMModemState
-nm_modem_get_state (NMModem *self)
-{
-	g_return_val_if_fail (NM_IS_MODEM (self), NM_MODEM_STATE_UNKNOWN);
-
-	return NM_MODEM_GET_PRIVATE (self)->state;
-}
-
-DBusGProxy *
-nm_modem_get_proxy (NMModem *self,
-					const char *interface)
+void
+nm_modem_set_mm_enabled (NMModem *self,
+                         gboolean enabled)
 {
+	NMModemPrivate *priv;
 
-	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
-	const char *current_iface;
-
-	g_return_val_if_fail (NM_IS_MODEM (self), NULL);
+	priv = NM_MODEM_GET_PRIVATE (self);
 
-	/* Default to the default interface. */
-	if (interface == NULL)
-		interface = MM_DBUS_INTERFACE_MODEM;
+	if (priv->mm_enabled != enabled)
+		NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled);
+}
 
-	if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES))
-		return priv->props_proxy;
+/*****************************************************************************/
 
-	current_iface = dbus_g_proxy_get_interface (priv->proxy);
-	if (!current_iface || strcmp (current_iface, interface))
-		dbus_g_proxy_set_interface (priv->proxy, interface);
+NMModemState
+nm_modem_get_state (NMModem *self)
+{
+	g_return_val_if_fail (NM_IS_MODEM (self), NM_MODEM_STATE_UNKNOWN);
 
-	return priv->proxy;
+	return NM_MODEM_GET_PRIVATE (self)->state;
 }
 
 /*****************************************************************************/
@@ -290,103 +265,6 @@ ppp_stage3_ip4_config_start (NMModem *self,
 }
 
 /*****************************************************************************/
-/* IP method static */
-
-static char addr_to_string_buf[INET6_ADDRSTRLEN + 1];
-
-static const char *
-ip_address_to_string (guint32 numeric)
-{
-	struct in_addr temp_addr;
-
-	memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf));
-	temp_addr.s_addr = numeric;
-
-	if (inet_ntop (AF_INET, &temp_addr, addr_to_string_buf, INET_ADDRSTRLEN)) {
-		return addr_to_string_buf;
-	} else {
-		nm_log_warn (LOGD_VPN, "error converting IP4 address 0x%X",
-		             ntohl (temp_addr.s_addr));
-		return NULL;
-	}
-}
-
-static void
-static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
-{
-	NMModem *self = NM_MODEM (user_data);
-	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
-	GValueArray *ret_array = NULL;
-	GError *error = NULL;
-	NMIP4Config *config = NULL;
-
-	priv->call = NULL;
-
-	/* Returned value array is (uuuu): [IP, DNS1, DNS2, DNS3], all in
-	 * network byte order.
-	 */
-	if (dbus_g_proxy_end_call (proxy, call, &error,
-	                           G_TYPE_VALUE_ARRAY, &ret_array,
-	                           G_TYPE_INVALID)) {
-		NMIP4Address *addr;
-		int i;
-
-		config = nm_ip4_config_new ();
-
-		addr = nm_ip4_address_new ();
-
-		nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", priv->iface);
-
-		/* IP address */
-		nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0)));
-		nm_ip4_address_set_prefix (addr, 32);
-		nm_ip4_config_take_address (config, addr);
-
-		nm_log_info (LOGD_MB, "  address %s/%d",
-		             ip_address_to_string (nm_ip4_address_get_address (addr)),
-		             nm_ip4_address_get_prefix (addr));
-
-		/* DNS servers */
-		for (i = 1; i < ret_array->n_values; i++) {
-			GValue *value = g_value_array_get_nth (ret_array, i);
-			guint32 tmp = g_value_get_uint (value);
-
-			if (tmp > 0) {
-				nm_ip4_config_add_nameserver (config, tmp);
-				nm_log_info (LOGD_MB, "  DNS %s", ip_address_to_string (tmp));
-			}
-		}
-		g_value_array_free (ret_array);
-	}
-
-	g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, error);
-	g_clear_error (&error);
-}
-
-static NMActStageReturn
-static_stage3_ip4_config_start (NMModem *self,
-                                NMActRequest *req,
-                                NMDeviceStateReason *reason)
-{
-	NMModemPrivate *priv;
-
-	g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE);
-	g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE);
-	g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
-	g_return_val_if_fail (reason !=	NULL, NM_ACT_STAGE_RETURN_FAILURE);
-
-	priv = NM_MODEM_GET_PRIVATE (self);
-
-	priv->call = dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
-	                                      "GetIP4Config", static_stage3_done,
-	                                      self, NULL,
-	                                      G_TYPE_INVALID);
-
-	return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
 
 NMActStageReturn
 nm_modem_stage3_ip4_config_start (NMModem *self,
@@ -415,7 +293,7 @@ nm_modem_stage3_ip4_config_start (NMModem *self,
 		ret = ppp_stage3_ip4_config_start (self, req, reason);
 		break;
 	case MM_MODEM_IP_METHOD_STATIC:
-		ret = static_stage3_ip4_config_start (self, req, reason);
+		ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason);
 		break;
 	case MM_MODEM_IP_METHOD_DHCP:
 		ret = device_class->act_stage3_ip4_config_start (device, NULL, reason);
@@ -429,6 +307,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self,
 	return ret;
 }
 
+/*****************************************************************************/
+
 NMActStageReturn
 nm_modem_stage3_ip6_config_start (NMModem *self,
                                   NMDevice *device,
@@ -440,6 +320,8 @@ nm_modem_stage3_ip6_config_start (NMModem *self,
 	return NM_ACT_STAGE_RETURN_POSTPONE;
 }
 
+/*****************************************************************************/
+
 static void
 cancel_get_secrets (NMModem *self)
 {
@@ -496,6 +378,8 @@ nm_modem_get_secrets (NMModem *self,
 	return !!(priv->secrets_id);
 }
 
+/*****************************************************************************/
+
 static NMActStageReturn
 act_stage1_prepare (NMModem *modem,
                     NMActRequest *req,
@@ -551,6 +435,8 @@ nm_modem_act_stage1_prepare (NMModem *self,
 	return ret;
 }
 
+/*****************************************************************************/
+
 NMActStageReturn
 nm_modem_act_stage2_config (NMModem *self,
                             NMActRequest *req,
@@ -566,6 +452,8 @@ nm_modem_act_stage2_config (NMModem *self,
 	return NM_ACT_STAGE_RETURN_SUCCESS;
 }
 
+/*****************************************************************************/
+
 NMConnection *
 nm_modem_get_best_auto_connection (NMModem *self,
                                    GSList *connections,
@@ -576,6 +464,8 @@ nm_modem_get_best_auto_connection (NMModem *self,
 	return NULL;
 }
 
+/*****************************************************************************/
+
 gboolean
 nm_modem_check_connection_compatible (NMModem *self,
                                       NMConnection *connection,
@@ -586,6 +476,8 @@ nm_modem_check_connection_compatible (NMModem *self,
 	return FALSE;
 }
 
+/*****************************************************************************/
+
 gboolean
 nm_modem_complete_connection (NMModem *self,
                               NMConnection *connection,
@@ -597,6 +489,8 @@ nm_modem_complete_connection (NMModem *self,
 	return FALSE;
 }
 
+/*****************************************************************************/
+
 static void
 deactivate (NMModem *self, NMDevice *device)
 {
@@ -618,11 +512,6 @@ deactivate (NMModem *self, NMDevice *device)
 		priv->act_request = NULL;
 	}
 
-	if (priv->call) {
-		dbus_g_proxy_cancel_call (priv->proxy, priv->call);
-		priv->call = NULL;
-	}
-
 	priv->in_bytes = priv->out_bytes = 0;
 
 	if (priv->ppp_manager) {
@@ -649,24 +538,15 @@ deactivate (NMModem *self, NMDevice *device)
 	}
 }
 
+/*****************************************************************************/
+
 void
 nm_modem_deactivate (NMModem *self, NMDevice *device)
 {
 	NM_MODEM_GET_CLASS (self)->deactivate (self, device);
 }
 
-static void
-disconnect_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
-	GError *error = NULL;
-	gboolean warn = GPOINTER_TO_UINT (user_data);
-
-	if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) && warn) {
-		nm_log_info (LOGD_MB, "disconnect failed: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-	}
-}
+/*****************************************************************************/
 
 void
 nm_modem_device_state_changed (NMModem *self,
@@ -707,12 +587,7 @@ nm_modem_device_state_changed (NMModem *self,
 			/* Don't bother warning on FAILED since the modem is already gone */
 			if (new_state == NM_DEVICE_STATE_FAILED)
 				warn = FALSE;
-			dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
-			                         "Disconnect",
-			                         disconnect_done,
-			                         GUINT_TO_POINTER (warn),
-			                         NULL,
-			                         G_TYPE_INVALID);
+			NM_MODEM_GET_CLASS (self)->disconnect (self, warn);
 		}
 		break;
 	default:
@@ -720,6 +595,8 @@ nm_modem_device_state_changed (NMModem *self,
 	}
 }
 
+/*****************************************************************************/
+
 gboolean
 nm_modem_hw_is_up (NMModem *self, NMDevice *device)
 {
@@ -736,6 +613,8 @@ nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware)
 	return ifindex > 0 ? nm_system_iface_set_up (ifindex, TRUE, no_firmware) : TRUE;
 }
 
+/*****************************************************************************/
+
 const char *
 nm_modem_get_iface (NMModem *self)
 {
@@ -754,129 +633,11 @@ nm_modem_get_path (NMModem *self)
 	return NM_MODEM_GET_PRIVATE (self)->path;
 }
 
-static void
-get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
-	NMModem *self = NM_MODEM (user_data);
-	GError *error = NULL;
-	GValue value = { 0, };
-
-	if (!dbus_g_proxy_end_call (proxy, call_id, &error,
-	                            G_TYPE_VALUE, &value,
-	                            G_TYPE_INVALID)) {
-		nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-		return;
-	}
-
-	if (G_VALUE_HOLDS_BOOLEAN (&value)) {
-		update_mm_enabled (self, g_value_get_boolean (&value));
-	} else
-		nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type");
-
-	g_value_unset (&value);
-}
-
-static void
-query_mm_enabled (NMModem *self)
-{
-	dbus_g_proxy_begin_call (NM_MODEM_GET_PRIVATE (self)->props_proxy,
-	                         "Get", get_mm_enabled_done,
-	                         self, NULL,
-	                         G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
-	                         G_TYPE_STRING, "Enabled",
-	                         G_TYPE_INVALID);
-}
-
-static void
-set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
-	GError *error = NULL;
-
-	if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
-		nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-	}
-
-	/* Update enabled/disabled state again */
-	query_mm_enabled (NM_MODEM (user_data));
-}
-
-void
-nm_modem_set_mm_enabled (NMModem *self, gboolean enabled)
-{
-	NMModemPrivate *priv;
-
-	g_return_if_fail (self != NULL);
-	g_return_if_fail (NM_IS_MODEM (self));
-
-	priv = NM_MODEM_GET_PRIVATE (self);
-
-	/* FIXME: For now this just toggles the ModemManager enabled state.  In the
-	 * future we want to tie this into rfkill state instead so that the user can
-	 * toggle rfkill status of the WWAN modem.
-	 */
-
-	if (priv->mm_enabled != enabled) {
-		DBusGProxy *proxy;
-
-		proxy = nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM);
-		dbus_g_proxy_begin_call (proxy,
-		                         "Enable", set_mm_enabled_done,
-		                         self, NULL,
-		                         G_TYPE_BOOLEAN, enabled,
-		                         G_TYPE_INVALID);
-		/* If we are disabling the modem, stop saying that it's enabled. */
-		if (!enabled)
-			update_mm_enabled (self, enabled);
-	}
-}
-
-static void
-modem_properties_changed (DBusGProxy *proxy,
-                          const char *interface,
-                          GHashTable *props,
-                          gpointer user_data)
-{
-	NMModem *self = NM_MODEM (user_data);
-	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
-	GValue *value;
-	NMModemState new_state;
-
-	if (strcmp (interface, MM_DBUS_INTERFACE_MODEM))
-		return;
-
-	value = g_hash_table_lookup (props, "Enabled");
-	if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
-		update_mm_enabled (self, g_value_get_boolean (value));
-	}
-
-	value = g_hash_table_lookup (props, "IpMethod");
-	if (value && G_VALUE_HOLDS_UINT (value)) {
-		priv->ip_method = g_value_get_uint (value);
-		g_object_notify (G_OBJECT (self), NM_MODEM_IP_METHOD);
-	}
-
-	value = g_hash_table_lookup (props, "State");
-	if (value && G_VALUE_HOLDS_UINT (value)) {
-		new_state = g_value_get_uint (value);
-		if (new_state != priv->state) {
-			priv->state = new_state;
-			g_object_notify (G_OBJECT (self), NM_MODEM_STATE);
-		}
-	}
-}
-
 /*****************************************************************************/
 
 static void
 nm_modem_init (NMModem *self)
 {
-	NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
-
-	priv->dbus_mgr = nm_dbus_manager_get ();
 }
 
 static GObject*
@@ -886,7 +647,6 @@ constructor (GType type,
 {
 	GObject *object;
 	NMModemPrivate *priv;
-	DBusGConnection *bus;
 
 	object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type,
 																  n_construct_params,
@@ -911,30 +671,6 @@ constructor (GType type,
 		goto err;
 	}
 
-	bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
-	priv->proxy = dbus_g_proxy_new_for_name (bus,
-	                                         MM_DBUS_SERVICE,
-	                                         priv->path,
-	                                         MM_DBUS_INTERFACE_MODEM);
-
-	priv->props_proxy = dbus_g_proxy_new_for_name (bus,
-	                                               MM_DBUS_SERVICE,
-	                                               priv->path,
-	                                               DBUS_INTERFACE_PROPERTIES);
-	dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
-	                                   G_TYPE_NONE,
-	                                   G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
-	                                   G_TYPE_INVALID);
-	dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged",
-	                         G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
-	                         G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged",
-	                             G_CALLBACK (modem_properties_changed),
-	                             object,
-	                             NULL);
-
-	query_mm_enabled (NM_MODEM (object));
-
 	return object;
 
  err:
@@ -1003,6 +739,7 @@ set_property (GObject *object, guint prop_id,
 		priv->mm_ip_timeout = g_value_get_uint (value);
 		break;
 	case PROP_ENABLED:
+		priv->mm_enabled = g_value_get_boolean (value);
 		break;
 	case PROP_STATE:
 		priv->state = g_value_get_uint (value);
@@ -1023,21 +760,6 @@ dispose (GObject *object)
 		priv->act_request = NULL;
 	}
 
-	if (priv->proxy) {
-		g_object_unref (priv->proxy);
-		priv->proxy = NULL;
-	}
-
-	if (priv->props_proxy) {
-		g_object_unref (priv->props_proxy);
-		priv->props_proxy = NULL;
-	}
-
-	if (priv->dbus_mgr) {
-		g_object_unref (priv->dbus_mgr);
-		priv->dbus_mgr = NULL;
-	}
-
 	G_OBJECT_CLASS (nm_modem_parent_class)->dispose (object);
 }
 
@@ -1071,6 +793,7 @@ nm_modem_class_init (NMModemClass *klass)
 	klass->deactivate = deactivate;
 
 	/* Properties */
+
 	g_object_class_install_property
 		(object_class, PROP_PATH,
 		 g_param_spec_string (NM_MODEM_PATH,
@@ -1103,7 +826,7 @@ nm_modem_class_init (NMModemClass *klass)
 							MM_MODEM_IP_METHOD_PPP,
 							MM_MODEM_IP_METHOD_DHCP,
 							MM_MODEM_IP_METHOD_PPP,
-							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+							G_PARAM_READWRITE));
 
 	g_object_class_install_property
 		(object_class, PROP_IP_TIMEOUT,
@@ -1111,7 +834,7 @@ nm_modem_class_init (NMModemClass *klass)
 		                    "IP timeout",
 		                    "IP timeout",
 		                    0, 360, 20,
-		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+		                    G_PARAM_READWRITE));
 
 	g_object_class_install_property
 		(object_class, PROP_ENABLED,
@@ -1119,7 +842,7 @@ nm_modem_class_init (NMModemClass *klass)
 		                       "Enabled",
 		                       "Enabled",
 		                       TRUE,
-		                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
+		                       G_PARAM_READWRITE));
 
 	g_object_class_install_property
 		(object_class, PROP_STATE,
@@ -1132,6 +855,7 @@ nm_modem_class_init (NMModemClass *klass)
 		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	/* Signals */
+
 	signals[PPP_STATS] =
 		g_signal_new ("ppp-stats",
 					  G_OBJECT_CLASS_TYPE (object_class),
@@ -1187,4 +911,3 @@ nm_modem_class_init (NMModemClass *klass)
 					  g_cclosure_marshal_VOID__POINTER,
 					  G_TYPE_NONE, 1, G_TYPE_POINTER);
 }
-
diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h
index 483dec1..1b6c6d8 100644
--- a/src/modem-manager/nm-modem.h
+++ b/src/modem-manager/nm-modem.h
@@ -67,6 +67,9 @@ typedef enum {
     NM_MODEM_STATE_LAST = NM_MODEM_STATE_CONNECTED
 } NMModemState;
 
+#define MM_MODEM_IP_METHOD_PPP    0
+#define MM_MODEM_IP_METHOD_STATIC 1
+#define MM_MODEM_IP_METHOD_DHCP   2
 
 typedef struct {
 	GObject parent;
@@ -101,6 +104,14 @@ typedef struct {
 	                                            const char **out_setting_name,
 	                                            NMDeviceStateReason *reason);
 
+	NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self,
+	                                                    NMActRequest *req,
+	                                                    NMDeviceStateReason *reason);
+
+	void (*set_mm_enabled)                     (NMModem *self, gboolean enabled);
+
+	void (*disconnect)                         (NMModem *self, gboolean warn);
+
 	void (*deactivate)                         (NMModem *self, NMDevice *device);
 
 	/* Signals */
@@ -116,9 +127,6 @@ typedef struct {
 
 GType nm_modem_get_type (void);
 
-/* Protected */
-
-DBusGProxy *  nm_modem_get_proxy       (NMModem *modem, const char *interface);
 const char *  nm_modem_get_iface       (NMModem *modem);
 const char *  nm_modem_get_path        (NMModem *modem);
 
-- 
1.7.11.7



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]