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

_______________________________________________
networkmanager-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to