diff options
author | Tambet Ingo <tambet@gmail.com> | 2007-11-29 14:38:07 +0000 |
---|---|---|
committer | Tambet Ingo <tambet@gmail.com> | 2007-11-29 14:38:07 +0000 |
commit | db5a10dc4d33ebc793c21ee83e9da38e3675c132 (patch) | |
tree | 3b90c80b0bddb99b8c082eb7da95c7857cecd502 /src | |
parent | f5fb0162719b68d9c32cf82ba0af1ed82021fd86 (diff) | |
download | NetworkManager-db5a10dc4d33ebc793c21ee83e9da38e3675c132.tar.gz |
2007-11-28 Tambet Ingo <tambet@gmail.com>
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 <tambet@gmail.com>
* 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 <tambet@gmail.com>
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 <tambet@gmail.com>
* 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.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3116 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/NetworkManager.conf | 9 | ||||
-rw-r--r-- | src/NetworkManagerSystem.c | 12 | ||||
-rw-r--r-- | src/nm-device-802-11-wireless.c | 22 | ||||
-rw-r--r-- | src/nm-device-802-11-wireless.h | 9 | ||||
-rw-r--r-- | src/nm-device-802-3-ethernet.c | 31 | ||||
-rw-r--r-- | src/nm-device-802-3-ethernet.h | 9 | ||||
-rw-r--r-- | src/nm-device-interface.c | 10 | ||||
-rw-r--r-- | src/nm-device-interface.h | 2 | ||||
-rw-r--r-- | src/nm-device.c | 64 | ||||
-rw-r--r-- | src/nm-device.h | 2 | ||||
-rw-r--r-- | src/nm-hal-manager.c | 143 | ||||
-rw-r--r-- | src/nm-manager.c | 6 | ||||
-rw-r--r-- | src/nm-serial-device.c | 869 | ||||
-rw-r--r-- | src/nm-serial-device.h | 77 | ||||
-rw-r--r-- | src/nm-umts-device.c | 364 | ||||
-rw-r--r-- | src/nm-umts-device.h | 33 | ||||
-rw-r--r-- | src/ppp-manager/nm-ppp-manager.c | 7 |
18 files changed, 1518 insertions, 156 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f8c30de2ed..012d9d3316 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 18dea10b50..01dfee2590 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -4,9 +4,12 @@ <busconfig> <policy user="root"> <allow own="org.freedesktop.NetworkManager"/> - <allow send_destination="org.freedesktop.NetworkManager"/> <allow send_interface="org.freedesktop.NetworkManager"/> + + <allow own="org.freedesktop.NetworkManager.PPP"/> + <allow send_destination="org.freedesktop.NetworkManager.PPP"/> + <allow send_interface="org.freedesktop.NetworkManager.PPP"/> </policy> <policy at_console="true"> <allow send_destination="org.freedesktop.NetworkManager"/> @@ -16,6 +19,10 @@ <deny own="org.freedesktop.NetworkManager"/> <deny send_destination="org.freedesktop.NetworkManager"/> <deny send_interface="org.freedesktop.NetworkManager"/> + + <deny own="org.freedesktop.NetworkManager.PPP"/> + <deny send_destination="org.freedesktop.NetworkManager.PPP"/> + <deny send_interface="org.freedesktop.NetworkManager.PPP"/> </policy> <limit name="max_replies_per_connection">512</limit> diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 97db4acad1..9c77fa3b54 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 9c14108631..e68c7cbca6 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 e7b7dd4c40..cfd17bdbca 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 <dcbw@redhat.com> @@ -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 6124ad6575..589b83805f 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 0413ff8400..45734bc49f 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 <dcbw@redhat.com> @@ -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 a2bb770856..d2d62f9725 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -56,19 +56,11 @@ nm_device_interface_init (gpointer g_iface) 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 b33ad79f41..124c91427f 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 74f14c326b..6f3aee071e 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); @@ -246,14 +230,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) { g_return_val_if_fail (self != NULL, NULL); @@ -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; @@ -1688,10 +1654,6 @@ nm_device_class_init (NMDeviceClass *klass) 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 ea2b735b5c..4ed69eea14 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 3f63c62f1a..03def21262 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 5744b4deca..b28bc03eef 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 0000000000..9fcc9b53dd --- /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 <termio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <string.h> +#include <glib.h> + +#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 0000000000..b32f8fefbf --- /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 <nm-device.h> + +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 0000000000..de0f77f6db --- /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 0000000000..2cfa921f2a --- /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 <nm-serial-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 ((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 73c8ff6c8f..0fc7adad6a 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; |