diff --git a/ChangeLog b/ChangeLog index f785715185..1ec9572133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2008-06-10 Dan Williams + + Patch from Tambet Ingo + + * src/ppp-manager/nm-ppp-manager.c: Add ppp stats monitoring, signal the + changes. + + * src/nm-serial-device.c: Monitor "ppp-stats" signals from NMPPPManager. Add + a signal to emit these changes over dbus. + + * src/Makefile.am: Genereate nm-serial-device-glue. + + * libnm-glib/nm-serial-device.[ch]: Implement. + + * libnm-glib/nm-cdma-device.[ch] + libnm-glib/nm-gsm-device.[ch]: Inherit from NMSerialDevice. + + * libnm-glib/Makefile.am: Add nm-serial-device.[ch]. + + * introspection/nm-device-serial.xml: Implement. + + * introspection/all.xml: Fix a couple of typos, add nm-device-serial.xml. + + * introspection/Makefile.am: Add nm-device-serial.xml. + + * include/NetworkManager.h: Add a DBus interface for serial device. + 2008-06-10 Dan Williams * configure.in diff --git a/include/NetworkManager.h b/include/NetworkManager.h index b39a1186f9..59c685ae30 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -34,6 +34,7 @@ #define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless" #define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" #define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" +#define NM_DBUS_INTERFACE_SERIAL_DEVICE NM_DBUS_INTERFACE_DEVICE ".Serial" #define NM_DBUS_INTERFACE_GSM_DEVICE NM_DBUS_INTERFACE_DEVICE ".Gsm" #define NM_DBUS_INTERFACE_CDMA_DEVICE NM_DBUS_INTERFACE_DEVICE ".Cdma" #define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active" diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 143af0c1b6..10d0fc1461 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -4,6 +4,7 @@ EXTRA_DIST = \ nm-device-802-3-ethernet.xml \ nm-device-cdma.xml \ nm-device-gsm.xml \ + nm-device-serial.xml \ nm-device.xml \ nm-ip4-config.xml \ nm-manager.xml \ diff --git a/introspection/all.xml b/introspection/all.xml index 654f7cce99..ec2752187e 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -30,8 +30,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - + + + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index bce2dbbdad..973b59e343 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -41,6 +41,7 @@ libnminclude_HEADERS = \ nm-settings.h \ nm-gsm-device.h \ nm-cdma-device.h \ + nm-serial-device.h \ nm-vpn-connection.h \ nm-vpn-plugin.h \ nm-types.h \ @@ -65,6 +66,7 @@ libnm_glib_la_SOURCES = \ nm-settings.c \ nm-gsm-device.c \ nm-cdma-device.c \ + nm-serial-device.c \ nm-vpn-connection.c \ nm-types.c \ nm-types-private.h \ diff --git a/libnm-glib/nm-cdma-device.c b/libnm-glib/nm-cdma-device.c index af337edeb3..9266707ecd 100644 --- a/libnm-glib/nm-cdma-device.c +++ b/libnm-glib/nm-cdma-device.c @@ -4,7 +4,7 @@ #include "nm-device-private.h" #include "nm-object-private.h" -G_DEFINE_TYPE (NMCdmaDevice, nm_cdma_device, NM_TYPE_DEVICE) +G_DEFINE_TYPE (NMCdmaDevice, nm_cdma_device, NM_TYPE_SERIAL_DEVICE) #define NM_CDMA_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CDMA_DEVICE, NMCdmaDevicePrivate)) diff --git a/libnm-glib/nm-cdma-device.h b/libnm-glib/nm-cdma-device.h index b65f9a4681..6b1c3e972f 100644 --- a/libnm-glib/nm-cdma-device.h +++ b/libnm-glib/nm-cdma-device.h @@ -3,7 +3,7 @@ #ifndef NM_CDMA_DEVICE_H #define NM_CDMA_DEVICE_H -#include "nm-device.h" +#include "nm-serial-device.h" G_BEGIN_DECLS @@ -15,11 +15,11 @@ G_BEGIN_DECLS #define NM_CDMA_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CDMA_DEVICE, NMCdmaDeviceClass)) typedef struct { - NMDevice parent; + NMSerialDevice parent; } NMCdmaDevice; typedef struct { - NMDeviceClass parent; + NMSerialDeviceClass parent; } NMCdmaDeviceClass; GType nm_cdma_device_get_type (void); diff --git a/libnm-glib/nm-gsm-device.c b/libnm-glib/nm-gsm-device.c index 9c71d58a5a..c3c28f46db 100644 --- a/libnm-glib/nm-gsm-device.c +++ b/libnm-glib/nm-gsm-device.c @@ -4,7 +4,7 @@ #include "nm-device-private.h" #include "nm-object-private.h" -G_DEFINE_TYPE (NMGsmDevice, nm_gsm_device, NM_TYPE_DEVICE) +G_DEFINE_TYPE (NMGsmDevice, nm_gsm_device, NM_TYPE_SERIAL_DEVICE) #define NM_GSM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_DEVICE, NMGsmDevicePrivate)) diff --git a/libnm-glib/nm-gsm-device.h b/libnm-glib/nm-gsm-device.h index 09cc1e88a9..eda36cfead 100644 --- a/libnm-glib/nm-gsm-device.h +++ b/libnm-glib/nm-gsm-device.h @@ -3,7 +3,7 @@ #ifndef NM_GSM_DEVICE_H #define NM_GSM_DEVICE_H -#include "nm-device.h" +#include "nm-serial-device.h" G_BEGIN_DECLS @@ -15,11 +15,11 @@ G_BEGIN_DECLS #define NM_GSM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_GSM_DEVICE, NMGsmDeviceClass)) typedef struct { - NMDevice parent; + NMSerialDevice parent; } NMGsmDevice; typedef struct { - NMDeviceClass parent; + NMSerialDeviceClass parent; } NMGsmDeviceClass; GType nm_gsm_device_get_type (void); diff --git a/src/Makefile.am b/src/Makefile.am index 494e8d2bf6..8a19e3f896 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,6 +87,9 @@ nm-device-802-3-ethernet-glue.h: $(top_srcdir)/introspection/nm-device-802-3-eth nm-device-802-11-wireless-glue.h: $(top_srcdir)/introspection/nm-device-802-11-wireless.xml dbus-binding-tool --prefix=nm_device_802_11_wireless --mode=glib-server --output=nm-device-802-11-wireless-glue.h $(top_srcdir)/introspection/nm-device-802-11-wireless.xml +nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml + dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=nm-serial-device-glue.h $(top_srcdir)/introspection/nm-device-serial.xml + nm-cdma-device-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml dbus-binding-tool --prefix=nm_cdma_device --mode=glib-server --output=nm-cdma-device-glue.h $(top_srcdir)/introspection/nm-device-cdma.xml @@ -105,6 +108,7 @@ built_sources = \ nm-device-interface-glue.h \ nm-device-802-3-ethernet-glue.h \ nm-device-802-11-wireless-glue.h \ + nm-serial-device-glue.h \ nm-cdma-device-glue.h \ nm-gsm-device-glue.h \ nm-ip4-config-glue.h \ diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c index 4e84dac81b..319e7b0f4d 100644 --- a/src/nm-serial-device.c +++ b/src/nm-serial-device.c @@ -17,7 +17,9 @@ #include "nm-device-private.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-setting-ppp.h" +#include "nm-marshal.h" #include "nm-utils.h" +#include "nm-serial-device-glue.h" /* #define NM_DEBUG_SERIAL 1 */ @@ -33,8 +35,20 @@ typedef struct { NMPPPManager *ppp_manager; NMIP4Config *pending_ip4_config; struct termios old_t; + + /* PPP stats */ + guint32 in_bytes; + guint32 out_bytes; } NMSerialDevicePrivate; +enum { + PPP_STATS, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + static int parse_baudrate (guint i) { @@ -941,6 +955,23 @@ ppp_ip4_config (NMPPPManager *ppp_manager, nm_device_activate_schedule_stage4_ip_config_get (device); } +static void +ppp_stats (NMPPPManager *ppp_manager, + guint32 in_bytes, + guint32 out_bytes, + gpointer user_data) +{ + NMSerialDevice *device = NM_SERIAL_DEVICE (user_data); + NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + + if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { + priv->in_bytes = in_bytes; + priv->out_bytes = out_bytes; + + g_signal_emit (device, signals[PPP_STATS], 0, in_bytes, out_bytes); + } +} + static NMActStageReturn real_act_stage2_config (NMDevice *device) { @@ -964,6 +995,10 @@ real_act_stage2_config (NMDevice *device) g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), device); + g_signal_connect (priv->ppp_manager, "stats", + G_CALLBACK (ppp_stats), + device); + ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { nm_warning ("%s", err->message); @@ -1002,6 +1037,8 @@ real_deactivate_quickly (NMDevice *device) priv->pending_ip4_config = NULL; } + priv->in_bytes = priv->out_bytes = 0; + if (priv->ppp_manager) { g_object_unref (priv->ppp_manager); priv->ppp_manager = NULL; @@ -1048,4 +1085,18 @@ nm_serial_device_class_init (NMSerialDeviceClass *klass) parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; parent_class->deactivate_quickly = real_deactivate_quickly; + + /* Signals */ + signals[PPP_STATS] = + g_signal_new ("ppp-stats", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSerialDeviceClass, ppp_stats), + NULL, NULL, + nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_serial_device_object_info); } diff --git a/src/nm-serial-device.h b/src/nm-serial-device.h index b6f8134d8e..49644b61ad 100644 --- a/src/nm-serial-device.h +++ b/src/nm-serial-device.h @@ -21,6 +21,9 @@ typedef struct { typedef struct { NMDeviceClass parent; + + /* Signals */ + void (*ppp_stats) (NMSerialDevice *device, guint32 in_bytes, guint32 out_bytes); } NMSerialDeviceClass; GType nm_serial_device_get_type (void); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 9910f723ad..78ec76bc04 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -7,6 +7,18 @@ #include #include +#include +#include +#include +#include +#include + +#include +#ifndef aligned_u64 +#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#endif +#include + #include "nm-ppp-manager.h" #include "nm-setting-connection.h" #include "nm-setting-ppp.h" @@ -41,6 +53,11 @@ typedef struct { guint32 ppp_watch_id; guint32 ppp_timeout_handler; + + /* Monitoring */ + char *iface; + int monitor_fd; + guint monitor_id; } NMPPPManagerPrivate; #define NM_PPP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_PPP_MANAGER, NMPPPManagerPrivate)) @@ -50,6 +67,7 @@ G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, G_TYPE_OBJECT) enum { STATE_CHANGED, IP4_CONFIG, + STATS, LAST_SIGNAL }; @@ -163,6 +181,16 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_OBJECT); + + signals[STATS] = + g_signal_new ("stats", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, stats), + NULL, NULL, + nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); } NMPPPManager * @@ -173,6 +201,42 @@ nm_ppp_manager_new (void) /*******************************************/ +static gboolean +monitor_cb (gpointer user_data) +{ + NMPPPManager *manager = NM_PPP_MANAGER (user_data); + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + struct ifpppstatsreq req; + + memset (&req, 0, sizeof (req)); + req.stats_ptr = (caddr_t) &req.stats; + + strncpy (req.ifr__name, priv->iface, sizeof (req.ifr__name)); + if (!ioctl (priv->monitor_fd, SIOCGPPPSTATS, &req) < 0) + nm_warning ("Could not read ppp stats: %s", strerror (errno)); + else + g_signal_emit (manager, signals[STATS], 0, + req.stats.p.ppp_ibytes, + req.stats.p.ppp_obytes); + + return TRUE; +} + +static void +monitor_stats (NMPPPManager *manager, const char *iface) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + + priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); + if (priv->monitor_fd > 0) { + priv->iface = g_strdup (iface); + priv->monitor_id = g_timeout_add (5000, monitor_cb, manager); + } else + nm_warning ("Could not open pppd monitor: %s", strerror (errno)); +} + +/*******************************************/ + static void remove_timeout_handler (NMPPPManager *manager) { @@ -292,6 +356,8 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, g_signal_emit (manager, signals[IP4_CONFIG], 0, iface, config); + monitor_stats (manager, iface); + out: g_object_unref (config); @@ -753,6 +819,20 @@ nm_ppp_manager_stop (NMPPPManager *manager) priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + if (priv->monitor_id) { + g_source_remove (priv->monitor_id); + priv->monitor_id = 0; + } + + if (priv->monitor_fd) { + /* Get the stats one last time */ + monitor_cb (manager); + close (priv->monitor_fd); + priv->monitor_fd = 0; + } + + g_free (priv->iface); + if (priv->ppp_timeout_handler) { g_source_remove (priv->ppp_timeout_handler); priv->ppp_timeout_handler = 0; diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 7a9baafd7d..38fd1e3e5e 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -29,6 +29,7 @@ typedef struct { /* Signals */ void (*state_changed) (NMPPPManager *manager, NMPPPStatus status); void (*ip4_config) (NMPPPManager *manager, const char *iface, NMIP4Config *config); + void (*stats) (NMPPPManager *manager, guint32 in_bytes, guint32 out_bytes); } NMPPPManagerClass; GType nm_ppp_manager_get_type (void);