From 50e36ce69809b1574423080ea7c2bba5e30d0c68 Mon Sep 17 00:00:00 2001 From: Tambet Ingo Date: Thu, 6 Dec 2007 14:51:43 +0000 Subject: [PATCH] 2007-12-06 Tambet Ingo * src/NetworkManagerSystem.c * (nm_system_device_set_from_ip4_config): Change the arguments: This whole file shouldn't really know anything about NMDevices, it should deal only with device interfaces. Devices might have different ifaces for different stuff and this place shouldn't know anything about it. * src/NetworkManagerPolicy.c: Get rid of leftover global * variable global_policy. (global_state_changed): Implement. In the current NM it's not really important, but will be required in the case of multiple active devices. (Or even better, if stuff like that gets moved out from NM). * src/vpn-manager/nm-vpn-connection.c * (connection_state_changed): Don't call nm_system_device_set_from_ip4_config() directly, use nm_device_set_ip4_config() instead. * src/nm-device.c: Add a ip_face protected member. It's used for * 'multi-interface' devices like serial devices (ttyS0 and ppp0 for example). (nm_device_get_ip_iface): Implement. Default to the device iface if ip_iface is not set. (nm_device_set_ip_iface): Implement. (nm_device_activate_stage5_ip_config_commit): Move all the extra actions that happen after setting ip4_config from here ... (nm_device_set_ip4_config): ... to here. The reason behind it is that no other code than this function should call nm_system_device_set_from_ip4_config() because no other code has enough information on which arguments to use. So instead, other code could just set the new ip4 config using this function and everyone is happy. * src/nm-umts-device.c: Store the pending ids so that we can * remove pending actions if we happen to get deactivated while something is pending. (automatic_registration): Handle the response that indicates pending network registration and wait until the pending registration is done. (real_deactivate_quickly): If there's a pending operation, cancel it. * src/nm-serial-device.c (ppp_ip4_config): Set the ip_iface when * the iface is up ... (real_deactivate_quickly): ... and remove it when it's down. (nm_serial_device_get_reply): Return the timeout id so that the callers can remove it if needed. (nm_serial_device_wait_for_reply): Ditto. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3141 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 40 +++++++++++ src/NetworkManagerPolicy.c | 28 ++++---- src/NetworkManagerSystem.c | 55 +++++++-------- src/NetworkManagerSystem.h | 7 +- src/nm-device-private.h | 1 + src/nm-device.c | 71 +++++++++++++++---- src/nm-device.h | 2 +- src/nm-serial-device.c | 49 ++++---------- src/nm-serial-device.h | 4 +- src/nm-umts-device.c | 101 +++++++++++++++++++++++++--- src/vpn-manager/nm-vpn-connection.c | 3 +- 11 files changed, 248 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0663382272..ea02079dd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2007-12-06 Tambet Ingo + + * src/NetworkManagerSystem.c (nm_system_device_set_from_ip4_config): Change the + arguments: This whole file shouldn't really know anything about NMDevices, it + should deal only with device interfaces. Devices might have different ifaces for + different stuff and this place shouldn't know anything about it. + + * src/NetworkManagerPolicy.c: Get rid of leftover global variable global_policy. + (global_state_changed): Implement. In the current NM it's not really important, + but will be required in the case of multiple active devices. (Or even better, + if stuff like that gets moved out from NM). + + * src/vpn-manager/nm-vpn-connection.c (connection_state_changed): Don't call + nm_system_device_set_from_ip4_config() directly, use nm_device_set_ip4_config() + instead. + + * src/nm-device.c: Add a ip_face protected member. It's used for 'multi-interface' + devices like serial devices (ttyS0 and ppp0 for example). + (nm_device_get_ip_iface): Implement. Default to the device iface if ip_iface is not + set. + (nm_device_set_ip_iface): Implement. + (nm_device_activate_stage5_ip_config_commit): Move all the extra actions that happen + after setting ip4_config from here ... + (nm_device_set_ip4_config): ... to here. The reason behind it is that no other code + than this function should call nm_system_device_set_from_ip4_config() because no + other code has enough information on which arguments to use. So instead, other code + could just set the new ip4 config using this function and everyone is happy. + + * src/nm-umts-device.c: Store the pending ids so that we can remove pending actions + if we happen to get deactivated while something is pending. + (automatic_registration): Handle the response that indicates pending network + registration and wait until the pending registration is done. + (real_deactivate_quickly): If there's a pending operation, cancel it. + + * src/nm-serial-device.c (ppp_ip4_config): Set the ip_iface when the iface is up ... + (real_deactivate_quickly): ... and remove it when it's down. + (nm_serial_device_get_reply): Return the timeout id so that the callers can remove + it if needed. + (nm_serial_device_wait_for_reply): Ditto. + 2007-12-05 Tambet Ingo * src/nm-umts-device.c (dial_done): Fix the typoes in warnings. diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 0635002c87..1d6aaa4185 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -39,6 +39,7 @@ #include "nm-device-802-3-ethernet.h" #include "nm-dbus-manager.h" #include "nm-setting-connection.h" +#include "NetworkManagerSystem.h" struct NMPolicy { NMManager *manager; @@ -49,16 +50,6 @@ struct NMPolicy { static void schedule_change_check (NMPolicy *policy); -/* NMPolicy is supposed to be one of the highest classes of the - NM class hierarchy and the only public API it needs is: - NMPolicy *nm_policy_new (NMManager *manager); - void nm_policy_destroy (NMPolicy *policy); - - Until this hasn't fixed, keep the global policy around. -*/ -static NMPolicy *global_policy; - - static const char * get_connection_id (NMConnection *connection) { @@ -389,6 +380,13 @@ out: /*****************************************************************************/ +static void +global_state_changed (NMManager *manager, NMState state, gpointer user_data) +{ + if (state == NM_STATE_CONNECTED) + nm_system_restart_mdns_responder (); +} + static void device_change_check_done (gpointer user_data) { @@ -552,15 +550,17 @@ NMPolicy * nm_policy_new (NMManager *manager) { NMPolicy *policy; + static gboolean initialized = FALSE; g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - - g_assert (global_policy == NULL); + g_return_val_if_fail (initialized == FALSE, NULL); policy = g_slice_new (NMPolicy); policy->manager = g_object_ref (manager); policy->device_state_changed_idle_id = 0; + g_signal_connect (manager, "state-change", G_CALLBACK (global_state_changed), policy); + g_signal_connect (manager, "device-added", G_CALLBACK (device_added), policy); @@ -583,8 +583,6 @@ nm_policy_new (NMManager *manager) g_signal_connect (manager, "connection-removed", G_CALLBACK (connection_removed), policy); - global_policy = policy; - return policy; } @@ -595,7 +593,5 @@ nm_policy_destroy (NMPolicy *policy) g_object_unref (policy->manager); g_slice_free (NMPolicy, policy); } - - global_policy = NULL; } diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 402f48f95d..509aebbae1 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -50,9 +50,6 @@ #include "nm-utils.h" #include "nm-netlink.h" -/* FIXME: Remove this */ -#include "nm-serial-device.h" - #include #include #include @@ -64,7 +61,8 @@ * */ static gboolean -nm_system_device_set_ip4_route (NMDevice *dev, +nm_system_device_set_ip4_route (const char *iface, + NMIP4Config *iface_config, int ip4_gateway, int ip4_dest, int ip4_netmask, @@ -74,8 +72,6 @@ nm_system_device_set_ip4_route (NMDevice *dev, gboolean success = FALSE; struct rtentry rtent; struct sockaddr_in *p; - const char * iface; - NMIP4Config * config = NULL; int err; struct rtentry rtent2; @@ -87,15 +83,12 @@ nm_system_device_set_ip4_route (NMDevice *dev, if (ip4_gateway == 0) return TRUE; - iface = nm_device_get_iface (dev); - /* * Do not add the route if the destination is on the same subnet. */ - config = nm_device_get_ip4_config(dev); - if (config && - ((guint32)ip4_dest & nm_ip4_config_get_netmask(config)) == - (nm_ip4_config_get_address(config) & nm_ip4_config_get_netmask(config))) + if (iface_config && + ((guint32)ip4_dest & nm_ip4_config_get_netmask (iface_config)) == + (nm_ip4_config_get_address (iface_config) & nm_ip4_config_get_netmask (iface_config))) return TRUE; @@ -192,32 +185,29 @@ out: * Set IPv4 configuration of the device from an NMIP4Config object. * */ -gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) +gboolean +nm_system_device_set_from_ip4_config (const char *iface, + NMIP4Config *config, + gboolean route_to_iface) { NMNamedManager * named_mgr; - NMIP4Config * config; struct nl_handle * nlh = NULL; struct rtnl_addr * addr = NULL; int err; int len, i; - g_return_val_if_fail (dev != NULL, FALSE); - - config = nm_device_get_ip4_config (dev); + g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (config != NULL, FALSE); nm_system_delete_default_route (); - nm_system_device_flush_addresses (dev); - nm_system_device_flush_routes (dev); + nm_system_device_flush_addresses_with_iface (iface); + nm_system_device_flush_routes_with_iface (iface); nm_system_flush_arp_cache (); nlh = nm_netlink_get_default_handle (); if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT))) { - 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) @@ -229,11 +219,11 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) sleep (1); - /* FIXME: This is wrong wrong wrong. But I don't know how to fix it. A virtual function to NMDevice class? */ - if (NM_IS_SERIAL_DEVICE (dev)) - nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev)); + if (route_to_iface) + nm_system_device_add_default_route_via_device_with_iface (iface); else - nm_system_device_set_ip4_route (dev, nm_ip4_config_get_gateway (config), 0, 0, + nm_system_device_set_ip4_route (iface, config, + nm_ip4_config_get_gateway (config), 0, 0, nm_ip4_config_get_mss (config)); len = nm_ip4_config_get_num_static_routes (config); @@ -242,7 +232,7 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) guint32 route = nm_ip4_config_get_static_route (config, (i * 2) + 1); guint32 saddr = nm_ip4_config_get_static_route (config, i * 2); - nm_system_device_set_ip4_route (dev, route, saddr, 0xffffffff, mss); + nm_system_device_set_ip4_route (iface, config, route, saddr, 0xffffffff, mss); } named_mgr = nm_named_manager_get (); @@ -352,11 +342,12 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, /* Set up a route to the VPN gateway through the real network device */ if (active_device && (ad_config = nm_device_get_ip4_config (active_device))) { - nm_system_device_set_ip4_route (active_device, - nm_ip4_config_get_gateway (ad_config), - nm_ip4_config_get_gateway (config), - 0xFFFFFFFF, - nm_ip4_config_get_mss (config)); + nm_system_device_set_ip4_route (nm_device_get_iface (active_device), + ad_config, + nm_ip4_config_get_gateway (ad_config), + nm_ip4_config_get_gateway (config), + 0xFFFFFFFF, + nm_ip4_config_get_mss (config)); } if (!iface || !strlen (iface)) diff --git a/src/NetworkManagerSystem.h b/src/NetworkManagerSystem.h index ebfaf425cf..1c98177cfc 100644 --- a/src/NetworkManagerSystem.h +++ b/src/NetworkManagerSystem.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + /* NetworkManager -- Network link manager * * Dan Williams @@ -61,7 +63,10 @@ gboolean nm_system_device_get_use_dhcp (NMDevice *dev); gboolean nm_system_device_get_disabled (NMDevice *dev); -gboolean nm_system_device_set_from_ip4_config (NMDevice *dev); +gboolean nm_system_device_set_from_ip4_config (const char *iface, + NMIP4Config *config, + gboolean route_to_iface); + gboolean nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, const char *iface, NMIP4Config *config, diff --git a/src/nm-device-private.h b/src/nm-device-private.h index 12a5b0b48f..a48acafb56 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -24,6 +24,7 @@ #include "nm-device.h" +void nm_device_set_ip_iface (NMDevice *self, const char *iface); void nm_device_set_device_type (NMDevice *dev, NMDeviceType type); void nm_device_set_active_link (NMDevice *dev, const gboolean active); NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); diff --git a/src/nm-device.c b/src/nm-device.c index 6f3aee071e..da4a3e687c 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -60,6 +60,7 @@ struct _NMDevicePrivate char * udi; char * iface; /* may change, could be renamed by user */ + char * ip_iface; NMDeviceType type; guint32 capabilities; char * driver; @@ -249,6 +250,26 @@ nm_device_get_iface (NMDevice *self) } +static const char * +nm_device_get_ip_iface (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, NULL); + + /* If it's not set, default to iface */ + return self->priv->ip_iface ? self->priv->ip_iface : self->priv->iface; +} + + +void +nm_device_set_ip_iface (NMDevice *self, const char *iface) +{ + g_return_if_fail (NM_IS_DEVICE (self)); + + g_free (self->priv->ip_iface); + self->priv->ip_iface = iface ? g_strdup (iface) : NULL; +} + + /* * Get/set functions for driver */ @@ -897,15 +918,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data) nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) started...", iface); - nm_device_set_ip4_config (self, ip4_config); - if (nm_system_device_set_from_ip4_config (self)) { - nm_device_update_ip4_address (self); - nm_system_device_add_ip6_link_address (self); - nm_system_restart_mdns_responder (); - nm_system_set_hostname (self->priv->ip4_config); - nm_system_activate_nis (self->priv->ip4_config); - nm_system_set_mtu (self); - + if (nm_device_set_ip4_config (self, ip4_config)) { if (NM_DEVICE_GET_CLASS (self)->update_link) NM_DEVICE_GET_CLASS (self)->update_link (self); @@ -1328,20 +1341,49 @@ nm_device_get_ip4_config (NMDevice *self) } -void +gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; + const char *ip_iface; + gboolean route_to_iface; + gboolean success; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE (self); if (priv->ip4_config) { g_object_unref (priv->ip4_config); priv->ip4_config = NULL; } - if (config) - priv->ip4_config = g_object_ref (config); + if (!config) + return TRUE; + + priv->ip4_config = g_object_ref (config); + + ip_iface = nm_device_get_ip_iface (self); + + /* FIXME: Not sure if the following makes any sense. */ + /* If iface and ip_iface are the same, it's a regular network device and we + treat it as such. However, if they differ, it's most likely something like + a serial device with ppp interface, so route all the traffic to it. */ + if (strcmp (ip_iface, nm_device_get_iface (self))) + route_to_iface = TRUE; + else + route_to_iface = FALSE; + + success = nm_system_device_set_from_ip4_config (ip_iface, config, route_to_iface); + if (success) { + nm_device_update_ip4_address (self); + nm_system_device_add_ip6_link_address (self); + nm_system_set_hostname (config); + nm_system_set_mtu (self); + nm_system_activate_nis (config); + } + + return success; } @@ -1546,6 +1588,7 @@ nm_device_finalize (GObject *object) g_free (self->priv->udi); g_free (self->priv->iface); + g_free (self->priv->ip_iface); g_free (self->priv->driver); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); diff --git a/src/nm-device.h b/src/nm-device.h index 4ed69eea14..3ed8750100 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -136,7 +136,7 @@ void nm_device_set_use_dhcp (NMDevice *dev, gboolean use_dhcp); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); -void nm_device_set_ip4_config (NMDevice *dev, +gboolean nm_device_set_ip4_config (NMDevice *dev, NMIP4Config *config); gboolean nm_device_is_up (NMDevice *dev); diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c index 6ad81b2c6e..969e4c1931 100644 --- a/src/nm-serial-device.c +++ b/src/nm-serial-device.c @@ -25,7 +25,6 @@ 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 { - char *serial_iface; int fd; GIOChannel *channel; NMPPPManager *ppp_manager; @@ -440,7 +439,7 @@ get_reply_got_data (GIOChannel *source, return !done; } -void +guint nm_serial_device_get_reply (NMSerialDevice *device, guint timeout, const char *terminators, @@ -449,9 +448,9 @@ nm_serial_device_get_reply (NMSerialDevice *device, { GetReplyInfo *info; - g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); - g_return_if_fail (terminators != NULL); - g_return_if_fail (callback != NULL); + g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0); + g_return_val_if_fail (terminators != NULL, 0); + g_return_val_if_fail (callback != NULL, 0); info = g_new (GetReplyInfo, 1); info->device = device; @@ -470,6 +469,8 @@ nm_serial_device_get_reply (NMSerialDevice *device, get_reply_timeout, info, get_reply_info_destroy); + + return info->timeout_id; } typedef struct { @@ -558,7 +559,7 @@ wait_for_reply_got_data (GIOChannel *source, return !done; } -void +guint nm_serial_device_wait_for_reply (NMSerialDevice *device, guint timeout, char **responses, @@ -569,9 +570,9 @@ nm_serial_device_wait_for_reply (NMSerialDevice *device, 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); + g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0); + g_return_val_if_fail (responses != NULL, 0); + g_return_val_if_fail (callback != NULL, 0); /* Copy the array */ str_array = g_new (char*, g_strv_length (responses) + 1); @@ -598,6 +599,8 @@ nm_serial_device_wait_for_reply (NMSerialDevice *device, wait_for_reply_timeout, info, wait_for_reply_info_destroy); + + return info->timeout_id; } #if 0 @@ -765,8 +768,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, { NMDevice *device = NM_DEVICE (user_data); - g_object_set (device, NM_DEVICE_INTERFACE_IFACE, iface, NULL); - + nm_device_set_ip_iface (device, iface); NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config); nm_device_activate_schedule_stage4_ip_config_get (device); } @@ -824,9 +826,7 @@ real_deactivate_quickly (NMDevice *device) NMSerialDevice *self = NM_SERIAL_DEVICE (device); NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); - /* Restore the iface (ttyUSB0 vs ppp0) */ - if (!strcmp (nm_device_get_iface (device), priv->serial_iface)) - g_object_set (device, NM_DEVICE_INTERFACE_IFACE, priv->serial_iface, NULL); + nm_device_set_ip_iface (device, NULL); if (priv->pending_ip4_config) { g_object_unref (priv->pending_ip4_config); @@ -869,32 +869,12 @@ nm_serial_device_init (NMSerialDevice *self) { } -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - - object = G_OBJECT_CLASS (nm_serial_device_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - NM_SERIAL_DEVICE_GET_PRIVATE (object)->serial_iface = g_strdup (nm_device_get_iface (NM_DEVICE (object))); - - return object; -} - static void finalize (GObject *object) { NMSerialDevice *self = NM_SERIAL_DEVICE (object); - NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self); nm_serial_device_close (self); - g_free (priv->serial_iface); G_OBJECT_CLASS (nm_serial_device_parent_class)->finalize (object); } @@ -908,7 +888,6 @@ nm_serial_device_class_init (NMSerialDeviceClass *klass) g_type_class_add_private (object_class, sizeof (NMSerialDevicePrivate)); /* Virtual methods */ - object_class->constructor = constructor; object_class->finalize = finalize; parent_class->check_connection = real_check_connection; diff --git a/src/nm-serial-device.h b/src/nm-serial-device.h index b32f8fefbf..68e62025f3 100644 --- a/src/nm-serial-device.h +++ b/src/nm-serial-device.h @@ -49,13 +49,13 @@ gboolean nm_serial_device_send_command (NMSerialDevice *device, gboolean nm_serial_device_send_command_string (NMSerialDevice *device, const char *str); -void nm_serial_device_get_reply (NMSerialDevice *device, +guint 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 nm_serial_device_wait_for_reply (NMSerialDevice *device, guint timeout, char **responses, NMSerialWaitForReplyFn callback, diff --git a/src/nm-umts-device.c b/src/nm-umts-device.c index f76bdb470e..684faa2532 100644 --- a/src/nm-umts-device.c +++ b/src/nm-umts-device.c @@ -19,10 +19,12 @@ typedef enum { typedef struct { NMUmtsSecret need_secret; + guint pending_id; } NMUmtsDevicePrivate; static void enter_pin (NMSerialDevice *device, gboolean retry); +static void automatic_registration (NMSerialDevice *device); NMUmtsDevice * nm_umts_device_new (const char *udi, @@ -40,6 +42,12 @@ nm_umts_device_new (const char *udi, NULL); } +static inline void +umts_device_set_pending (NMUmtsDevice *device, guint pending_id) +{ + NM_UMTS_DEVICE_GET_PRIVATE (device)->pending_id = pending_id; +} + static NMSetting * umts_device_get_setting (NMUmtsDevice *device, GType setting_type) { @@ -65,6 +73,8 @@ dial_done (NMSerialDevice *device, { gboolean success = FALSE; + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: nm_info ("Connected, Woo!"); @@ -98,6 +108,7 @@ do_dial (NMSerialDevice *device) { NMSettingUmts *setting; char *command; + guint id; 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)); @@ -106,7 +117,11 @@ do_dial (NMSerialDevice *device) nm_serial_device_send_command_string (device, command); g_free (command); - nm_serial_device_wait_for_reply (device, 60, responses, dial_done, NULL); + id = nm_serial_device_wait_for_reply (device, 60, responses, dial_done, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); } static void @@ -114,6 +129,8 @@ manual_registration_done (NMSerialDevice *device, int reply_index, gpointer user_data) { + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: do_dial (device); @@ -134,6 +151,7 @@ manual_registration (NMSerialDevice *device) { NMSettingUmts *setting; char *command; + guint id; char *responses[] = { "OK", "ERROR", "ERR", NULL }; setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); @@ -142,7 +160,11 @@ manual_registration (NMSerialDevice *device) nm_serial_device_send_command_string (device, command); g_free (command); - nm_serial_device_wait_for_reply (device, 30, responses, manual_registration_done, NULL); + id = nm_serial_device_wait_for_reply (device, 30, responses, manual_registration_done, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); } static void @@ -150,6 +172,8 @@ get_network_done (NMSerialDevice *device, const char *response, gpointer user_data) { + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + if (response) nm_info ("Associated with network: %s", response); else @@ -161,10 +185,22 @@ get_network_done (NMSerialDevice *device, static void automatic_registration_get_network (NMSerialDevice *device) { + guint id; const char terminators[] = { '\r', '\n', '\0' }; nm_serial_device_send_command_string (device, "AT+COPS?"); - nm_serial_device_get_reply (device, 10, terminators, get_network_done, NULL); + id = nm_serial_device_get_reply (device, 10, terminators, get_network_done, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); +} + +static gboolean +automatic_registration_again (gpointer data) +{ + automatic_registration (NM_SERIAL_DEVICE (data)); + return FALSE; } static void @@ -172,6 +208,8 @@ automatic_registration_response (NMSerialDevice *device, int reply_index, gpointer user_data) { + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: nm_info ("Registered on Home network"); @@ -181,6 +219,10 @@ automatic_registration_response (NMSerialDevice *device, nm_info ("Registered on Roaming network"); automatic_registration_get_network (device); break; + case 2: + umts_device_set_pending (NM_UMTS_DEVICE (device), + g_timeout_add (1000, automatic_registration_again, device)); + break; case -1: nm_warning ("Automatic registration timed out"); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); @@ -195,10 +237,15 @@ automatic_registration_response (NMSerialDevice *device, static void automatic_registration (NMSerialDevice *device) { - char *responses[] = { "+CREG: 0,1", "+CREG: 0,5", NULL }; + guint id; + char *responses[] = { "+CREG: 0,1", "+CREG: 0,5", "+CREG: 0,2", NULL }; nm_serial_device_send_command_string (device, "AT+CREG?"); - nm_serial_device_wait_for_reply (device, 60, responses, automatic_registration_response, NULL); + id = nm_serial_device_wait_for_reply (device, 60, responses, automatic_registration_response, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); } static void @@ -220,7 +267,9 @@ enter_pin_done (NMSerialDevice *device, gpointer user_data) { NMSettingUmts *setting; - + + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: do_register (device); @@ -286,13 +335,18 @@ enter_pin (NMSerialDevice *device, gboolean retry) if (secret) { char *command; + guint id; char *responses[] = { "OK", "ERROR", "ERR", NULL }; command = g_strdup_printf ("AT+CPIN=\"%s\"", secret); nm_serial_device_send_command_string (device, command); g_free (command); - nm_serial_device_wait_for_reply (device, 3, responses, enter_pin_done, NULL); + id = nm_serial_device_wait_for_reply (device, 3, responses, enter_pin_done, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); } else { nm_info ("%s required", secret_setting_name); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_NEED_AUTH); @@ -305,6 +359,8 @@ check_pin_done (NMSerialDevice *device, int reply_index, gpointer user_data) { + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: do_register (device); @@ -331,10 +387,16 @@ check_pin_done (NMSerialDevice *device, static void check_pin (NMSerialDevice *device) { + guint id; 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); + + id = nm_serial_device_wait_for_reply (device, 3, responses, check_pin_done, NULL); + if (id) + umts_device_set_pending (NM_UMTS_DEVICE (device), id); + else + nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); } static void @@ -342,6 +404,8 @@ init_done (NMSerialDevice *device, int reply_index, gpointer user_data) { + umts_device_set_pending (NM_UMTS_DEVICE (device), 0); + switch (reply_index) { case 0: check_pin (device); @@ -360,18 +424,19 @@ init_done (NMSerialDevice *device, static NMActStageReturn real_act_stage1_prepare (NMDevice *device) { + NMUmtsDevicePrivate *priv = NM_UMTS_DEVICE_GET_PRIVATE (device); NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); char *responses[] = { "OK", "ERR", NULL }; - NM_UMTS_DEVICE_GET_PRIVATE (serial_device)->need_secret = NM_UMTS_SECRET_NONE; + priv->need_secret = NM_UMTS_SECRET_NONE; if (!nm_serial_device_open (NM_SERIAL_DEVICE (device))) return NM_ACT_STAGE_RETURN_FAILURE; nm_serial_device_send_command_string (serial_device, "ATZ E0"); - nm_serial_device_wait_for_reply (serial_device, 10, responses, init_done, NULL); + priv->pending_id = nm_serial_device_wait_for_reply (serial_device, 10, responses, init_done, NULL); - return NM_ACT_STAGE_RETURN_POSTPONE; + return priv->pending_id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; } static guint32 @@ -422,6 +487,19 @@ real_connection_secrets_updated (NMDevice *dev, nm_device_activate_schedule_stage1_device_prepare (dev); } +static void +real_deactivate_quickly (NMDevice *device) +{ + NMUmtsDevicePrivate *priv = NM_UMTS_DEVICE_GET_PRIVATE (device); + + if (priv->pending_id) { + g_source_remove (priv->pending_id); + priv->pending_id = 0; + } + + NM_DEVICE_CLASS (nm_umts_device_parent_class)->deactivate_quickly (device); +} + /*****************************************************************************/ static void @@ -442,4 +520,5 @@ nm_umts_device_class_init (NMUmtsDeviceClass *klass) device_class->check_connection = real_check_connection; device_class->act_stage1_prepare = real_act_stage1_prepare; device_class->connection_secrets_updated = real_connection_secrets_updated; + device_class->deactivate_quickly = real_deactivate_quickly; } diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 82e91d8189..66b97a1a47 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -726,7 +726,8 @@ connection_state_changed (NMVPNConnection *connection, nm_system_vpn_device_unset_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config); /* Reset routes, nameservers, and domains of the currently active device */ - nm_system_device_set_from_ip4_config (priv->parent_dev); + nm_device_set_ip4_config (priv->parent_dev, + NM_IP4_CONFIG (g_object_ref (nm_device_get_ip4_config (priv->parent_dev)))); } if (priv->banner) {