2007-12-06 Tambet Ingo <tambet@gmail.com>

* 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
This commit is contained in:
Tambet Ingo
2007-12-06 14:51:43 +00:00
parent 260002e3e3
commit 50e36ce698
11 changed files with 248 additions and 113 deletions

View File

@@ -1,3 +1,43 @@
2007-12-06 Tambet Ingo <tambet@gmail.com>
* 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 <tambet@gmail.com> 2007-12-05 Tambet Ingo <tambet@gmail.com>
* src/nm-umts-device.c (dial_done): Fix the typoes in warnings. * src/nm-umts-device.c (dial_done): Fix the typoes in warnings.

View File

@@ -39,6 +39,7 @@
#include "nm-device-802-3-ethernet.h" #include "nm-device-802-3-ethernet.h"
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "NetworkManagerSystem.h"
struct NMPolicy { struct NMPolicy {
NMManager *manager; NMManager *manager;
@@ -49,16 +50,6 @@ struct NMPolicy {
static void schedule_change_check (NMPolicy *policy); 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 * static const char *
get_connection_id (NMConnection *connection) 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 static void
device_change_check_done (gpointer user_data) device_change_check_done (gpointer user_data)
{ {
@@ -552,15 +550,17 @@ NMPolicy *
nm_policy_new (NMManager *manager) nm_policy_new (NMManager *manager)
{ {
NMPolicy *policy; NMPolicy *policy;
static gboolean initialized = FALSE;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
g_return_val_if_fail (initialized == FALSE, NULL);
g_assert (global_policy == NULL);
policy = g_slice_new (NMPolicy); policy = g_slice_new (NMPolicy);
policy->manager = g_object_ref (manager); policy->manager = g_object_ref (manager);
policy->device_state_changed_idle_id = 0; 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_signal_connect (manager, "device-added",
G_CALLBACK (device_added), policy); G_CALLBACK (device_added), policy);
@@ -583,8 +583,6 @@ nm_policy_new (NMManager *manager)
g_signal_connect (manager, "connection-removed", g_signal_connect (manager, "connection-removed",
G_CALLBACK (connection_removed), policy); G_CALLBACK (connection_removed), policy);
global_policy = policy;
return policy; return policy;
} }
@@ -595,7 +593,5 @@ nm_policy_destroy (NMPolicy *policy)
g_object_unref (policy->manager); g_object_unref (policy->manager);
g_slice_free (NMPolicy, policy); g_slice_free (NMPolicy, policy);
} }
global_policy = NULL;
} }

View File

@@ -50,9 +50,6 @@
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-netlink.h" #include "nm-netlink.h"
/* FIXME: Remove this */
#include "nm-serial-device.h"
#include <netlink/route/addr.h> #include <netlink/route/addr.h>
#include <netlink/netlink.h> #include <netlink/netlink.h>
#include <netlink/utils.h> #include <netlink/utils.h>
@@ -64,7 +61,8 @@
* *
*/ */
static gboolean 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_gateway,
int ip4_dest, int ip4_dest,
int ip4_netmask, int ip4_netmask,
@@ -74,8 +72,6 @@ nm_system_device_set_ip4_route (NMDevice *dev,
gboolean success = FALSE; gboolean success = FALSE;
struct rtentry rtent; struct rtentry rtent;
struct sockaddr_in *p; struct sockaddr_in *p;
const char * iface;
NMIP4Config * config = NULL;
int err; int err;
struct rtentry rtent2; struct rtentry rtent2;
@@ -87,15 +83,12 @@ nm_system_device_set_ip4_route (NMDevice *dev,
if (ip4_gateway == 0) if (ip4_gateway == 0)
return TRUE; return TRUE;
iface = nm_device_get_iface (dev);
/* /*
* Do not add the route if the destination is on the same subnet. * Do not add the route if the destination is on the same subnet.
*/ */
config = nm_device_get_ip4_config(dev); if (iface_config &&
if (config && ((guint32)ip4_dest & nm_ip4_config_get_netmask (iface_config)) ==
((guint32)ip4_dest & nm_ip4_config_get_netmask(config)) == (nm_ip4_config_get_address (iface_config) & nm_ip4_config_get_netmask (iface_config)))
(nm_ip4_config_get_address(config) & nm_ip4_config_get_netmask(config)))
return TRUE; return TRUE;
@@ -192,32 +185,29 @@ out:
* Set IPv4 configuration of the device from an NMIP4Config object. * 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; NMNamedManager * named_mgr;
NMIP4Config * config;
struct nl_handle * nlh = NULL; struct nl_handle * nlh = NULL;
struct rtnl_addr * addr = NULL; struct rtnl_addr * addr = NULL;
int err; int err;
int len, i; int len, i;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
config = nm_device_get_ip4_config (dev);
g_return_val_if_fail (config != NULL, FALSE); g_return_val_if_fail (config != NULL, FALSE);
nm_system_delete_default_route (); nm_system_delete_default_route ();
nm_system_device_flush_addresses (dev); nm_system_device_flush_addresses_with_iface (iface);
nm_system_device_flush_routes (dev); nm_system_device_flush_routes_with_iface (iface);
nm_system_flush_arp_cache (); nm_system_flush_arp_cache ();
nlh = nm_netlink_get_default_handle (); nlh = nm_netlink_get_default_handle ();
if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT))) 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)); rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface));
if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) 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); sleep (1);
/* FIXME: This is wrong wrong wrong. But I don't know how to fix it. A virtual function to NMDevice class? */ if (route_to_iface)
if (NM_IS_SERIAL_DEVICE (dev)) nm_system_device_add_default_route_via_device_with_iface (iface);
nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev));
else 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)); nm_ip4_config_get_mss (config));
len = nm_ip4_config_get_num_static_routes (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 route = nm_ip4_config_get_static_route (config, (i * 2) + 1);
guint32 saddr = nm_ip4_config_get_static_route (config, i * 2); 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 (); 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 */ /* 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))) { if (active_device && (ad_config = nm_device_get_ip4_config (active_device))) {
nm_system_device_set_ip4_route (active_device, nm_system_device_set_ip4_route (nm_device_get_iface (active_device),
nm_ip4_config_get_gateway (ad_config), ad_config,
nm_ip4_config_get_gateway (config), nm_ip4_config_get_gateway (ad_config),
0xFFFFFFFF, nm_ip4_config_get_gateway (config),
nm_ip4_config_get_mss (config)); 0xFFFFFFFF,
nm_ip4_config_get_mss (config));
} }
if (!iface || !strlen (iface)) if (!iface || !strlen (iface))

View File

@@ -1,3 +1,5 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager -- Network link manager /* NetworkManager -- Network link manager
* *
* Dan Williams <dcbw@redhat.com> * Dan Williams <dcbw@redhat.com>
@@ -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_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, gboolean nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
const char *iface, const char *iface,
NMIP4Config *config, NMIP4Config *config,

View File

@@ -24,6 +24,7 @@
#include "nm-device.h" #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_device_type (NMDevice *dev, NMDeviceType type);
void nm_device_set_active_link (NMDevice *dev, const gboolean active); void nm_device_set_active_link (NMDevice *dev, const gboolean active);
NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self);

View File

@@ -60,6 +60,7 @@ struct _NMDevicePrivate
char * udi; char * udi;
char * iface; /* may change, could be renamed by user */ char * iface; /* may change, could be renamed by user */
char * ip_iface;
NMDeviceType type; NMDeviceType type;
guint32 capabilities; guint32 capabilities;
char * driver; 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 * 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...", nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) started...",
iface); iface);
nm_device_set_ip4_config (self, ip4_config); if (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_GET_CLASS (self)->update_link) if (NM_DEVICE_GET_CLASS (self)->update_link)
NM_DEVICE_GET_CLASS (self)->update_link (self); 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) 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) { if (priv->ip4_config) {
g_object_unref (priv->ip4_config); g_object_unref (priv->ip4_config);
priv->ip4_config = NULL; priv->ip4_config = NULL;
} }
if (config) if (!config)
priv->ip4_config = g_object_ref (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->udi);
g_free (self->priv->iface); g_free (self->priv->iface);
g_free (self->priv->ip_iface);
g_free (self->priv->driver); g_free (self->priv->driver);
G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);

View File

@@ -136,7 +136,7 @@ void nm_device_set_use_dhcp (NMDevice *dev,
gboolean use_dhcp); gboolean use_dhcp);
NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); 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); NMIP4Config *config);
gboolean nm_device_is_up (NMDevice *dev); gboolean nm_device_is_up (NMDevice *dev);

View File

@@ -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)) #define NM_SERIAL_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SERIAL_DEVICE, NMSerialDevicePrivate))
typedef struct { typedef struct {
char *serial_iface;
int fd; int fd;
GIOChannel *channel; GIOChannel *channel;
NMPPPManager *ppp_manager; NMPPPManager *ppp_manager;
@@ -440,7 +439,7 @@ get_reply_got_data (GIOChannel *source,
return !done; return !done;
} }
void guint
nm_serial_device_get_reply (NMSerialDevice *device, nm_serial_device_get_reply (NMSerialDevice *device,
guint timeout, guint timeout,
const char *terminators, const char *terminators,
@@ -449,9 +448,9 @@ nm_serial_device_get_reply (NMSerialDevice *device,
{ {
GetReplyInfo *info; GetReplyInfo *info;
g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
g_return_if_fail (terminators != NULL); g_return_val_if_fail (terminators != NULL, 0);
g_return_if_fail (callback != NULL); g_return_val_if_fail (callback != NULL, 0);
info = g_new (GetReplyInfo, 1); info = g_new (GetReplyInfo, 1);
info->device = device; info->device = device;
@@ -470,6 +469,8 @@ nm_serial_device_get_reply (NMSerialDevice *device,
get_reply_timeout, get_reply_timeout,
info, info,
get_reply_info_destroy); get_reply_info_destroy);
return info->timeout_id;
} }
typedef struct { typedef struct {
@@ -558,7 +559,7 @@ wait_for_reply_got_data (GIOChannel *source,
return !done; return !done;
} }
void guint
nm_serial_device_wait_for_reply (NMSerialDevice *device, nm_serial_device_wait_for_reply (NMSerialDevice *device,
guint timeout, guint timeout,
char **responses, char **responses,
@@ -569,9 +570,9 @@ nm_serial_device_wait_for_reply (NMSerialDevice *device,
char **str_array; char **str_array;
int i; int i;
g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
g_return_if_fail (responses != NULL); g_return_val_if_fail (responses != NULL, 0);
g_return_if_fail (callback != NULL); g_return_val_if_fail (callback != NULL, 0);
/* Copy the array */ /* Copy the array */
str_array = g_new (char*, g_strv_length (responses) + 1); 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, wait_for_reply_timeout,
info, info,
wait_for_reply_info_destroy); wait_for_reply_info_destroy);
return info->timeout_id;
} }
#if 0 #if 0
@@ -765,8 +768,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
{ {
NMDevice *device = NM_DEVICE (user_data); 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_SERIAL_DEVICE_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config);
nm_device_activate_schedule_stage4_ip_config_get (device); nm_device_activate_schedule_stage4_ip_config_get (device);
} }
@@ -824,9 +826,7 @@ real_deactivate_quickly (NMDevice *device)
NMSerialDevice *self = NM_SERIAL_DEVICE (device); NMSerialDevice *self = NM_SERIAL_DEVICE (device);
NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
/* Restore the iface (ttyUSB0 vs ppp0) */ nm_device_set_ip_iface (device, NULL);
if (!strcmp (nm_device_get_iface (device), priv->serial_iface))
g_object_set (device, NM_DEVICE_INTERFACE_IFACE, priv->serial_iface, NULL);
if (priv->pending_ip4_config) { if (priv->pending_ip4_config) {
g_object_unref (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 static void
finalize (GObject *object) finalize (GObject *object)
{ {
NMSerialDevice *self = NM_SERIAL_DEVICE (object); NMSerialDevice *self = NM_SERIAL_DEVICE (object);
NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self);
nm_serial_device_close (self); nm_serial_device_close (self);
g_free (priv->serial_iface);
G_OBJECT_CLASS (nm_serial_device_parent_class)->finalize (object); 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)); g_type_class_add_private (object_class, sizeof (NMSerialDevicePrivate));
/* Virtual methods */ /* Virtual methods */
object_class->constructor = constructor;
object_class->finalize = finalize; object_class->finalize = finalize;
parent_class->check_connection = real_check_connection; parent_class->check_connection = real_check_connection;

View File

@@ -49,13 +49,13 @@ gboolean nm_serial_device_send_command (NMSerialDevice *device,
gboolean nm_serial_device_send_command_string (NMSerialDevice *device, gboolean nm_serial_device_send_command_string (NMSerialDevice *device,
const char *str); const char *str);
void nm_serial_device_get_reply (NMSerialDevice *device, guint nm_serial_device_get_reply (NMSerialDevice *device,
guint timeout, guint timeout,
const char *terminators, const char *terminators,
NMSerialGetReplyFn callback, NMSerialGetReplyFn callback,
gpointer user_data); gpointer user_data);
void nm_serial_device_wait_for_reply (NMSerialDevice *device, guint nm_serial_device_wait_for_reply (NMSerialDevice *device,
guint timeout, guint timeout,
char **responses, char **responses,
NMSerialWaitForReplyFn callback, NMSerialWaitForReplyFn callback,

View File

@@ -19,10 +19,12 @@ typedef enum {
typedef struct { typedef struct {
NMUmtsSecret need_secret; NMUmtsSecret need_secret;
guint pending_id;
} NMUmtsDevicePrivate; } NMUmtsDevicePrivate;
static void enter_pin (NMSerialDevice *device, gboolean retry); static void enter_pin (NMSerialDevice *device, gboolean retry);
static void automatic_registration (NMSerialDevice *device);
NMUmtsDevice * NMUmtsDevice *
nm_umts_device_new (const char *udi, nm_umts_device_new (const char *udi,
@@ -40,6 +42,12 @@ nm_umts_device_new (const char *udi,
NULL); 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 * static NMSetting *
umts_device_get_setting (NMUmtsDevice *device, GType setting_type) umts_device_get_setting (NMUmtsDevice *device, GType setting_type)
{ {
@@ -65,6 +73,8 @@ dial_done (NMSerialDevice *device,
{ {
gboolean success = FALSE; gboolean success = FALSE;
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
nm_info ("Connected, Woo!"); nm_info ("Connected, Woo!");
@@ -98,6 +108,7 @@ do_dial (NMSerialDevice *device)
{ {
NMSettingUmts *setting; NMSettingUmts *setting;
char *command; char *command;
guint id;
char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL }; 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)); 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); nm_serial_device_send_command_string (device, command);
g_free (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 static void
@@ -114,6 +129,8 @@ manual_registration_done (NMSerialDevice *device,
int reply_index, int reply_index,
gpointer user_data) gpointer user_data)
{ {
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
do_dial (device); do_dial (device);
@@ -134,6 +151,7 @@ manual_registration (NMSerialDevice *device)
{ {
NMSettingUmts *setting; NMSettingUmts *setting;
char *command; char *command;
guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL }; char *responses[] = { "OK", "ERROR", "ERR", NULL };
setting = NM_SETTING_UMTS (umts_device_get_setting (NM_UMTS_DEVICE (device), NM_TYPE_SETTING_UMTS)); 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); nm_serial_device_send_command_string (device, command);
g_free (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 static void
@@ -150,6 +172,8 @@ get_network_done (NMSerialDevice *device,
const char *response, const char *response,
gpointer user_data) gpointer user_data)
{ {
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
if (response) if (response)
nm_info ("Associated with network: %s", response); nm_info ("Associated with network: %s", response);
else else
@@ -161,10 +185,22 @@ get_network_done (NMSerialDevice *device,
static void static void
automatic_registration_get_network (NMSerialDevice *device) automatic_registration_get_network (NMSerialDevice *device)
{ {
guint id;
const char terminators[] = { '\r', '\n', '\0' }; const char terminators[] = { '\r', '\n', '\0' };
nm_serial_device_send_command_string (device, "AT+COPS?"); 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 static void
@@ -172,6 +208,8 @@ automatic_registration_response (NMSerialDevice *device,
int reply_index, int reply_index,
gpointer user_data) gpointer user_data)
{ {
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
nm_info ("Registered on Home network"); nm_info ("Registered on Home network");
@@ -181,6 +219,10 @@ automatic_registration_response (NMSerialDevice *device,
nm_info ("Registered on Roaming network"); nm_info ("Registered on Roaming network");
automatic_registration_get_network (device); automatic_registration_get_network (device);
break; break;
case 2:
umts_device_set_pending (NM_UMTS_DEVICE (device),
g_timeout_add (1000, automatic_registration_again, device));
break;
case -1: case -1:
nm_warning ("Automatic registration timed out"); nm_warning ("Automatic registration timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
@@ -195,10 +237,15 @@ automatic_registration_response (NMSerialDevice *device,
static void static void
automatic_registration (NMSerialDevice *device) 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_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 static void
@@ -220,7 +267,9 @@ enter_pin_done (NMSerialDevice *device,
gpointer user_data) gpointer user_data)
{ {
NMSettingUmts *setting; NMSettingUmts *setting;
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
do_register (device); do_register (device);
@@ -286,13 +335,18 @@ enter_pin (NMSerialDevice *device, gboolean retry)
if (secret) { if (secret) {
char *command; char *command;
guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL }; char *responses[] = { "OK", "ERROR", "ERR", NULL };
command = g_strdup_printf ("AT+CPIN=\"%s\"", secret); command = g_strdup_printf ("AT+CPIN=\"%s\"", secret);
nm_serial_device_send_command_string (device, command); nm_serial_device_send_command_string (device, command);
g_free (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 { } else {
nm_info ("%s required", secret_setting_name); nm_info ("%s required", secret_setting_name);
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_NEED_AUTH);
@@ -305,6 +359,8 @@ check_pin_done (NMSerialDevice *device,
int reply_index, int reply_index,
gpointer user_data) gpointer user_data)
{ {
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
do_register (device); do_register (device);
@@ -331,10 +387,16 @@ check_pin_done (NMSerialDevice *device,
static void static void
check_pin (NMSerialDevice *device) check_pin (NMSerialDevice *device)
{ {
guint id;
char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL }; char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
nm_serial_device_send_command_string (device, "AT+CPIN?"); 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 static void
@@ -342,6 +404,8 @@ init_done (NMSerialDevice *device,
int reply_index, int reply_index,
gpointer user_data) gpointer user_data)
{ {
umts_device_set_pending (NM_UMTS_DEVICE (device), 0);
switch (reply_index) { switch (reply_index) {
case 0: case 0:
check_pin (device); check_pin (device);
@@ -360,18 +424,19 @@ init_done (NMSerialDevice *device,
static NMActStageReturn static NMActStageReturn
real_act_stage1_prepare (NMDevice *device) real_act_stage1_prepare (NMDevice *device)
{ {
NMUmtsDevicePrivate *priv = NM_UMTS_DEVICE_GET_PRIVATE (device);
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
char *responses[] = { "OK", "ERR", NULL }; 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))) if (!nm_serial_device_open (NM_SERIAL_DEVICE (device)))
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
nm_serial_device_send_command_string (serial_device, "ATZ E0"); 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 static guint32
@@ -422,6 +487,19 @@ real_connection_secrets_updated (NMDevice *dev,
nm_device_activate_schedule_stage1_device_prepare (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 static void
@@ -442,4 +520,5 @@ nm_umts_device_class_init (NMUmtsDeviceClass *klass)
device_class->check_connection = real_check_connection; device_class->check_connection = real_check_connection;
device_class->act_stage1_prepare = real_act_stage1_prepare; device_class->act_stage1_prepare = real_act_stage1_prepare;
device_class->connection_secrets_updated = real_connection_secrets_updated; device_class->connection_secrets_updated = real_connection_secrets_updated;
device_class->deactivate_quickly = real_deactivate_quickly;
} }

View File

@@ -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); 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 */ /* 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) { if (priv->banner) {