diff --git a/ChangeLog b/ChangeLog index 8b45c0dd9..6c284a5c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,119 @@ +2007-11-28 Tambet Ingo + + Merge the beginnings of the new GSM card support. + + * src/ppp-manager/nm-ppp-manager.c (nm_ppp_manager_stop): Remove the + ppp watch source before killing pppd - If this happens from g_object_unref() + then the ppp manager is already destroyed by the time the watch callback runs. + + * src/nm-hal-manager.c: Add a device_type_name string to the device + creators, so that we can print a nice human readable string when a + device is added. + + * src/nm-umts-device.c (automatic_registration_get_network): Query + for the activated network, not much is done with the result thought. + + * src/nm-serial-device.c (nm_serial_device_get_reply): Implement. + (ppp_ip4_config): Change the device state to activated here for now. + (real_check_connection): Make sure the connection includes ppp setting. + + * libnm-glib/nm-client.c (get_device): Handle umts devices. + + * libnm-glib/Makefile.am: Add the new files to build. + + * libnm-glib/nm-umts-device.c: + * libnm-glib/nm-umts-device.h: Implement. + +2007-11-26 Tambet Ingo + + * src/nm-umts-device.c (automatic_registration_get_network): For now, dial + immediately, nm_serial_device_get_reply() isn't implemented correctly yet. + + * src/nm-serial-device.c (wait_for_reply_info_destroy): Don't try to remove + the timeout source - this function is only called when the timeout source has + been removed. + (nm_serial_device_wait_for_reply): Allocate the duplicate responses array + to be big enough to contain the terminating zero element as well. + The timeout argument is meant to be in seconds now. + (real_deactivate_quickly): Implement. + + * src/NetworkManager.conf: Allow root to own + "org.freedesktop.NetworkManager.PPP", deny it for everybody else. + + * libnm-util/nm-setting-umts.c: Network type and band properties are ints, + (not unsigned ints). + + * libnm-util/nm-setting-serial.c (nm_setting_serial_class_init): Fix a + small issue with parity bounds - capital letters have lower ascii codes + than lower case letters. + + * libnm-util/nm-connection.c (register_default_settings): Register serial + and umts settings. + +2007-11-22 Tambet Ingo + + Remove the "index" property from devices as not all device types have this. + + * include/NetworkManager.h (NM_DBUS_PATH_DEVICE): Remove. + + * src/nm-hal-manager.c (nm_get_device_index_from_hal): Remove. + (wired_device_creator): Get the device interface from hal to create the device. + (wireless_device_creator): Ditto. + + * src/nm-device.c (nm_device_init): Remove the index member. + (constructor): Remove the checks for index property, make interface property + a require constructor property. + Use the HAL udi for DBus path for devices. + (nm_device_get_index): Remove. + (set_property): Remove index handling. + (get_property): Ditto. + (nm_device_get_dbus_path): Remove. + + * src/nm-device-interface.c (nm_device_interface_init): Remove the index + property. + + * src/nm-device-802-3-ethernet.c (nm_device_802_3_ethernet_link_activated): + Access the device index through it's interface. + (nm_device_802_3_ethernet_link_deactivated): Ditto. + (nm_device_802_3_ethernet_new): Remove the useless argument test_dev. Remove + index argument. Add interface argument. + + * src/nm-device-802-11-wireless.c (nm_device_802_11_wireless_new): Remove + the useless test_dev argument. Remove index argument. Add interface arugment. + + * src/NetworkManagerSystem.c (nm_system_device_set_from_ip4_config): Get the + device index through interface. + (nm_system_set_mtu): Ditto. + + * introspection/nm-device.xml: Remove the "Index" property. + +2007-11-21 Tambet Ingo + + * src/nm-serial-device.c: + * src/nm-serial-device.c: + * src/nm-umts-device.c: + * src/nm-umts-device.h: Implement. + + * src/nm-hal-manager.c (nm_get_device_driver_name): libhal_free_string the string + allocated by libhal. + (modem_device_creator): Implement. + (register_built_in_creators): Register the modem creator. + + * src/nm-device-802-11-wireless.c (nm_device_802_11_wireless_new): + Remove the unused test_dev argument. + + * src/nm-device-802-3-ethernet.c (nm_device_802_3_ethernet_new): Ditto. + + * src/Makefile.am: Add new files to build. + Link in ppp-manager. + + * libnm-util/nm-setting-umts.c: + * libnm-util/nm-setting-umts.h: + * libnm-util/nm-setting-serial.c: + * libnm-util/nm-setting-serial.h: Implement. + + * libnm-util/Makefile.am: Add new files to build. + 2007-11-28 Dan Williams Patch from Zdeněk Jurka diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 92cc41665..f7f36f189 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -29,12 +29,12 @@ #define NM_DBUS_PATH "/org/freedesktop/NetworkManager" #define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" -#define NM_DBUS_PATH_DEVICE "/org/freedesktop/NetworkManager/Device" #define NM_DBUS_INTERFACE_DEVICE "org.freedesktop.NetworkManager.Device" #define NM_DBUS_INTERFACE_DEVICE_WIRED "org.freedesktop.NetworkManager.Device.Wired" #define NM_DBUS_INTERFACE_DEVICE_WIRELESS "org.freedesktop.NetworkManager.Device.Wireless" #define NM_DBUS_PATH_ACCESS_POINT "/org/freedesktop/NetworkManager/AccessPoint" #define NM_DBUS_INTERFACE_ACCESS_POINT "org.freedesktop.NetworkManager.AccessPoint" +#define NM_DBUS_INTERFACE_UMTS_DEVICE "org.freedesktop.NetworkManager.Device.Umts" #define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings" #define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings" @@ -68,7 +68,8 @@ typedef enum NMDeviceType { DEVICE_TYPE_UNKNOWN = 0, DEVICE_TYPE_802_3_ETHERNET, - DEVICE_TYPE_802_11_WIRELESS + DEVICE_TYPE_802_11_WIRELESS, + DEVICE_TYPE_UMTS } NMDeviceType; diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index c3f3fe56a..cf7007779 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -7,7 +7,6 @@ - diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index c20469309..06f6b572c 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -35,6 +35,7 @@ libnminclude_HEADERS = \ nm-access-point.h \ nm-ip4-config.h \ nm-settings.h \ + nm-umts-device.h \ nm-vpn-connection.h \ nm-vpn-manager.h \ nm-vpn-plugin.h @@ -52,6 +53,7 @@ libnm_glib_la_SOURCES = \ nm-access-point.c \ nm-ip4-config.c \ nm-settings.c \ + nm-umts-device.c \ nm-vpn-connection.c \ nm-vpn-manager.c \ nm-marshal-main.c diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index d5f5552a1..34b29d9c1 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -5,6 +5,7 @@ #include "nm-client.h" #include "nm-device-802-3-ethernet.h" #include "nm-device-802-11-wireless.h" +#include "nm-umts-device.h" #include "nm-device-private.h" #include "nm-marshal.h" #include @@ -386,6 +387,9 @@ get_device (NMClient *client, const char *path, gboolean create_if_not_found) case DEVICE_TYPE_802_11_WIRELESS: device = NM_DEVICE (nm_device_802_11_wireless_new (connection, path)); break; + case DEVICE_TYPE_UMTS: + device = NM_DEVICE (nm_umts_device_new (connection, path)); + break; default: device = nm_device_new (connection, path); } diff --git a/libnm-glib/nm-umts-device.c b/libnm-glib/nm-umts-device.c new file mode 100644 index 000000000..bf91ce745 --- /dev/null +++ b/libnm-glib/nm-umts-device.c @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-umts-device.h" + +G_DEFINE_TYPE (NMUmtsDevice, nm_umts_device, NM_TYPE_DEVICE) + +#define NM_UMTS_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_UMTS_DEVICE, NMUmtsDevicePrivate)) + +typedef struct { + DBusGProxy *umts_proxy; + + gboolean disposed; +} NMUmtsDevicePrivate; + +static void +nm_umts_device_init (NMUmtsDevice *device) +{ +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMUmtsDevicePrivate *priv; + + object = G_OBJECT_CLASS (nm_umts_device_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + priv = NM_UMTS_DEVICE_GET_PRIVATE (object); + + priv->umts_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), + NM_DBUS_SERVICE, + nm_object_get_path (NM_OBJECT (object)), + NM_DBUS_INTERFACE_UMTS_DEVICE); + return object; +} + +static void +dispose (GObject *object) +{ + NMUmtsDevicePrivate *priv = NM_UMTS_DEVICE_GET_PRIVATE (object); + + if (priv->disposed) + return; + + priv->disposed = TRUE; + + g_object_unref (priv->umts_proxy); + + G_OBJECT_CLASS (nm_umts_device_parent_class)->dispose (object); +} + +static void +nm_umts_device_class_init (NMUmtsDeviceClass *device_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (device_class); + + g_type_class_add_private (device_class, sizeof (NMUmtsDevicePrivate)); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->dispose = dispose; +} + +NMUmtsDevice * +nm_umts_device_new (DBusGConnection *connection, const char *path) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + return (NMUmtsDevice *) g_object_new (NM_TYPE_UMTS_DEVICE, + NM_OBJECT_CONNECTION, connection, + NM_OBJECT_PATH, path, + NULL); +} diff --git a/libnm-glib/nm-umts-device.h b/libnm-glib/nm-umts-device.h new file mode 100644 index 000000000..40ef366fc --- /dev/null +++ b/libnm-glib/nm-umts-device.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_UMTS_DEVICE_H +#define NM_UMTS_DEVICE_H + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_UMTS_DEVICE (nm_umts_device_get_type ()) +#define NM_UMTS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_UMTS_DEVICE, NMUmtsDevice)) +#define NM_UMTS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_UMTS_DEVICE, NMUmtsDeviceClass)) +#define NM_IS_UMTS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_UMTS_DEVICE)) +#define NM_IS_UMTS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_UMTS_DEVICE)) +#define NM_UMTS_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_UMTS_DEVICE, NMUmtsDeviceClass)) + +typedef struct { + NMDevice parent; +} NMUmtsDevice; + +typedef struct { + NMDeviceClass parent; +} NMUmtsDeviceClass; + +GType nm_umts_device_get_type (void); + +NMUmtsDevice *nm_umts_device_new (DBusGConnection *connection, + const char *path); + +G_END_DECLS + +#endif /* NM_UMTS_DEVICE_H */ diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 9efaa8f5e..19b28045b 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -18,6 +18,8 @@ libnm_util_include_HEADERS = \ nm-setting-connection.h \ nm-setting-ip4-config.h \ nm-setting-ppp.h \ + nm-setting-serial.h \ + nm-setting-umts.h \ nm-setting-wired.h \ nm-setting-wireless.h \ nm-setting-wireless-security.h \ @@ -32,6 +34,8 @@ libnm_util_la_SOURCES= \ nm-setting-connection.c \ nm-setting-ip4-config.c \ nm-setting-ppp.c \ + nm-setting-serial.c \ + nm-setting-umts.c \ nm-setting-wired.c \ nm-setting-wireless.c \ nm-setting-wireless-security.c \ diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index d2cba9985..e2a2d7063 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -15,6 +15,9 @@ #include "nm-setting-vpn.h" #include "nm-setting-vpn-properties.h" +#include "nm-setting-serial.h" +#include "nm-setting-umts.h" + typedef struct { GHashTable *settings; } NMConnectionPrivate; @@ -46,6 +49,8 @@ register_default_settings (void) { NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG }, { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY }, + { NM_SETTING_SERIAL_SETTING_NAME, NM_TYPE_SETTING_SERIAL }, + { NM_SETTING_UMTS_SETTING_NAME, NM_TYPE_SETTING_UMTS }, { NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP }, { NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN }, { NM_SETTING_VPN_PROPERTIES_SETTING_NAME, NM_TYPE_SETTING_VPN_PROPERTIES }, diff --git a/libnm-util/nm-setting-serial.c b/libnm-util/nm-setting-serial.c new file mode 100644 index 000000000..c278af916 --- /dev/null +++ b/libnm-util/nm-setting-serial.c @@ -0,0 +1,136 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-setting-serial.h" + +G_DEFINE_TYPE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_BAUD, + PROP_BITS, + PROP_PARITY, + PROP_STOPBITS, + PROP_SEND_DELAY, + + LAST_PROP +}; + +NMSetting * +nm_setting_serial_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_SERIAL, NULL); +} + +static void +nm_setting_serial_init (NMSettingSerial *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_SERIAL_SETTING_NAME); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingSerial *setting = NM_SETTING_SERIAL (object); + + switch (prop_id) { + case PROP_BAUD: + setting->baud = g_value_get_uint (value); + break; + case PROP_BITS: + setting->bits = g_value_get_uint (value); + break; + case PROP_PARITY: + setting->parity = g_value_get_char (value); + break; + case PROP_STOPBITS: + setting->stopbits = g_value_get_uint (value); + break; + case PROP_SEND_DELAY: + setting->send_delay = g_value_get_uint64 (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingSerial *setting = NM_SETTING_SERIAL (object); + + switch (prop_id) { + case PROP_BAUD: + g_value_set_uint (value, setting->baud); + break; + case PROP_BITS: + g_value_set_uint (value, setting->bits); + break; + case PROP_PARITY: + g_value_set_char (value, setting->parity); + break; + case PROP_STOPBITS: + g_value_set_uint (value, setting->stopbits); + break; + case PROP_SEND_DELAY: + g_value_set_uint64 (value, setting->send_delay); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_serial_class_init (NMSettingSerialClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + + /* Properties */ + + g_object_class_install_property + (object_class, PROP_BAUD, + g_param_spec_uint (NM_SETTING_SERIAL_BAUD, + "Baud", + "Baud rate", + 0, G_MAXUINT, 57600, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_BITS, + g_param_spec_uint (NM_SETTING_SERIAL_BITS, + "Bits", + "Bits", + 5, 8, 8, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PARITY, + g_param_spec_char (NM_SETTING_SERIAL_PARITY, + "Parity", + "Parity", + 'E', 'o', 'n', + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_STOPBITS, + g_param_spec_uint (NM_SETTING_SERIAL_STOPBITS, + "Stopbits", + "Stopbits", + 1, 2, 1, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_SEND_DELAY, + g_param_spec_uint64 (NM_SETTING_SERIAL_SEND_DELAY, + "SendDelay", + "Send delay", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-serial.h b/libnm-util/nm-setting-serial.h new file mode 100644 index 000000000..42d43631d --- /dev/null +++ b/libnm-util/nm-setting-serial.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_SERIAL_H +#define NM_SETTING_SERIAL_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_SERIAL (nm_setting_serial_get_type ()) +#define NM_SETTING_SERIAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerial)) +#define NM_SETTING_SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) +#define NM_IS_SETTING_SERIAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_SERIAL)) +#define NM_IS_SETTING_SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_SERIAL)) +#define NM_SETTING_SERIAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) + +#define NM_SETTING_SERIAL_SETTING_NAME "serial" + +#define NM_SETTING_SERIAL_BAUD "baud" +#define NM_SETTING_SERIAL_BITS "bits" +#define NM_SETTING_SERIAL_PARITY "parity" +#define NM_SETTING_SERIAL_STOPBITS "stopbits" +#define NM_SETTING_SERIAL_SEND_DELAY "send-delay" + +typedef struct { + NMSetting parent; + + guint baud; + guint bits; + char parity; + guint stopbits; + guint64 send_delay; +} NMSettingSerial; + +typedef struct { + NMSettingClass parent; +} NMSettingSerialClass; + +GType nm_setting_serial_get_type (void); + +NMSetting *nm_setting_serial_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_SERIAL_H */ diff --git a/libnm-util/nm-setting-umts.c b/libnm-util/nm-setting-umts.c new file mode 100644 index 000000000..af5ff4791 --- /dev/null +++ b/libnm-util/nm-setting-umts.c @@ -0,0 +1,238 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include +#include "nm-setting-umts.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSettingUmts, nm_setting_umts, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_NUMBER, + PROP_USERNAME, + PROP_PASSWORD, + PROP_APN, + PROP_NETWORK_ID, + PROP_NETWORK_TYPE, + PROP_BAND, + PROP_PIN, + PROP_PUK, + + LAST_PROP +}; + +NMSetting * +nm_setting_umts_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_UMTS, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings) +{ + NMSettingUmts *self = NM_SETTING_UMTS (setting); + + if (!self->number || strlen (self->number) < 1) { + nm_warning ("Missing phone number"); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_umts_init (NMSettingUmts *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_UMTS_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingUmts *self = NM_SETTING_UMTS (object); + + g_free (self->number); + g_free (self->username); + g_free (self->password); + g_free (self->apn); + g_free (self->network_id); + g_free (self->pin); + g_free (self->puk); + + G_OBJECT_CLASS (nm_setting_umts_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingUmts *setting = NM_SETTING_UMTS (object); + + switch (prop_id) { + case PROP_NUMBER: + g_free (setting->number); + setting->number = g_value_dup_string (value); + break; + case PROP_USERNAME: + g_free (setting->username); + setting->username = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (setting->password); + setting->password = g_value_dup_string (value); + break; + case PROP_APN: + g_free (setting->apn); + setting->apn = g_value_dup_string (value); + break; + case PROP_NETWORK_ID: + g_free (setting->network_id); + setting->network_id = g_value_dup_string (value); + break; + case PROP_NETWORK_TYPE: + setting->network_type = g_value_get_int (value); + break; + case PROP_BAND: + setting->band = g_value_get_int (value); + break; + case PROP_PIN: + g_free (setting->pin); + setting->pin = g_value_dup_string (value); + break; + case PROP_PUK: + g_free (setting->puk); + setting->puk = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingUmts *setting = NM_SETTING_UMTS (object); + + switch (prop_id) { + case PROP_NUMBER: + g_value_set_string (value, setting->number); + break; + case PROP_USERNAME: + g_value_set_string (value, setting->username); + break; + case PROP_PASSWORD: + g_value_set_string (value, setting->password); + break; + case PROP_APN: + g_value_set_string (value, setting->apn); + break; + case PROP_NETWORK_ID: + g_value_set_string (value, setting->network_id); + break; + case PROP_NETWORK_TYPE: + g_value_set_int (value, setting->network_type); + break; + case PROP_BAND: + g_value_set_int (value, setting->band); + break; + case PROP_PIN: + g_value_set_string (value, setting->pin); + break; + case PROP_PUK: + g_value_set_string (value, setting->puk); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_umts_class_init (NMSettingUmtsClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_NUMBER, + g_param_spec_string (NM_SETTING_UMTS_NUMBER, + "Number", + "Number", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_USERNAME, + g_param_spec_string (NM_SETTING_UMTS_USERNAME, + "Username", + "Username", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_UMTS_PASSWORD, + "Password", + "Password", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_APN, + g_param_spec_string (NM_SETTING_UMTS_APN, + "APN", + "APN", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_NETWORK_ID, + g_param_spec_string (NM_SETTING_UMTS_NETWORK_ID, + "Network ID", + "Network ID", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_NETWORK_TYPE, + g_param_spec_int (NM_SETTING_UMTS_NETWORK_TYPE, + "Network type", + "Network type", + NM_UMTS_NETWORK_ANY, + NM_UMTS_NETWORK_PREFER_UMTS, + NM_UMTS_NETWORK_ANY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_BAND, + g_param_spec_int (NM_SETTING_UMTS_BAND, + "Band", + "Band", + -1, 5, -1, /* FIXME: Use an enum for it */ + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PIN, + g_param_spec_string (NM_SETTING_UMTS_PIN, + "PIN", + "PIN", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + g_object_class_install_property + (object_class, PROP_PUK, + g_param_spec_string (NM_SETTING_UMTS_PUK, + "PUK", + "PUK", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); +} diff --git a/libnm-util/nm-setting-umts.h b/libnm-util/nm-setting-umts.h new file mode 100644 index 000000000..f4cebdc97 --- /dev/null +++ b/libnm-util/nm-setting-umts.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_UMTS_H +#define NM_SETTING_UMTS_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_UMTS (nm_setting_umts_get_type ()) +#define NM_SETTING_UMTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_UMTS, NMSettingUmts)) +#define NM_SETTING_UMTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_UMTS, NMSettingUmtsClass)) +#define NM_IS_SETTING_UMTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_UMTS)) +#define NM_IS_SETTING_UMTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_UMTS)) +#define NM_SETTING_UMTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_UMTS, NMSettingUmtsClass)) + +#define NM_SETTING_UMTS_SETTING_NAME "umts" + +#define NM_SETTING_UMTS_NUMBER "number" +#define NM_SETTING_UMTS_USERNAME "username" +#define NM_SETTING_UMTS_PASSWORD "password" +#define NM_SETTING_UMTS_APN "apn" +#define NM_SETTING_UMTS_NETWORK_ID "network-id" +#define NM_SETTING_UMTS_NETWORK_TYPE "network-type" +#define NM_SETTING_UMTS_BAND "band" +#define NM_SETTING_UMTS_PIN "pin" +#define NM_SETTING_UMTS_PUK "puk" + +enum { + NM_UMTS_NETWORK_ANY = -1, + NM_UMTS_NETWORK_GPRS = 0, + NM_UMTS_NETWORK_UMTS = 1, + NM_UMTS_NETWORK_PREFER_GPRS = 2, + NM_UMTS_NETWORK_PREFER_UMTS = 3, +}; + +typedef struct { + NMSetting parent; + + char *number; /* For dialing, duh */ + char *username; + char *password; + + char *apn; /* NULL for dynamic */ + char *network_id; /* for manual registration or NULL for automatic */ + int network_type; /* One of the NM_UMTS_NETWORK_* */ + int band; + + char *pin; + char *puk; +} NMSettingUmts; + +typedef struct { + NMSettingClass parent; +} NMSettingUmtsClass; + +GType nm_setting_umts_get_type (void); + +NMSetting *nm_setting_umts_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_UMTS_H */ diff --git a/src/Makefile.am b/src/Makefile.am index f8c30de2e..012d9d331 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,10 @@ NetworkManager_SOURCES = \ nm-activation-request.h \ nm-properties-changed-signal.c \ nm-properties-changed-signal.h \ + nm-serial-device.c \ + nm-serial-device.h \ + nm-umts-device.c \ + nm-umts-device.h \ autoip.c \ autoip.h \ kernel-types.h \ @@ -123,6 +127,7 @@ NetworkManager_LDADD = \ ./vpn-manager/libvpn-manager.la \ ./dhcp-manager/libdhcp-manager.la \ ./supplicant-manager/libsupplicant-manager.la \ + ./ppp-manager/libppp-manager.la \ ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index 18dea10b5..01dfee259 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -4,9 +4,12 @@ - + + + + @@ -16,6 +19,10 @@ + + + + 512 diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 97db4acad..9c77fa3b5 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -210,9 +210,13 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT))) { - rtnl_addr_set_ifindex (addr, nm_device_get_index (dev)); + const char *iface; + + iface = nm_device_get_iface (dev); + rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface)); + if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) - nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", nm_device_get_iface (dev), err, nl_geterror()); + nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror()); rtnl_addr_put (addr); } else @@ -492,6 +496,7 @@ void nm_system_set_mtu (NMDevice *dev) struct rtnl_link * old; unsigned long mtu; struct nl_handle * nlh; + guint32 idx; mtu = nm_system_get_mtu (dev); if (!mtu) @@ -501,7 +506,8 @@ void nm_system_set_mtu (NMDevice *dev) if (!request) return; - old = nm_netlink_index_to_rtnl_link (nm_device_get_index (dev)); + idx = nm_netlink_iface_to_index (nm_device_get_iface (dev)); + old = nm_netlink_index_to_rtnl_link (idx); if (!old) goto out_request; diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 9c1410863..e68c7cbca 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -3048,31 +3048,29 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) NMDevice80211Wireless * -nm_device_802_11_wireless_new (int idx, - const char *udi, - const char *driver, - gboolean test_dev) +nm_device_802_11_wireless_new (const char *udi, + const char *iface, + const char *driver) { GObject *obj; - g_return_val_if_fail (idx >= 0, NULL); g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_INDEX, idx, - NM_DEVICE_INTERFACE_DRIVER, driver, - NULL); + NM_DEVICE_INTERFACE_UDI, udi, + NM_DEVICE_INTERFACE_IFACE, iface, + NM_DEVICE_INTERFACE_DRIVER, driver, + NULL); if (obj == NULL) return NULL; g_signal_connect (obj, "state-changed", - G_CALLBACK (state_changed_cb), - NULL); + G_CALLBACK (state_changed_cb), + NULL); return NM_DEVICE_802_11_WIRELESS (obj); - } NMAccessPoint * diff --git a/src/nm-device-802-11-wireless.h b/src/nm-device-802-11-wireless.h index e7b7dd4c4..cfd17bdbc 100644 --- a/src/nm-device-802-11-wireless.h +++ b/src/nm-device-802-11-wireless.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + /* NetworkManager -- Network link manager * * Dan Williams @@ -78,10 +80,9 @@ struct _NMDevice80211WirelessClass GType nm_device_802_11_wireless_get_type (void); -NMDevice80211Wireless *nm_device_802_11_wireless_new (int index, - const char *udi, - const char *driver, - gboolean test_dev); +NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *udi, + const char *iface, + const char *driver); void nm_device_802_11_wireless_set_ssid (NMDevice80211Wireless *self, const GByteArray * ssid); diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index 6124ad657..589b83805 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -34,6 +34,7 @@ #include "nm-activation-request.h" #include "NetworkManagerUtils.h" #include "nm-supplicant-manager.h" +#include "nm-netlink.h" #include "nm-netlink-monitor.h" #include "NetworkManagerSystem.h" #include "nm-setting-connection.h" @@ -85,7 +86,7 @@ nm_device_802_3_ethernet_link_activated (NMNetlinkMonitor *monitor, NMDevice *dev = NM_DEVICE (user_data); /* Make sure signal is for us */ - if (nm_device_get_index (dev) == idx) + if (nm_netlink_iface_to_index (nm_device_get_iface (dev)) == idx) nm_device_set_active_link (dev, TRUE); } @@ -97,7 +98,7 @@ nm_device_802_3_ethernet_link_deactivated (NMNetlinkMonitor *monitor, NMDevice *dev = NM_DEVICE (user_data); /* Make sure signal is for us */ - if (nm_device_get_index (dev) == idx) + if (nm_netlink_iface_to_index (nm_device_get_iface (dev)) == idx) nm_device_set_active_link (dev, FALSE); } @@ -119,6 +120,7 @@ constructor (GType type, dev = NM_DEVICE (object); priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (dev); + priv->carrier_file_path = g_strdup_printf ("/sys/class/net/%s/carrier", nm_device_get_iface (dev)); @@ -237,26 +239,21 @@ real_bring_down (NMDevice *dev) NMDevice8023Ethernet * -nm_device_802_3_ethernet_new (int idx, - const char *udi, - const char *driver, - gboolean test_dev) +nm_device_802_3_ethernet_new (const char *udi, + const char *iface, + const char *driver) { GObject *obj; - g_return_val_if_fail (idx >= 0, NULL); g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); - obj = g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, - NM_DEVICE_INTERFACE_UDI, udi, - NM_DEVICE_INTERFACE_INDEX, idx, - NM_DEVICE_INTERFACE_DRIVER, driver, - NULL); - if (obj == NULL) - return NULL; - - return NM_DEVICE_802_3_ETHERNET (obj); + return (NMDevice8023Ethernet *) g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, + NM_DEVICE_INTERFACE_UDI, udi, + NM_DEVICE_INTERFACE_IFACE, iface, + NM_DEVICE_INTERFACE_DRIVER, driver, + NULL); } @@ -426,7 +423,7 @@ nm_device_802_3_ethernet_finalize (GObject *object) static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMDevice8023Ethernet *device = NM_DEVICE_802_3_ETHERNET (object); struct ether_addr hw_addr; diff --git a/src/nm-device-802-3-ethernet.h b/src/nm-device-802-3-ethernet.h index 0413ff840..45734bc49 100644 --- a/src/nm-device-802-3-ethernet.h +++ b/src/nm-device-802-3-ethernet.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + /* NetworkManager -- Network link manager * * Dan Williams @@ -51,10 +53,9 @@ typedef struct { GType nm_device_802_3_ethernet_get_type (void); -NMDevice8023Ethernet *nm_device_802_3_ethernet_new (int index, - const char *udi, - const char *driver, - gboolean test_dev); +NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *udi, + const char *iface, + const char *driver); void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev, struct ether_addr *addr); diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index a2bb77085..d2d62f972 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -54,21 +54,13 @@ nm_device_interface_init (gpointer g_iface) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_DEVICE_INTERFACE_INDEX, - "Index", - "Index", - 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_interface_install_property (g_iface, g_param_spec_string (NM_DEVICE_INTERFACE_IFACE, "Interface", "Interface", NULL, - G_PARAM_READABLE)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_interface_install_property (g_iface, diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index b33ad79f4..124c91427 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -22,7 +22,6 @@ typedef enum #define NM_DEVICE_INTERFACE_UDI "udi" #define NM_DEVICE_INTERFACE_IFACE "interface" -#define NM_DEVICE_INTERFACE_INDEX "index" #define NM_DEVICE_INTERFACE_DRIVER "driver" #define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" #define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4_address" @@ -35,7 +34,6 @@ typedef enum { NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, NM_DEVICE_INTERFACE_PROP_UDI = NM_DEVICE_INTERFACE_PROP_FIRST, - NM_DEVICE_INTERFACE_PROP_INDEX, NM_DEVICE_INTERFACE_PROP_IFACE, NM_DEVICE_INTERFACE_PROP_DRIVER, NM_DEVICE_INTERFACE_PROP_CAPABILITIES, diff --git a/src/nm-device.c b/src/nm-device.c index 74f14c326..6f3aee071 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -58,9 +58,7 @@ struct _NMDevicePrivate NMDeviceState state; - char * dbus_path; char * udi; - int index; /* Should always stay the same over lifetime of device */ char * iface; /* may change, could be renamed by user */ NMDeviceType type; guint32 capabilities; @@ -113,7 +111,6 @@ nm_device_init (NMDevice * self) self->priv->initialized = FALSE; self->priv->udi = NULL; self->priv->iface = NULL; - self->priv->index = G_MAXUINT32; self->priv->type = DEVICE_TYPE_UNKNOWN; self->priv->capabilities = NM_DEVICE_CAP_NONE; self->priv->driver = NULL; @@ -142,30 +139,27 @@ constructor (GType type, NMDBusManager *manager; object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type, - n_construct_params, - construct_params); + n_construct_params, + construct_params); if (!object) return NULL; dev = NM_DEVICE (object); priv = NM_DEVICE_GET_PRIVATE (dev); - if (priv->index == G_MAXUINT32) { - nm_warning ("Interface index is a required constructor property."); + if (!priv->udi) { + nm_warning ("No device udi provided, ignoring"); goto error; } - priv->iface = nm_netlink_index_to_iface (priv->index); - if (priv->iface == NULL) { - nm_warning ("(%u): Couldn't get interface name for device, ignoring.", - priv->index); + if (!priv->iface) { + nm_warning ("No device interface provided, ignoring"); goto error; } priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) { - nm_warning ("(%s): Device unsupported, ignoring.", - nm_device_get_iface (dev)); + nm_warning ("(%s): Device unsupported, ignoring.", priv->iface); goto error; } @@ -174,27 +168,17 @@ constructor (GType type, /* Allow distributions to flag devices as disabled */ if (nm_system_device_get_disabled (dev)) { - nm_warning ("(%s): Device otherwise managed, ignoring.", - nm_device_get_iface (dev)); + nm_warning ("(%s): Device otherwise managed, ignoring.", priv->iface); goto error; } nm_print_device_capabilities (dev); manager = nm_dbus_manager_get (); - priv->dbus_path = g_strdup_printf ("%s/%d", - NM_DBUS_PATH_DEVICE, - nm_device_get_index (dev)); - if (priv->dbus_path == NULL) { - nm_warning ("(%s): Not enough memory to initialize device.", - nm_device_get_iface (dev)); - goto error; - } - nm_info ("(%s): exporting device as %s", nm_device_get_iface (dev), nm_device_get_dbus_path (dev)); + nm_info ("(%s): exporting device as %s", priv->iface, priv->udi); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (manager), - nm_device_get_dbus_path (dev), - object); + priv->udi, object); g_object_unref (manager); @@ -245,14 +229,6 @@ real_get_generic_capabilities (NMDevice *dev) } -const char * -nm_device_get_dbus_path (NMDevice *self) -{ - g_return_val_if_fail (self != NULL, NULL); - - return self->priv->dbus_path; -} - const char * nm_device_get_udi (NMDevice *self) { @@ -261,14 +237,6 @@ nm_device_get_udi (NMDevice *self) return self->priv->udi; } -guint32 -nm_device_get_index (NMDevice *self) -{ - g_return_val_if_fail (self != NULL, G_MAXUINT32); - - return self->priv->index; -} - /* * Get/set functions for iface */ @@ -1595,8 +1563,9 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->udi = g_strdup (g_value_get_string (value)); break; - case NM_DEVICE_INTERFACE_PROP_INDEX: - priv->index = g_value_get_uint (value); + case NM_DEVICE_INTERFACE_PROP_IFACE: + g_free (priv->iface); + priv->iface = g_value_dup_string (value); break; case NM_DEVICE_INTERFACE_PROP_DRIVER: priv->driver = g_strdup (g_value_get_string (value)); @@ -1623,9 +1592,6 @@ get_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_UDI: g_value_set_string (value, priv->udi); break; - case NM_DEVICE_INTERFACE_PROP_INDEX: - g_value_set_uint (value, priv->index); - break; case NM_DEVICE_INTERFACE_PROP_IFACE: g_value_set_string (value, priv->iface); break; @@ -1687,10 +1653,6 @@ nm_device_class_init (NMDeviceClass *klass) NM_DEVICE_INTERFACE_PROP_UDI, NM_DEVICE_INTERFACE_UDI); - g_object_class_override_property (object_class, - NM_DEVICE_INTERFACE_PROP_INDEX, - NM_DEVICE_INTERFACE_INDEX); - g_object_class_override_property (object_class, NM_DEVICE_INTERFACE_PROP_IFACE, NM_DEVICE_INTERFACE_IFACE); diff --git a/src/nm-device.h b/src/nm-device.h index ea2b735b5..4ed69eea1 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -118,9 +118,7 @@ struct _NMDeviceClass GType nm_device_get_type (void); -const char * nm_device_get_dbus_path (NMDevice *dev); const char * nm_device_get_udi (NMDevice *dev); -guint32 nm_device_get_index (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev); const char * nm_device_get_driver (NMDevice *dev); diff --git a/src/nm-hal-manager.c b/src/nm-hal-manager.c index 3f63c62f1..03def2126 100644 --- a/src/nm-hal-manager.c +++ b/src/nm-hal-manager.c @@ -12,6 +12,7 @@ #include "nm-utils.h" #include "nm-device-802-11-wireless.h" #include "nm-device-802-3-ethernet.h" +#include "nm-umts-device.h" /* Killswitch poll frequency in seconds */ #define NM_HAL_MANAGER_KILLSWITCH_POLL_FREQUENCY 6 @@ -33,15 +34,16 @@ struct _NMHalManager { /* Device creators */ typedef NMDevice *(*NMDeviceCreatorFn) (NMHalManager *manager, - const char *udi); + const char *udi); typedef struct { + char *device_type_name; char *capability_str; gboolean (*is_device_fn) (NMHalManager *manager, const char *udi); NMDeviceCreatorFn creator_fn; } DeviceCreator; -static NMDeviceCreatorFn +static DeviceCreator * get_creator (NMHalManager *manager, const char *udi) { DeviceCreator *creator; @@ -51,7 +53,7 @@ get_creator (NMHalManager *manager, const char *udi) creator = (DeviceCreator *) iter->data; if (creator->is_device_fn (manager, udi)) - return creator->creator_fn; + return creator; } return NULL; @@ -61,24 +63,6 @@ get_creator (NMHalManager *manager, const char *udi) /* Common helpers for built-in device creators */ -static int -get_device_index_from_hal (LibHalContext *ctx, const char *udi) -{ - int idx = -1; - - if (libhal_device_property_exists (ctx, udi, "net.linux.ifindex", NULL) && - libhal_device_property_exists (ctx, udi, "info.category", NULL)) { - - char *category = libhal_device_get_property_string (ctx, udi, "info.category", NULL); - if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211"))) { - idx = libhal_device_get_property_int (ctx, udi, "net.linux.ifindex", NULL); - } - libhal_free_string (category); - } - - return idx; -} - static char * nm_get_device_driver_name (LibHalContext *ctx, const char *udi) { @@ -89,7 +73,7 @@ nm_get_device_driver_name (LibHalContext *ctx, const char *udi) if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL)) { char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL); driver_name = g_strdup (drv); - g_free (drv); + libhal_free_string (drv); } libhal_free_string (physdev_udi); @@ -121,17 +105,19 @@ static NMDevice * wired_device_creator (NMHalManager *manager, const char *udi) { NMDevice *device; - int idx; + char *iface; char *driver; - idx = get_device_index_from_hal (manager->hal_ctx, udi); - if (idx < 0) { - nm_warning ("Couldn't get interface index for %s, ignoring.", udi); + iface = libhal_device_get_property_string (manager->hal_ctx, udi, "net.interface", NULL); + if (!iface) { + nm_warning ("Couldn't get interface for %s, ignoring.", udi); return NULL; } driver = nm_get_device_driver_name (manager->hal_ctx, udi); - device = (NMDevice *) nm_device_802_3_ethernet_new (idx, udi, driver, FALSE); + device = (NMDevice *) nm_device_802_3_ethernet_new (udi, iface, driver); + + libhal_free_string (iface); g_free (driver); return device; @@ -162,22 +148,70 @@ static NMDevice * wireless_device_creator (NMHalManager *manager, const char *udi) { NMDevice *device; - int idx; + char *iface; char *driver; - idx = get_device_index_from_hal (manager->hal_ctx, udi); - if (idx < 0) { - nm_warning ("Couldn't get interface index for %s, ignoring.", udi); + iface = libhal_device_get_property_string (manager->hal_ctx, udi, "net.interface", NULL); + if (!iface) { + nm_warning ("Couldn't get interface for %s, ignoring.", udi); return NULL; } driver = nm_get_device_driver_name (manager->hal_ctx, udi); - device = (NMDevice *) nm_device_802_11_wireless_new (idx, udi, driver, FALSE); + device = (NMDevice *) nm_device_802_11_wireless_new (udi, iface, driver); + + libhal_free_string (iface); g_free (driver); return device; } +/* Modem device creator */ + +static gboolean +is_modem_device (NMHalManager *manager, const char *udi) +{ + gboolean is_modem = FALSE; + + if (libhal_device_property_exists (manager->hal_ctx, udi, "info.category", NULL)) { + char *category; + + category = libhal_device_get_property_string (manager->hal_ctx, udi, "info.category", NULL); + if (category) { + is_modem = strcmp (category, "serial") == 0; + libhal_free_string (category); + } + } + + return is_modem; +} + +NMDevice * +modem_device_creator (NMHalManager *manager, const char *udi) +{ + char *serial_device; + char *parent_udi; + char *driver_name = NULL; + NMDevice *device = NULL; + + serial_device = libhal_device_get_property_string (manager->hal_ctx, udi, "serial.device", NULL); + + /* Get the driver */ + parent_udi = libhal_device_get_property_string (manager->hal_ctx, udi, "info.parent", NULL); + if (parent_udi) { + driver_name = libhal_device_get_property_string (manager->hal_ctx, parent_udi, "info.linux.driver", NULL); + libhal_free_string (parent_udi); + } + + if (serial_device && driver_name) + device = (NMDevice *) nm_umts_device_new (udi, serial_device + strlen ("/dev/"), driver_name); + + libhal_free_string (serial_device); + libhal_free_string (driver_name); + + return device; +} + static void register_built_in_creators (NMHalManager *manager) { @@ -185,6 +219,7 @@ register_built_in_creators (NMHalManager *manager) /* Wired device */ creator = g_slice_new0 (DeviceCreator); + creator->device_type_name = g_strdup ("wired Ethernet (802.3)"); creator->capability_str = g_strdup ("net"); creator->is_device_fn = is_wired_device; creator->creator_fn = wired_device_creator; @@ -192,16 +227,25 @@ register_built_in_creators (NMHalManager *manager) /* Wireless device */ creator = g_slice_new0 (DeviceCreator); + creator->device_type_name = g_strdup ("wireless (802.11)"); creator->capability_str = g_strdup ("net"); creator->is_device_fn = is_wireless_device; creator->creator_fn = wireless_device_creator; manager->device_creators = g_slist_append (manager->device_creators, creator); + + /* Modem */ + creator = g_slice_new0 (DeviceCreator); + creator->device_type_name = g_strdup ("UMTS (GSM)"); + creator->capability_str = g_strdup ("modem"); + creator->is_device_fn = is_modem_device; + creator->creator_fn = modem_device_creator; + manager->device_creators = g_slist_append (manager->device_creators, creator); } static NMDevice * create_device_and_add_to_list (NMHalManager *manager, - NMDeviceCreatorFn creator_fn, - const char *udi) + DeviceCreator *creator, + const char *udi) { NMDevice *dev = NULL; char *usb_test = NULL; @@ -218,11 +262,11 @@ create_device_and_add_to_list (NMHalManager *manager, return NULL; } - dev = creator_fn (manager, udi); + dev = creator->creator_fn (manager, udi); if (dev) { - nm_info ("Now managing %s device '%s'.", - NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)", - nm_device_get_iface (dev)); + nm_info ("Now managing %s device '%s'.", + creator->device_type_name, + nm_device_get_iface (dev)); nm_manager_add_device (manager->nm_manager, dev); g_object_unref (dev); @@ -235,7 +279,7 @@ static void device_added (LibHalContext *ctx, const char *udi) { NMHalManager *manager = (NMHalManager *) libhal_ctx_get_user_data (ctx); - NMDeviceCreatorFn creator_fn; + DeviceCreator *creator; // nm_debug ("New device added (hal udi is '%s').", udi ); @@ -249,9 +293,9 @@ device_added (LibHalContext *ctx, const char *udi) * so this call will fail, and it will actually be added when hal sets the device's * capabilities a bit later on. */ - creator_fn = get_creator (manager, udi); - if (creator_fn) - create_device_and_add_to_list (manager, creator_fn, udi); + creator = get_creator (manager, udi); + if (creator) + create_device_and_add_to_list (manager, creator, udi); } static void @@ -270,7 +314,7 @@ static void device_new_capability (LibHalContext *ctx, const char *udi, const char *capability) { NMHalManager *manager = (NMHalManager *) libhal_ctx_get_user_data (ctx); - NMDeviceCreatorFn creator_fn; + DeviceCreator *creator; /*nm_debug ("nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/ @@ -280,9 +324,9 @@ device_new_capability (LibHalContext *ctx, const char *udi, const char *capabili if (nm_manager_get_state (manager->nm_manager) == NM_STATE_ASLEEP) return; - creator_fn = get_creator (manager, udi); - if (creator_fn) - create_device_and_add_to_list (manager, creator_fn, udi); + creator = get_creator (manager, udi); + if (creator) + create_device_and_add_to_list (manager, creator, udi); } static void @@ -312,7 +356,7 @@ add_initial_devices (NMHalManager *manager) if (devices) { for (i = 0; i < num_devices; i++) { if (creator->is_device_fn (manager, devices[i])) - create_device_and_add_to_list (manager, creator->creator_fn, devices[i]); + create_device_and_add_to_list (manager, creator, devices[i]); } } @@ -671,7 +715,10 @@ nm_hal_manager_new (NMManager *nm_manager) static void destroy_creator (gpointer data, gpointer user_data) { - g_free (((DeviceCreator *) data)->capability_str); + DeviceCreator *creator = (DeviceCreator *) data; + + g_free (creator->device_type_name); + g_free (creator->capability_str); g_slice_free (DeviceCreator, data); } diff --git a/src/nm-manager.c b/src/nm-manager.c index 5744b4dec..b28bc03ee 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1062,7 +1062,7 @@ impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err) *devices = g_ptr_array_sized_new (g_slist_length (priv->devices)); for (iter = priv->devices; iter; iter = iter->next) - g_ptr_array_add (*devices, g_strdup (nm_device_get_dbus_path (NM_DEVICE (iter->data)))); + g_ptr_array_add (*devices, g_strdup (nm_device_get_udi (NM_DEVICE (iter->data)))); return TRUE; } @@ -1078,7 +1078,7 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path) for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { NMDevice *device = NM_DEVICE (iter->data); - if (!strcmp (nm_device_get_dbus_path (device), path)) + if (!strcmp (nm_device_get_udi (device), path)) return device; } @@ -1377,7 +1377,7 @@ add_one_connection_element (NMManager *manager, dev_array = g_ptr_array_sized_new (1); if (!dev_array) return NULL; - g_ptr_array_add (dev_array, g_strdup (nm_device_get_dbus_path (device))); + g_ptr_array_add (dev_array, g_strdup (nm_device_get_udi (device))); g_value_init (&entry, type); g_value_take_boxed (&entry, dbus_g_type_specialized_construct (type)); diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c new file mode 100644 index 000000000..9fcc9b53d --- /dev/null +++ b/src/nm-serial-device.c @@ -0,0 +1,869 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-serial-device.h" +#include "nm-device-private.h" +#include "ppp-manager/nm-ppp-manager.h" +#include "nm-setting-serial.h" +#include "nm-setting-ppp.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSerialDevice, nm_serial_device, NM_TYPE_DEVICE) + +#define NM_SERIAL_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SERIAL_DEVICE, NMSerialDevicePrivate)) + +typedef struct { + int fd; + GIOChannel *channel; + NMPPPManager *ppp_manager; + struct termios old_t; +} NMSerialDevicePrivate; + +static int +parse_baudrate (guint i) +{ + int speed; + + switch (i) { + case 0: + speed = B0; + break; + case 50: + speed = B50; + break; + case 75: + speed = B75; + break; + case 110: + speed = B110; + break; + case 150: + speed = B150; + break; + case 300: + speed = B300; + break; + case 600: + speed = B600; + break; + case 1200: + speed = B1200; + break; + case 2400: + speed = B2400; + break; + case 4800: + speed = B4800; + break; + case 9600: + speed = B9600; + break; + case 19200: + speed = B19200; + break; + case 38400: + speed = B38400; + break; + case 57600: + speed = B57600; + break; + case 115200: + speed = B115200; + break; + case 460800: + speed = B460800; + break; + default: + g_warning ("Invalid baudrate '%d'", i); + speed = B9600; + } + + return speed; +} + +static int +parse_bits (guint i) +{ + int bits; + + switch (i) { + case 5: + bits = CS5; + break; + case 6: + bits = CS6; + break; + case 7: + bits = CS7; + break; + case 8: + bits = CS8; + break; + default: + g_warning ("Invalid bits (%d). Valid values are 5, 6, 7, 8.", i); + bits = CS8; + } + + return bits; +} + +static int +parse_parity (char c) +{ + int parity; + + switch (c) { + case 'n': + case 'N': + parity = 0; + break; + case 'e': + case 'E': + parity = PARENB; + break; + case 'o': + case 'O': + parity = PARENB | PARODD; + break; + default: + g_warning ("Invalid parity (%c). Valid values are n, e, o", c); + parity = 0; + } + + return parity; +} + +static int +parse_stopbits (guint i) +{ + int stopbits; + + switch (i) { + case 1: + stopbits = 0; + break; + case 2: + stopbits = CSTOPB; + break; + default: + g_warning ("Invalid stop bits (%d). Valid values are 1 and 2)", i); + stopbits = 0; + } + + return stopbits; +} + +static NMSetting * +serial_device_get_setting (NMSerialDevice *device, GType setting_type) +{ + NMActRequest *req; + NMSetting *setting = NULL; + + req = nm_device_get_act_request (NM_DEVICE (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 gboolean +config_fd (NMSerialDevice *device) +{ + NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + NMSettingSerial *setting; + struct termio stbuf; + int speed; + int bits; + int parity; + int stopbits; + + setting = NM_SETTING_SERIAL (serial_device_get_setting (device, NM_TYPE_SETTING_SERIAL)); + + speed = parse_baudrate (setting->baud); + bits = parse_bits (setting->bits); + parity = parse_parity (setting->parity); + stopbits = parse_stopbits (setting->stopbits); + + ioctl (priv->fd, TCGETA, &stbuf); + + stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR ); + stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET); + stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL); + stbuf.c_lflag &= ~(ECHO | ECHOE); + stbuf.c_cc[VMIN] = 1; + stbuf.c_cc[VTIME] = 0; + stbuf.c_cc[VEOF] = 1; + + stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB); + stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity | stopbits); + + if (ioctl (priv->fd, TCSETA, &stbuf) < 0) { + g_warning ("Can not control device"); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_serial_device_open (NMSerialDevice *device) +{ + NMSerialDevicePrivate *priv; + const char *iface; + char *path; + + g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); + + priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + iface = nm_device_get_iface (NM_DEVICE (device)); + + nm_debug ("Opening device '%s'", iface); + + path = g_build_filename ("/dev", iface, NULL); + priv->fd = open (path, O_RDWR | O_EXCL | O_NONBLOCK | O_NOCTTY); + g_free (path); + + if (priv->fd < 0) { + nm_warning ("Can not open device '%s'", iface); + return FALSE; + } + + if (ioctl (priv->fd, TCGETA, &priv->old_t) < 0) { + nm_warning ("Can not control device '%s'", iface); + close (priv->fd); + return FALSE; + } + + config_fd (device); + + priv->channel = g_io_channel_unix_new (priv->fd); + + return TRUE; +} + +void +nm_serial_device_close (NMSerialDevice *device) +{ + NMSerialDevicePrivate *priv; + + g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); + + priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + + if (priv->fd) { + nm_debug ("Closing device '%s'", nm_device_get_iface (NM_DEVICE (device))); + + g_io_channel_unref (priv->channel); + ioctl (priv->fd, TCSETA, &priv->old_t); + close (priv->fd); + + priv->fd = 0; + } +} + +gboolean +nm_serial_device_send_command (NMSerialDevice *device, GByteArray *command) +{ + int fd; + NMSettingSerial *setting; + int i; + ssize_t status; + + g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); + g_return_val_if_fail (command != NULL, FALSE); + + fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd; + setting = NM_SETTING_SERIAL (serial_device_get_setting (device, NM_TYPE_SETTING_SERIAL)); + + g_print ("Sending: "); + for (i = 0; i < command->len; i++) + g_print ("%c", command->data[i]); + g_print ("\n"); + + for (i = 0; i < command->len; i++) { + again: + status = write (fd, command->data + i, 1); + + if (status < 0) { + if (errno == EAGAIN) + goto again; + + g_warning ("Error in writing"); + return FALSE; + } + + if (setting->send_delay) + usleep (setting->send_delay); + } + + return TRUE; +} + +gboolean +nm_serial_device_send_command_string (NMSerialDevice *device, const char *str) +{ + GByteArray *command; + gboolean ret; + + g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); + g_return_val_if_fail (str != NULL, FALSE); + + command = g_byte_array_new (); + g_byte_array_append (command, (guint8 *) str, strlen (str)); + g_byte_array_append (command, (guint8 *) "\r\n", 2); + + ret = nm_serial_device_send_command (device, command); + g_byte_array_free (command, TRUE); + + return ret; +} + +typedef struct { + NMSerialDevice *device; + char *terminators; + GString *result; + NMSerialGetReplyFn callback; + gpointer user_data; + guint timeout_id; + guint got_data_id; +} GetReplyInfo; + +static void +get_reply_info_destroy (gpointer data) +{ + GetReplyInfo *info = (GetReplyInfo *) data; + + if (info->got_data_id) + g_source_remove (info->got_data_id); + + g_free (info->terminators); + + if (info->result) + g_string_free (info->result, TRUE); + + g_free (info); +} + +static gboolean +get_reply_timeout (gpointer data) +{ + GetReplyInfo *info = (GetReplyInfo *) data; + + info->callback (info->device, NULL, info->user_data); + + return FALSE; +} + +static gboolean +get_reply_got_data (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GetReplyInfo *info = (GetReplyInfo *) data; + gsize bytes_read; + char buf[4096]; + GIOStatus status; + gboolean done = FALSE; + int i; + + if (condition & G_IO_IN) { + do { + GError *err = NULL; + + status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, &err); + + if (status == G_IO_STATUS_ERROR) { + g_warning ("%s", err->message); + g_error_free (err); + err = NULL; + } + + if (bytes_read > 0) { + char *p; + + g_print ("Got: "); + for (i = 0; i < bytes_read; i++) + g_print ("%c", buf[i]); + g_print ("\n"); + + p = &buf[0]; + for (i = 0; i < bytes_read && !done; i++, p++) { + int j; + + for (j = 0; j < strlen (info->terminators); j++) + if (*p == info->terminators[j]) + done = TRUE; + + if (!done) + g_string_append_c (info->result, *p); + } + } + } while (!done || bytes_read == 4096 || status == G_IO_STATUS_AGAIN); + } + + if (condition & G_IO_HUP || condition & G_IO_ERR) { + g_string_free (info->result, TRUE); + info->result = NULL; + done = TRUE; + } + + if (done) { + char *result = info->result ? g_string_free (info->result, FALSE) : NULL; + info->result = NULL; + info->callback (info->device, result, info->user_data); + g_free (result); + + /* Clear the id - returning FALSE already removes it */ + info->got_data_id = 0; + g_source_remove (info->timeout_id); + } + + return !done; +} + +void +nm_serial_device_get_reply (NMSerialDevice *device, + guint timeout, + const char *terminators, + NMSerialGetReplyFn callback, + gpointer user_data) +{ + GetReplyInfo *info; + + g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); + g_return_if_fail (terminators != NULL); + g_return_if_fail (callback != NULL); + + info = g_new (GetReplyInfo, 1); + info->device = device; + info->terminators = g_strdup (terminators); + info->result = g_string_new (NULL); + info->callback = callback; + info->user_data = user_data; + + info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel, + G_IO_IN | G_IO_ERR | G_IO_HUP, + get_reply_got_data, + info); + + info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, + timeout * 1000, + get_reply_timeout, + info, + get_reply_info_destroy); +} + +typedef struct { + NMSerialDevice *device; + char **str_needles; + NMSerialWaitForReplyFn callback; + gpointer user_data; + guint timeout_id; + guint got_data_id; +} WaitForReplyInfo; + +static void +wait_for_reply_info_destroy (gpointer data) +{ + WaitForReplyInfo *info = (WaitForReplyInfo *) data; + + if (info->got_data_id) + g_source_remove (info->got_data_id); + + g_strfreev (info->str_needles); + g_free (info); +} + +static gboolean +wait_for_reply_timeout (gpointer data) +{ + WaitForReplyInfo *info = (WaitForReplyInfo *) data; + + info->callback (info->device, -1, info->user_data); + + return FALSE; +} + +static gboolean +wait_for_reply_got_data (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + WaitForReplyInfo *info = (WaitForReplyInfo *) data; + gsize bytes_read; + char buf[4096]; + GIOStatus status; + gboolean done = FALSE; + int index = -1; + int i; + + if (condition & G_IO_IN) { + do { + GError *err = NULL; + + status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, &err); + + if (status == G_IO_STATUS_ERROR) { + g_warning ("%s", err->message); + g_error_free (err); + err = NULL; + } + + if (bytes_read > 0) { + g_print ("Got: "); + for (i = 0; i < bytes_read; i++) + g_print ("%c", buf[i]); + g_print ("\n"); + + for (i = 0; info->str_needles[i]; i++) { + if (strcasestr (buf, info->str_needles[i])) { + index = i; + done = TRUE; + } + } + } + } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN); + } + + if (condition & G_IO_HUP || condition & G_IO_ERR) + done = TRUE; + + if (done) { + info->callback (info->device, index, info->user_data); + + /* Clear the id - returning FALSE already removes it */ + info->got_data_id = 0; + g_source_remove (info->timeout_id); + } + + return !done; +} + +void +nm_serial_device_wait_for_reply (NMSerialDevice *device, + guint timeout, + char **responses, + NMSerialWaitForReplyFn callback, + gpointer user_data) +{ + WaitForReplyInfo *info; + char **str_array; + int i; + + g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); + g_return_if_fail (responses != NULL); + g_return_if_fail (callback != NULL); + + /* Copy the array */ + str_array = g_new (char*, g_strv_length (responses) + 1); + i = 0; + while (responses[i]) { + str_array[i] = g_strdup (responses[i]); + i++; + } + str_array[i] = NULL; + + info = g_new (WaitForReplyInfo, 1); + info->device = device; + info->str_needles = str_array; + info->callback = callback; + info->user_data = user_data; + + info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel, + G_IO_IN | G_IO_ERR | G_IO_HUP, + wait_for_reply_got_data, + info); + + info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, + timeout * 1000, + wait_for_reply_timeout, + info, + wait_for_reply_info_destroy); +} + +#if 0 +typedef struct { + NMSerialDevice *device; + gboolean timed_out; + NMSerialWaitQuietFn callback; + gpointer user_data; +} WaitQuietInfo; + +static gboolean +wait_quiet_done (gpointer data) +{ + WaitQuietInfo *info = (WaitQuietInfo *) data; + + info->callback (info->device, info->timed_out, info->user_data); + + return FALSE; +} + +static gboolean +wait_quiet_quiettime (gpointer data) +{ + WaitQuietInfo *info = (WaitQuietInfo *) data; + + info->timed_out = FALSE; + wait_quiet_done (data); + + return FALSE; +} + +static gboolean +wait_quiet_got_data (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + WaitQuietInfo *info = (WaitQuietInfo *) data; + gsize bytes_read; + char buf[4096]; + GIOStatus status; + + if (condition & G_IO_IN) { + do { + status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL); + + if (bytes_read) { + /* Reset the quiet time timeout */ + g_source_remove (info->quiet_id); + info->quiet_id = g_timeout_add (info->quiet_time, wait_quiet_quiettime, info); + } + } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN); + } + + if (condition & G_IO_HUP || condition & G_IO_ERR) { + wait_quiet_done (data); + return FALSE + } + + return TRUE; +} + +void +nm_serial_device_wait_quiet (NMSerialDevice *device, + guint timeout, + guint quiet_time, + NMSerialWaitQuietFn callback, + gpointer user_data) +{ + WaitQuietInfo *info; + + g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); + g_return_if_fail (callback != NULL); + + info = g_new (WaitQuietInfo, 1); + + info->device = device; + info->timed_out = TRUE; + info->callback = callback; + info->user_data = user_data; + + info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel, + G_IO_IN | G_IO_ERR | G_IO_HUP, + wait_quiet_got_data, + info); + + info->quiet_id = g_timeout_add (quiet_time, + wait_quiet_timeout, + info); + + info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, + timeout, + wait_quiet_timeout, + info, + wait_quiet_info_destroy); +} + +typedef struct { + NMSerialDevice *device; + int current_speed; + NMSerialFlashFn callback; + gpointer user_data; +} FlashInfo; + +static gboolean +flash_done (gpointer user_data) +{ + FlashInfo *info = (FlashInfo *) user_data; + + /* FIXME: Restore the speed */ + info->current_speed; + + info->callback (info->device, info->user_data); + + return FALSE; +} + +void +nm_serial_device_flash (NMSerialDevice *device, + guint32 flash_time, + NMSerialFlashFn callback, + gpointer user_data) +{ + int fd; + struct termio stbuf; + int speed; + FlashInfo *info; + + g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); + g_return_if_fail (callback != NULL); + + fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd; + + ioctl (fd, TCGETA, &stbuf); + speed = stbuf.c_cflags & CBAUD; + + /* FIXME: Set speed to 0 */ + + info = g_new (FlashInfo, 1); + info->device = device; + info->current_speed = speed; + info->callback = callback; + info->user_data = user_data; + + g_timeout_add_full (G_PRIORITY_DEFAULT, + flash_time, + flash_done, + info, + g_free); +} + +#endif + +static void +ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) +{ + nm_debug ("ppp state changed: %d", status); + /* FIXME */ +} + +static void +ppp_ip4_config (NMPPPManager *ppp_manager, + const char *iface, + NMIP4Config *config, + gpointer user_data) +{ + nm_debug ("got ipconfig from pppd: %s", iface); + /* FIXME */ + + nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_ACTIVATED); +} + +static NMActStageReturn +real_act_stage2_config (NMDevice *device) +{ + NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + NMSettingPPP *setting; + GError *err = NULL; + NMActStageReturn ret; + + setting = NM_SETTING_PPP (serial_device_get_setting (NM_SERIAL_DEVICE (device), NM_TYPE_SETTING_PPP)); + + priv->ppp_manager = nm_ppp_manager_new (); + + if (nm_ppp_manager_start (priv->ppp_manager, + nm_device_get_iface (device), + setting, + &err)) { + g_signal_connect (priv->ppp_manager, "state-changed", + G_CALLBACK (ppp_state_changed), + device); + g_signal_connect (priv->ppp_manager, "ip4-config", + G_CALLBACK (ppp_ip4_config), + device); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else { + nm_warning ("%s", err->message); + g_error_free (err); + + g_object_unref (priv->ppp_manager); + priv->ppp_manager = NULL; + + ret = NM_ACT_STAGE_RETURN_FAILURE; + } + + return ret; +} + +static void +real_deactivate_quickly (NMDevice *device) +{ + NMSerialDevice *self = NM_SERIAL_DEVICE (device); + NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); + + if (priv->ppp_manager) { + g_object_unref (priv->ppp_manager); + priv->ppp_manager = NULL; + } + + nm_serial_device_close (self); +} + +static gboolean +real_check_connection (NMDevice *dev, NMConnection *connection) +{ + NMSettingSerial *serial; + NMSettingPPP *ppp; + + serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); + if (!serial) { + nm_warning ("Connection check failed: serial setting not present."); + return FALSE; + } + + ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + if (!ppp) { + nm_warning ("Connection check failed: ppp setting not present."); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +nm_serial_device_init (NMSerialDevice *self) +{ +} + +static void +finalize (GObject *object) +{ + NMSerialDevice *self = NM_SERIAL_DEVICE (object); + + nm_serial_device_close (self); + + G_OBJECT_CLASS (nm_serial_device_parent_class)->finalize (object); +} + +static void +nm_serial_device_class_init (NMSerialDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMSerialDevicePrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + + parent_class->check_connection = real_check_connection; + parent_class->act_stage2_config = real_act_stage2_config; + parent_class->deactivate_quickly = real_deactivate_quickly; +} diff --git a/src/nm-serial-device.h b/src/nm-serial-device.h new file mode 100644 index 000000000..b32f8fefb --- /dev/null +++ b/src/nm-serial-device.h @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SERIAL_DEVICE_H +#define NM_SERIAL_DEVICE_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SERIAL_DEVICE (nm_serial_device_get_type ()) +#define NM_SERIAL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SERIAL_DEVICE, NMSerialDevice)) +#define NM_SERIAL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass)) +#define NM_IS_SERIAL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SERIAL_DEVICE)) +#define NM_IS_SERIAL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SERIAL_DEVICE)) +#define NM_SERIAL_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass)) + +typedef struct { + NMDevice parent; +} NMSerialDevice; + +typedef struct { + NMDeviceClass parent; +} NMSerialDeviceClass; + +GType nm_serial_device_get_type (void); + +typedef void (*NMSerialGetReplyFn) (NMSerialDevice *device, + const char *reply, + gpointer user_data); + +typedef void (*NMSerialWaitForReplyFn) (NMSerialDevice *device, + int reply_index, + gpointer user_data); + +typedef void (*NMSerialWaitQuietFn) (NMSerialDevice *device, + gboolean timed_out, + gpointer user_data); + +typedef void (*NMSerialFlashFn) (NMSerialDevice *device, + gpointer user_data); + + + +gboolean nm_serial_device_open (NMSerialDevice *device); +void nm_serial_device_close (NMSerialDevice *device); +gboolean nm_serial_device_send_command (NMSerialDevice *device, + GByteArray *command); + +gboolean nm_serial_device_send_command_string (NMSerialDevice *device, + const char *str); + +void nm_serial_device_get_reply (NMSerialDevice *device, + guint timeout, + const char *terminators, + NMSerialGetReplyFn callback, + gpointer user_data); + +void nm_serial_device_wait_for_reply (NMSerialDevice *device, + guint timeout, + char **responses, + NMSerialWaitForReplyFn callback, + gpointer user_data); + +void nm_serial_device_wait_quiet (NMSerialDevice *device, + guint timeout, + guint quiet_time, + NMSerialWaitQuietFn callback, + gpointer user_data); + +void nm_serial_device_flash (NMSerialDevice *device, + guint32 flash_time, + NMSerialFlashFn callback, + gpointer user_data); + +G_END_DECLS + +#endif /* NM_SERIAL_DEVICE_H */ diff --git a/src/nm-umts-device.c b/src/nm-umts-device.c new file mode 100644 index 000000000..de0f77f6d --- /dev/null +++ b/src/nm-umts-device.c @@ -0,0 +1,364 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include "nm-umts-device.h" +#include "nm-device-interface.h" +#include "nm-device-private.h" +#include "nm-setting-umts.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMUmtsDevice, nm_umts_device, NM_TYPE_SERIAL_DEVICE) + +NMUmtsDevice * +nm_umts_device_new (const char *udi, + const char *iface, + const char *driver) +{ + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (driver != NULL, NULL); + + return (NMUmtsDevice *) g_object_new (NM_TYPE_UMTS_DEVICE, + NM_DEVICE_INTERFACE_UDI, udi, + NM_DEVICE_INTERFACE_IFACE, iface, + NM_DEVICE_INTERFACE_DRIVER, driver, + NULL); +} + +static NMSetting * +umts_device_get_setting (NMUmtsDevice *device, GType setting_type) +{ + NMActRequest *req; + NMSetting *setting = NULL; + + req = nm_device_get_act_request (NM_DEVICE (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 +dial_done (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + gboolean success = FALSE; + + switch (reply_index) { + case 0: + nm_info ("Connected, Woo!"); + success = TRUE; + break; + case 1: + nm_info ("Busy"); + break; + case 2: + nm_warning ("No dial tone"); + break; + case 3: + nm_warning ("No carrier"); + break; + case -1: + nm_warning ("Manual registration timed out"); + break; + default: + nm_warning ("Manual registration failed"); + break; + } + + if (success) + nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device)); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); +} + +static void +do_dial (NMSerialDevice *device) +{ + NMSettingUmts *setting; + char *command; + char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL }; + + setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); + + command = g_strconcat ("ATDT", setting->number, NULL); + nm_serial_device_send_command_string (device, command); + g_free (command); + + nm_serial_device_wait_for_reply (device, 60, responses, dial_done, NULL); +} + +static void +manual_registration_done (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + switch (reply_index) { + case 0: + do_dial (device); + break; + case -1: + nm_warning ("Manual registration timed out"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + default: + nm_warning ("Manual registration failed"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + } +} + +static void +manual_registration (NMSerialDevice *device) +{ + NMSettingUmts *setting; + char *command; + char *responses[] = { "OK", "ERROR", "ERR", NULL }; + + setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); + + command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", setting->network_id); + nm_serial_device_send_command_string (device, command); + g_free (command); + + nm_serial_device_wait_for_reply (device, 30, responses, manual_registration_done, NULL); +} + +static void +get_network_done (NMSerialDevice *device, + const char *response, + gpointer user_data) +{ + if (response) + nm_info ("Associated with network: %s\n", response); + else + nm_warning ("Couldn't read active network name"); + + do_dial (device); +} + +static void +automatic_registration_get_network (NMSerialDevice *device) +{ + char terminators[] = { '\r', '\n', NULL }; + + nm_serial_device_send_command_string (device, "AT+COPS?"); + nm_serial_device_get_reply (device, 10, terminators, get_network_done, NULL); +} + +static void +automatic_registration_response (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + switch (reply_index) { + case 0: + nm_info ("Registered on Home network"); + automatic_registration_get_network (device); + break; + case 1: + nm_info ("Registered on Roaming network"); + automatic_registration_get_network (device); + break; + case -1: + nm_warning ("Automatic registration timed out"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + default: + nm_warning ("Automatic registration failed"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + } +} + +static void +automatic_registration (NMSerialDevice *device) +{ + char *responses[] = { "+CREG: 0,1", "+CREG: 0,5", NULL }; + + nm_serial_device_send_command_string (device, "AT+CREG?"); + nm_serial_device_wait_for_reply (device, 60, responses, automatic_registration_response, NULL); +} + +static void +do_register (NMSerialDevice *device) +{ + NMSettingUmts *setting; + + setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); + + if (setting->network_id) + manual_registration (device); + else + automatic_registration (device); +} + +static void +enter_pin_done (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + switch (reply_index) { + case 0: + do_register (device); + break; + case -1: + nm_warning ("Did not receive response for entered PIN"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + default: + nm_warning ("Invalid PIN"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + } +} + +static void +enter_pin (NMSerialDevice *device) +{ + NMSettingUmts *setting; + char *command; + char *responses[] = { "OK", "ERROR", "ERR", NULL }; + + setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); + + if (!setting->pin) { + /* FIXME: Ask PIN */ + nm_warning ("PIN required but not provided"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + return; + } + + command = g_strdup_printf ("AT+CPIN=\"%s\"", setting->pin); + nm_serial_device_send_command_string (device, command); + g_free (command); + + nm_serial_device_wait_for_reply (device, 3, responses, enter_pin_done, NULL); +} + +static void +enter_puk (NMSerialDevice *device) +{ + /* FIXME */ + nm_warning ("PUK entering not implemented at the moment"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); +} + +static void +check_pin_done (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + switch (reply_index) { + case 0: + do_register (device); + break; + case 1: + enter_pin (device); + break; + case 2: + enter_puk (device); + break; + case -1: + nm_warning ("PIN checking timed out"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + default: + nm_warning ("PIN checking failed"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + return; + } +} + +static void +check_pin (NMSerialDevice *device) +{ + char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL }; + + nm_serial_device_send_command_string (device, "AT+CPIN?"); + nm_serial_device_wait_for_reply (device, 3, responses, check_pin_done, NULL); +} + +static void +init_done (NMSerialDevice *device, + int reply_index, + gpointer user_data) +{ + switch (reply_index) { + case 0: + check_pin (device); + break; + case -1: + nm_warning ("Modem initialization timed out"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + break; + default: + nm_warning ("Modem initialization failed"); + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); + return; + } +} + +static NMActStageReturn +real_act_stage1_prepare (NMDevice *device) +{ + NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); + char *responses[] = { "OK", "ERR", NULL }; + + if (!nm_serial_device_open (NM_SERIAL_DEVICE (device))) + return NM_ACT_STAGE_RETURN_FAILURE; + + nm_serial_device_send_command_string (serial_device, "ATZ"); + nm_serial_device_wait_for_reply (serial_device, 3, responses, init_done, NULL); + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +static guint32 +real_get_generic_capabilities (NMDevice *dev) +{ + return NM_DEVICE_CAP_NM_SUPPORTED; +} + +static gboolean +real_check_connection (NMDevice *dev, NMConnection *connection) +{ + NMSettingUmts *umts; + + umts = (NMSettingUmts *) nm_connection_get_setting (connection, NM_TYPE_SETTING_UMTS); + if (!umts) { + nm_warning ("Connection check failed: umts setting not present."); + return FALSE; + } + + if (!umts->number) { + nm_warning ("Connection check failed: Phone number not set."); + return FALSE; + } + + return NM_DEVICE_CLASS (nm_umts_device_parent_class)->check_connection (dev, connection); +} + +/*****************************************************************************/ + +static void +nm_umts_device_init (NMUmtsDevice *self) +{ + nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_UMTS); +} + +static void +nm_umts_device_class_init (NMUmtsDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + device_class->get_generic_capabilities = real_get_generic_capabilities; + device_class->check_connection = real_check_connection; + device_class->act_stage1_prepare = real_act_stage1_prepare; +} diff --git a/src/nm-umts-device.h b/src/nm-umts-device.h new file mode 100644 index 000000000..2cfa921f2 --- /dev/null +++ b/src/nm-umts-device.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_UMTS_DEVICE_H +#define NM_UMTS_DEVICE_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_UMTS_DEVICE (nm_umts_device_get_type ()) +#define NM_UMTS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_UMTS_DEVICE, NMUmtsDevice)) +#define NM_UMTS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_UMTS_DEVICE, NMUmtsDeviceClass)) +#define NM_IS_UMTS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_UMTS_DEVICE)) +#define NM_IS_UMTS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_UMTS_DEVICE)) +#define NM_UMTS_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_UMTS_DEVICE, NMUmtsDeviceClass)) + +typedef struct { + NMSerialDevice parent; +} NMUmtsDevice; + +typedef struct { + NMSerialDeviceClass parent; +} NMUmtsDeviceClass; + +GType nm_umts_device_get_type (void); + +NMUmtsDevice *nm_umts_device_new (const char *udi, + const char *iface, + const char *driver); + +G_END_DECLS + +#endif /* NM_UMTS_DEVICE_H */ diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 73c8ff6c8..0fc7adad6 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -19,6 +19,7 @@ typedef struct { NMDBusManager *dbus_manager; DBusGProxy *proxy; + guint32 ppp_watch_id; guint32 ppp_timeout_handler; guint32 name_owner_changed_handler; } NMPPPManagerPrivate; @@ -540,6 +541,7 @@ nm_ppp_manager_start (NMPPPManager *manager, ppp_watch = g_child_watch_source_new (priv->pid); g_source_set_callback (ppp_watch, (GSourceFunc) ppp_watch_cb, manager, NULL); g_source_attach (ppp_watch, NULL); + priv->ppp_watch_id = g_source_get_id (ppp_watch); g_source_unref (ppp_watch); start_dbus_watcher (manager); @@ -576,6 +578,11 @@ nm_ppp_manager_stop (NMPPPManager *manager) priv->dbus_manager = NULL; } + if (priv->ppp_watch_id) { + g_source_remove (priv->ppp_watch_id); + priv->ppp_watch_id = 0; + } + if (priv->pid) { kill (priv->pid, SIGTERM); priv->pid = 0;