This is the "juice" of the patch series. Initial cut at carrier handling
(by polling /sys/class/atm/$iface/carrier) and also support for calling
pppd with the proper command-line to achieve a connection.

Also implement the necessary boilerplate for the NM state machine to
be happy with our device.

With this patch, you can already test carrier management but not yet
make a complete connection.

Relevant extract from logs:
<info> (ueagle-atm0): carrier now ON (device state 20)
<info> (ueagle-atm0): device state change: unavailable -> disconnected (reason 
'carrier-chagned') [20 30 40]

Signed-off-by: Pantelis Koukousoulas <pkt...@gmail.com>
---
 include/NetworkManager.h         |    1 +
 src/nm-device-adsl.c             |  519 +++++++++++++++++++++++++++++++++++++-
 src/nm-device-adsl.h             |    5 +-
 src/ppp-manager/nm-ppp-manager.c |   31 +++-
 src/settings/nm-settings.c       |    2 +
 5 files changed, 553 insertions(+), 5 deletions(-)

diff --git a/include/NetworkManager.h b/include/NetworkManager.h
index b007e1c..cfc61ee 100644
--- a/include/NetworkManager.h
+++ b/include/NetworkManager.h
@@ -34,6 +34,7 @@
 #define        NM_DBUS_INTERFACE                   
"org.freedesktop.NetworkManager"
 #define        NM_DBUS_INTERFACE_DEVICE            NM_DBUS_INTERFACE ".Device"
 #define NM_DBUS_INTERFACE_DEVICE_WIRED      NM_DBUS_INTERFACE_DEVICE ".Wired"
+#define NM_DBUS_INTERFACE_DEVICE_ADSL       NM_DBUS_INTERFACE_DEVICE ".Adsl"
 #define NM_DBUS_INTERFACE_DEVICE_WIRELESS   NM_DBUS_INTERFACE_DEVICE 
".Wireless"
 #define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH  NM_DBUS_INTERFACE_DEVICE 
".Bluetooth"
 #define NM_DBUS_PATH_ACCESS_POINT           NM_DBUS_PATH "/AccessPoint"
diff --git a/src/nm-device-adsl.c b/src/nm-device-adsl.c
index 212fec1..77e4d0a 100644
--- a/src/nm-device-adsl.c
+++ b/src/nm-device-adsl.c
@@ -1,5 +1,6 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
+/*
+ * Pantelis Koukousoulas <pkt...@gmail.com>
  *
  * 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
@@ -15,26 +16,153 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Pantelis Koukousoulas <pkt...@gmail.com>
  */
 
 #include <glib.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "nm-glib-compat.h"
 #include "nm-device-adsl.h"
 #include "nm-device-interface.h"
+#include "nm-device-private.h"
 #include "nm-properties-changed-signal.h"
+#include "nm-glib-compat.h"
+#include "NetworkManagerUtils.h"
+#include "nm-logging.h"
+
+#include "ppp-manager/nm-ppp-manager.h"
+#include "nm-setting-adsl.h"
 
 #include "nm-device-adsl-glue.h"
 
 G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE)
 
+#define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate))
+
+typedef enum
+{
+       NM_ADSL_ERROR_CONNECTION_NOT_ADSL = 0,
+       NM_ADSL_ERROR_CONNECTION_INVALID,
+       NM_ADSL_ERROR_CONNECTION_INCOMPATIBLE,
+} NMAdslError;
+
+#define NM_ADSL_ERROR (nm_adsl_error_quark ())
+#define NM_TYPE_ADSL_ERROR (nm_adsl_error_get_type ())
+
+static GQuark
+nm_adsl_error_quark (void)
+{
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string ("nm-ethernet-error");
+       return quark;
+}
+
+typedef struct {
+       gboolean            disposed;
+       gboolean            carrier;
+       guint               carrier_poll_id;
+
+       /* PPP */
+       NMPPPManager *ppp_manager;
+       NMIP4Config  *pending_ip4_config;
+} NMDeviceAdslPrivate;
+
 enum {
        PROPERTIES_CHANGED,
        LAST_SIGNAL
 };
+
 static guint signals[LAST_SIGNAL] = { 0 };
 
+enum {
+       PROP_0,
+       PROP_CARRIER,
+
+       LAST_PROP
+};
+
+/* FIXME: Move it to nm-device.c and then get rid of all 
foo_device_get_setting() all around.
+   It's here now to keep the patch short. */
+static NMSetting *
+device_get_setting (NMDevice *device, GType setting_type)
+{
+       NMActRequest *req;
+       NMSetting *setting = NULL;
+
+       req = nm_device_get_act_request (device);
+       if (req) {
+               NMConnection *connection;
+
+               connection = nm_act_request_get_connection (req);
+               if (connection)
+                       setting = nm_connection_get_setting (connection, 
setting_type);
+       }
+
+       return setting;
+}
+
+static void
+set_carrier(NMDeviceAdsl *self, const gboolean carrier)
+{
+       NMDeviceAdslPrivate *priv;
+       NMDeviceState state;
+
+       g_return_if_fail (NM_IS_DEVICE (self));
+
+       priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+
+       if (priv->carrier == carrier)
+               return;
+
+       priv->carrier = carrier;
+       g_object_notify (G_OBJECT (self), NM_DEVICE_ADSL_CARRIER);
+
+       state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+       nm_log_info (LOGD_HW, "(%s): carrier now %s (device state %d)",
+                    nm_device_get_iface (NM_DEVICE (self)),
+                    carrier ? "ON" : "OFF",
+                    state);
+
+       if (state == NM_DEVICE_STATE_UNAVAILABLE) {
+               if (priv->carrier)
+                       nm_device_state_changed (NM_DEVICE (self), 
NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
+       } else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
+               if (!priv->carrier)
+                       nm_device_state_changed (NM_DEVICE (self), 
NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER);
+       }
+}
+
+static gboolean
+carrier_update_cb (gpointer user_data)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data);
+
+       gchar *contents = NULL;
+       GError *error = NULL;
+       gboolean carrier = FALSE;
+       const gchar *path, *iface;
+
+       iface = nm_device_get_iface (NM_DEVICE (self));
+       path  = g_strdup_printf("/sys/class/atm/%s/carrier", iface);
+
+       if (!g_file_get_contents(path, &contents, NULL, &error)) {
+               nm_log_dbg (LOGD_DEVICE, "error reading %s: (%d) %s",
+                           path,
+                           error ? error->code : -1,
+                           error && error->message ? error->message : 
"(unknown)");
+               g_clear_error (&error);
+               return TRUE;
+       }
+
+       carrier = (gboolean) atoi(contents);
+       set_carrier(self, carrier);
+
+       return TRUE;
+}
+
 
 NMDevice *
 nm_device_adsl_new (const char *udi,
@@ -52,6 +180,79 @@ nm_device_adsl_new (const char *udi,
                                          NULL);
 }
 
+static GObject*
+constructor (GType type,
+                        guint n_construct_params,
+                        GObjectConstructParam *construct_params)
+{
+       GObject *object;
+       NMDeviceAdslPrivate *priv;
+       NMDevice *self;
+
+       object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor 
(type,
+                                                                           
n_construct_params,
+                                                                           
construct_params);
+       if (!object)
+               return NULL;
+
+       self = NM_DEVICE (object);
+       priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+
+       priv->carrier = FALSE;
+       priv->carrier_poll_id = g_timeout_add_seconds(5, carrier_update_cb, 
self);
+
+       return object;
+}
+
+static void
+dispose (GObject *object)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (object);
+       NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+
+       if (priv->disposed) {
+               G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object);
+               return;
+       }
+
+       priv->disposed = TRUE;
+
+       if (priv->carrier_poll_id) {
+               g_source_remove(priv->carrier_poll_id);
+               priv->carrier_poll_id = 0;
+       }
+
+
+       G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+              GValue *value, GParamSpec *pspec)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (object);
+       NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self);
+
+       switch (prop_id) {
+       case PROP_CARRIER:
+               g_value_set_boolean (value, priv->carrier);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+                         const GValue *value, GParamSpec *pspec)
+{
+       switch (prop_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
 
 static void
 nm_device_adsl_init (NMDeviceAdsl * self)
@@ -62,7 +263,291 @@ nm_device_adsl_init (NMDeviceAdsl * self)
 static guint32
 real_get_generic_capabilities (NMDevice *dev)
 {
-       return NM_DEVICE_CAP_NM_SUPPORTED;
+       guint32 caps = NM_DEVICE_CAP_NM_SUPPORTED;
+       caps |= NM_DEVICE_CAP_CARRIER_DETECT;
+       return caps;
+}
+
+static gboolean
+real_can_interrupt_activation (NMDevice *dev)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (dev);
+       gboolean interrupt = FALSE;
+
+       /* Devices that support carrier detect can interrupt activation
+        * if the link becomes inactive.
+        */
+       if (NM_DEVICE_ADSL_GET_PRIVATE (self)->carrier == FALSE)
+               interrupt = TRUE;
+
+       return interrupt;
+}
+
+static gboolean
+real_is_available (NMDevice *dev)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (dev);
+
+       /* Can't do anything if there isn't a carrier */
+       if (!NM_DEVICE_ADSL_GET_PRIVATE (self)->carrier)
+               return FALSE;
+
+       return TRUE;
+}
+
+static gboolean
+real_check_connection_compatible (NMDevice *device,
+                                  NMConnection *connection,
+                                  GError **error)
+{
+       NMSettingConnection *s_con;
+       NMSettingAdsl *s_adsl;
+       const char *connection_type;
+
+       s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, 
NM_TYPE_SETTING_CONNECTION));
+       g_assert (s_con);
+
+       connection_type = nm_setting_connection_get_connection_type (s_con);
+       if (strcmp (connection_type, NM_SETTING_ADSL_SETTING_NAME)) {
+               g_set_error (error,
+                            NM_ADSL_ERROR, NM_ADSL_ERROR_CONNECTION_NOT_ADSL,
+                            "The connection was not an ADSL connection.");
+               return FALSE;
+       }
+
+       s_adsl = (NMSettingAdsl *) nm_connection_get_setting (connection, 
NM_TYPE_SETTING_ADSL);
+       /* Wired setting is optional for PPPoE */
+       if (!s_adsl) {
+               g_set_error (error,
+                            NM_ADSL_ERROR, NM_ADSL_ERROR_CONNECTION_INVALID,
+                            "The connection was not a valid ADSL connection.");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+real_complete_connection (NMDevice *device,
+                          NMConnection *connection,
+                          const char *specific_object,
+                          const GSList *existing_connections,
+                          GError **error)
+{
+       NMSettingAdsl *s_adsl;
+
+       s_adsl = (NMSettingAdsl *) nm_connection_get_setting (connection, 
NM_TYPE_SETTING_ADSL);
+
+       /*
+        * We can't telepathically figure out the username, so if
+        * it wasn't given, we can't complete the connection.
+        */
+       if (s_adsl && !nm_setting_verify (NM_SETTING (s_adsl), NULL, error))
+               return FALSE;
+
+       nm_utils_complete_generic (connection,
+                                  NM_SETTING_ADSL_SETTING_NAME,
+                                  existing_connections,
+                                  _("ADSL connection %d"),
+                                  NULL,
+                                  FALSE); /* No IPv6 yet by default */
+
+
+       return TRUE;
+}
+
+static void
+real_deactivate (NMDevice *device)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
+       NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+
+       if (priv->pending_ip4_config) {
+               g_object_unref (priv->pending_ip4_config);
+               priv->pending_ip4_config = NULL;
+       }
+
+       if (priv->ppp_manager) {
+               g_object_unref (priv->ppp_manager);
+               priv->ppp_manager = NULL;
+       }
+}
+
+static NMConnection *
+real_get_best_auto_connection (NMDevice *dev,
+                               GSList *connections,
+                               char **specific_object)
+{
+       GSList *iter;
+
+       for (iter = connections; iter; iter = g_slist_next (iter)) {
+               NMConnection *connection = NM_CONNECTION (iter->data);
+               NMSettingConnection *s_con;
+               NMSettingAdsl *s_adsl;
+               const char *connection_type;
+
+               s_con = (NMSettingConnection *) nm_connection_get_setting 
(connection, NM_TYPE_SETTING_CONNECTION);
+               g_assert (s_con);
+
+               connection_type = nm_setting_connection_get_connection_type 
(s_con);
+               if (strcmp (connection_type, NM_SETTING_ADSL_SETTING_NAME))
+                       continue;
+
+               s_adsl = (NMSettingAdsl *) nm_connection_get_setting 
(connection, NM_TYPE_SETTING_ADSL);
+               if (!s_adsl)
+                       continue;
+
+               if (!nm_setting_connection_get_autoconnect (s_con))
+                       continue;
+
+               return connection;
+       }
+       return NULL;
+}
+
+static NMActStageReturn
+real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
+{
+       NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (dev);
+       NMActRequest *req;
+       NMSettingAdsl *s_adsl;
+
+       g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+
+       req = nm_device_get_act_request (NM_DEVICE (self));
+       g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+
+       s_adsl = NM_SETTING_ADSL (device_get_setting (dev, 
NM_TYPE_SETTING_ADSL));
+       g_assert (s_adsl);
+
+       return ret;
+}
+
+static NMActStageReturn
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
+{
+       NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
+       return ret;
+}
+
+static void
+ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer 
user_data)
+{
+       NMDevice *device = NM_DEVICE (user_data);
+
+       switch (status) {
+       case NM_PPP_STATUS_DISCONNECT:
+               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, 
NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
+               break;
+       case NM_PPP_STATUS_DEAD:
+               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, 
NM_DEVICE_STATE_REASON_PPP_FAILED);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+ppp_ip4_config (NMPPPManager *ppp_manager,
+                        const char *iface,
+                        NMIP4Config *config,
+                        gpointer user_data)
+{
+       NMDevice *device = NM_DEVICE (user_data);
+
+       /* Ignore PPP IP4 events that come in after initial configuration */
+       if (nm_device_get_state (device) != NM_DEVICE_STATE_IP_CONFIG)
+               return;
+
+       nm_device_set_ip_iface (device, iface);
+       NM_DEVICE_ADSL_GET_PRIVATE (device)->pending_ip4_config = g_object_ref 
(config);
+       nm_device_activate_schedule_stage4_ip4_config_get (device);
+}
+
+static NMActStageReturn
+pppoa_stage3_ip4_config_start (NMDeviceAdsl *self, NMDeviceStateReason *reason)
+{
+       NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+       NMConnection *connection;
+       NMSettingAdsl *s_adsl;
+       NMActRequest *req;
+       GError *err = NULL;
+       NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
+
+       req = nm_device_get_act_request (NM_DEVICE (self));
+       g_assert (req);
+
+       connection = nm_act_request_get_connection (req);
+       g_assert (req);
+
+       s_adsl = (NMSettingAdsl *) nm_connection_get_setting (connection, 
NM_TYPE_SETTING_ADSL);
+       g_assert (s_adsl);
+
+       priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE 
(self)));
+       if (nm_ppp_manager_start (priv->ppp_manager, req, 
nm_setting_adsl_get_username (s_adsl), 30, &err)) {
+               g_signal_connect (priv->ppp_manager, "state-changed",
+                                          G_CALLBACK (ppp_state_changed),
+                                          self);
+               g_signal_connect (priv->ppp_manager, "ip4-config",
+                                          G_CALLBACK (ppp_ip4_config),
+                                          self);
+               ret = NM_ACT_STAGE_RETURN_POSTPONE;
+       } else {
+               nm_log_warn (LOGD_DEVICE, "(%s): ADSL(PPPoA) failed to start: 
%s",
+                            nm_device_get_iface (NM_DEVICE (self)), 
err->message);
+               g_error_free (err);
+
+               g_object_unref (priv->ppp_manager);
+               priv->ppp_manager = NULL;
+
+               *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
+       }
+
+       return ret;
+}
+
+static NMActStageReturn
+real_act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason 
*reason)
+{
+       NMSettingConnection *s_con;
+       const char *connection_type;
+
+       g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+
+       s_con = NM_SETTING_CONNECTION (device_get_setting (device, 
NM_TYPE_SETTING_CONNECTION));
+       g_assert (s_con);
+
+       connection_type = nm_setting_connection_get_connection_type (s_con);
+
+       return pppoa_stage3_ip4_config_start (NM_DEVICE_ADSL (device), reason);
+}
+
+static NMActStageReturn
+real_act_stage4_get_ip4_config (NMDevice *device,
+                                NMIP4Config **config,
+                                NMDeviceStateReason *reason)
+{
+       NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
+       NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
+       NMConnection *connection;
+       NMSettingIP4Config *s_ip4;
+
+       g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+       g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
+       g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
+
+       /* PPP */
+       *config = priv->pending_ip4_config;
+       priv->pending_ip4_config = NULL;
+
+       /* Merge user-defined overrides into the IP4Config to be applied */
+       connection = nm_act_request_get_connection (nm_device_get_act_request 
(device));
+       g_assert (connection);
+       s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, 
NM_TYPE_SETTING_IP4_CONFIG);
+       nm_utils_merge_ip4_config (*config, s_ip4);
+
+       return NM_ACT_STAGE_RETURN_SUCCESS;
 }
 
 static void
@@ -71,7 +556,35 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass)
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
 
+       g_type_class_add_private (object_class, sizeof (NMDeviceAdslPrivate));
+
+       object_class->constructor  = constructor;
+       object_class->dispose      = dispose;
+       object_class->get_property = get_property;
+       object_class->set_property = set_property;
+
        parent_class->get_generic_capabilities = real_get_generic_capabilities;
+       parent_class->can_interrupt_activation = real_can_interrupt_activation;
+       parent_class->is_available = real_is_available;
+
+       parent_class->check_connection_compatible = 
real_check_connection_compatible;
+       parent_class->get_best_auto_connection = real_get_best_auto_connection;
+       parent_class->complete_connection = real_complete_connection;
+
+       parent_class->act_stage1_prepare = real_act_stage1_prepare;
+       parent_class->act_stage2_config = real_act_stage2_config;
+       parent_class->act_stage3_ip4_config_start = 
real_act_stage3_ip4_config_start;
+       parent_class->act_stage4_get_ip4_config = 
real_act_stage4_get_ip4_config;
+       parent_class->deactivate = real_deactivate;
+
+       /* properties */
+       g_object_class_install_property
+               (object_class, PROP_CARRIER,
+                g_param_spec_boolean (NM_DEVICE_ADSL_CARRIER,
+                                                          "Carrier",
+                                                          "Carrier",
+                                                          FALSE,
+                                                          G_PARAM_READABLE));
 
        /* Signals */
        signals[PROPERTIES_CHANGED] =
diff --git a/src/nm-device-adsl.h b/src/nm-device-adsl.h
index 42c5bc9..fe51a6a 100644
--- a/src/nm-device-adsl.h
+++ b/src/nm-device-adsl.h
@@ -15,7 +15,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Pantelis Koukousoulas <pkt...@gmail.com>
+ * Author: Pantelis Koukousoulas <pkt...@gmail.com>
+ * Copyright (C) 2009 - 2011 Red Hat Inc.
  */
 
 #ifndef NM_DEVICE_ADSL_H
@@ -35,6 +36,8 @@ G_BEGIN_DECLS
 #define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
NM_TYPE_DEVICE_ADSL))
 #define NM_DEVICE_ADSL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass))
 
+#define NM_DEVICE_ADSL_CARRIER "carrier"
+
 typedef struct {
        NMDevice parent;
 } NMDeviceAdsl;
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 767b931..4de3e80 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -47,6 +47,7 @@
 #include "nm-setting-connection.h"
 #include "nm-setting-ppp.h"
 #include "nm-setting-pppoe.h"
+#include "nm-setting-adsl.h"
 #include "nm-setting-gsm.h"
 #include "nm-setting-cdma.h"
 #include "nm-dbus-manager.h"
@@ -391,6 +392,9 @@ extract_details_from_connection (NMConnection *connection,
        if (NM_IS_SETTING_PPPOE (setting)) {
                *username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE 
(setting));
                *password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE 
(setting));
+       } else if (NM_IS_SETTING_ADSL (setting)) {
+               *username = nm_setting_adsl_get_username (NM_SETTING_ADSL 
(setting));
+               *password = nm_setting_adsl_get_password (NM_SETTING_ADSL 
(setting));
        } else if (NM_IS_SETTING_GSM (setting)) {
                *username = nm_setting_gsm_get_username (NM_SETTING_GSM 
(setting));
                *password = nm_setting_gsm_get_password (NM_SETTING_GSM 
(setting));
@@ -792,6 +796,7 @@ static NMCmdLine *
 create_pppd_cmd_line (NMPPPManager *self,
                       NMSettingPPP *setting, 
                       NMSettingPPPOE *pppoe,
+                      NMSettingAdsl  *adsl_pppoa,
                       const char *ppp_name,
                       GError **err)
 {
@@ -844,6 +849,27 @@ create_pppd_cmd_line (NMPPPManager *self,
                        nm_cmd_line_add_string (cmd, "rp_pppoe_service");
                        nm_cmd_line_add_string (cmd, pppoe_service);
                }
+       } else if (adsl_pppoa) {
+               const char *vpi;
+               const char *vci;
+               const gchar *encapsulation;
+               gchar *vpivci;
+
+               vpi = nm_setting_adsl_get_vpi (adsl_pppoa);
+               vci = nm_setting_adsl_get_vci (adsl_pppoa);
+               encapsulation = nm_setting_adsl_get_encapsulation (adsl_pppoa);
+               vpivci = g_strdup_printf("%s.%s", vpi, vci);
+
+               nm_cmd_line_add_string (cmd, "plugin");
+               nm_cmd_line_add_string (cmd, "pppoatm.so");
+               nm_cmd_line_add_string (cmd, vpivci);
+
+               if (!g_ascii_strcasecmp(encapsulation, "llc"))
+                       nm_cmd_line_add_string (cmd, "llc-encaps");
+
+               nm_cmd_line_add_string (cmd, "noipdefault");
+
+               g_free (vpivci);
        } else {
                nm_cmd_line_add_string (cmd, priv->parent_iface);
                /* Don't send some random address as the local address */
@@ -965,6 +991,7 @@ nm_ppp_manager_start (NMPPPManager *manager,
        NMSettingPPP *s_ppp;
        gboolean s_ppp_created = FALSE;
        NMSettingPPPOE *pppoe_setting;
+       NMSettingAdsl *adsl_setting;
        NMCmdLine *ppp_cmd;
        char *cmd_str;
        struct stat st;
@@ -1006,7 +1033,9 @@ nm_ppp_manager_start (NMPPPManager *manager,
        if (pppoe_setting)
                pppoe_fill_defaults (s_ppp);
 
-       ppp_cmd = create_pppd_cmd_line (manager, s_ppp, pppoe_setting, 
ppp_name, err);
+       adsl_setting = (NMSettingAdsl *) nm_connection_get_setting (connection, 
NM_TYPE_SETTING_ADSL);
+
+       ppp_cmd = create_pppd_cmd_line (manager, s_ppp, pppoe_setting, 
adsl_setting, ppp_name, err);
        if (!ppp_cmd)
                goto out;
 
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 87fa4b6..78aa31c 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -49,6 +49,7 @@
 #include <nm-setting-serial.h>
 #include <nm-setting-vpn.h>
 #include <nm-setting-wired.h>
+#include <nm-setting-adsl.h>
 #include <nm-setting-wireless.h>
 #include <nm-setting-wireless-security.h>
 
@@ -1688,6 +1689,7 @@ nm_settings_class_init (NMSettingsClass *class)
        dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, 
NM_TYPE_SETTING_PPP_ERROR);
        dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, 
NM_TYPE_SETTING_PPPOE_ERROR);
        dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, 
NM_TYPE_SETTING_SERIAL_ERROR);
+       dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, 
NM_TYPE_SETTING_ADSL_ERROR);
        dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, 
NM_TYPE_SETTING_VPN_ERROR);
        dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, 
NM_TYPE_SETTING_WIRED_ERROR);
        dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, 
NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR);
-- 
1.7.4.1

_______________________________________________
networkmanager-list mailing list
networkmanager-list@gnome.org
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to