summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-02-21 09:45:40 -0600
committerDan Williams <dcbw@redhat.com>2014-02-21 09:45:40 -0600
commit255cc3f70783a7f94f7ba857217fa920a67a7c1b (patch)
tree7e830e85ff896d932a049452fdc371e04f4bdbb8
parentf8dcab53d9ccdb9203d2f63872926c83413add52 (diff)
parent19089fb9609c5a62a3cfe5ff81e3d3d93beabeb3 (diff)
downloadNetworkManager-255cc3f70783a7f94f7ba857217fa920a67a7c1b.tar.gz
merge: various WWAN fixes
-rw-r--r--src/devices/nm-device-bt.c10
-rw-r--r--src/devices/nm-device-modem.c10
-rw-r--r--src/modem-manager/nm-modem-broadband.c97
-rw-r--r--src/modem-manager/nm-modem-old.c30
-rw-r--r--src/modem-manager/nm-modem.c95
-rw-r--r--src/modem-manager/nm-modem.h8
-rw-r--r--src/nm-manager.c29
7 files changed, 162 insertions, 117 deletions
diff --git a/src/devices/nm-device-bt.c b/src/devices/nm-device-bt.c
index e22c96eee3..3e5b693354 100644
--- a/src/devices/nm-device-bt.c
+++ b/src/devices/nm-device-bt.c
@@ -423,7 +423,15 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
static void
modem_auth_requested (NMModem *modem, gpointer user_data)
{
- nm_device_state_changed (NM_DEVICE (user_data),
+ NMDevice *device = NM_DEVICE (user_data);
+
+ /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled
+ * during activation.
+ */
+ if (!nm_device_is_activating (device))
+ return;
+
+ nm_device_state_changed (device,
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_NONE);
}
diff --git a/src/devices/nm-device-modem.c b/src/devices/nm-device-modem.c
index 0bed60cd80..e047c03e11 100644
--- a/src/devices/nm-device-modem.c
+++ b/src/devices/nm-device-modem.c
@@ -113,7 +113,15 @@ modem_prepare_result (NMModem *modem,
static void
modem_auth_requested (NMModem *modem, gpointer user_data)
{
- nm_device_state_changed (NM_DEVICE (user_data),
+ NMDevice *device = NM_DEVICE (user_data);
+
+ /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled
+ * during activation.
+ */
+ if (!nm_device_is_activating (device))
+ return;
+
+ nm_device_state_changed (device,
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_NONE);
}
diff --git a/src/modem-manager/nm-modem-broadband.c b/src/modem-manager/nm-modem-broadband.c
index 032557de99..f368c2e0ac 100644
--- a/src/modem-manager/nm-modem-broadband.c
+++ b/src/modem-manager/nm-modem-broadband.c
@@ -124,6 +124,20 @@ get_capabilities (NMModem *_self,
*current_caps = (NMDeviceModemCapabilities) mm_modem_get_current_capabilities (self->priv->modem_iface);
}
+static gboolean
+owns_port (NMModem *_self, const char *iface)
+{
+ NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
+ const MMModemPortInfo *ports = NULL;
+ guint n_ports = 0, i;
+ gboolean owns = FALSE;
+
+ mm_modem_peek_ports (self->priv->modem_iface, &ports, &n_ports);
+ for (i = 0; i < n_ports && !owns; i++)
+ owns = (g_strcmp0 (iface, ports[i].name) == 0);
+ return owns;
+}
+
/*****************************************************************************/
static void
@@ -296,47 +310,34 @@ create_gsm_connect_properties (NMConnection *connection)
static NMActStageReturn
act_stage1_prepare (NMModem *_self,
- NMActRequest *req,
- GPtrArray **out_hints,
- const char **out_setting_name,
+ NMConnection *connection,
NMDeviceStateReason *reason)
{
NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
- NMConnection *connection;
+ MMModemCapability caps;
- connection = nm_act_request_get_connection (req);
- g_assert (connection);
-
- *out_setting_name = nm_connection_need_secrets (connection, out_hints);
- if (!*out_setting_name) {
- MMModemCapability caps;
-
- caps = mm_modem_get_current_capabilities (self->priv->modem_iface);
-
- g_clear_object (&self->priv->connect_properties);
+ g_clear_object (&self->priv->connect_properties);
- if (MODEM_CAPS_3GPP (caps))
- self->priv->connect_properties = create_gsm_connect_properties (connection);
- else if (MODEM_CAPS_3GPP2 (caps))
- self->priv->connect_properties = create_cdma_connect_properties (connection);
- else {
- nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem",
- nm_modem_get_uid (NM_MODEM (self)));
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
+ caps = mm_modem_get_current_capabilities (self->priv->modem_iface);
+ if (MODEM_CAPS_3GPP (caps))
+ self->priv->connect_properties = create_gsm_connect_properties (connection);
+ else if (MODEM_CAPS_3GPP2 (caps))
+ self->priv->connect_properties = create_cdma_connect_properties (connection);
+ else {
+ nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem",
+ nm_modem_get_uid (NM_MODEM (self)));
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
- if (!self->priv->simple_iface)
- self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object);
+ if (!self->priv->simple_iface)
+ self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object);
- g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->priv->simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000);
- mm_modem_simple_connect (self->priv->simple_iface,
- self->priv->connect_properties,
- NULL,
- (GAsyncReadyCallback)connect_ready,
- g_object_ref (self));
- } else {
- /* NMModem will handle requesting secrets... */
- }
+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->priv->simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000);
+ mm_modem_simple_connect (self->priv->simple_iface,
+ self->priv->connect_properties,
+ NULL,
+ (GAsyncReadyCallback)connect_ready,
+ g_object_ref (self));
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -614,14 +615,16 @@ static gboolean
ip_string_to_network_address (const gchar *str,
guint32 *out)
{
- guint32 addr;
+ guint32 addr = 0;
+ gboolean success = FALSE;
- /* IP address */
- if (inet_pton (AF_INET, str, &addr) <= 0)
- return FALSE;
+ if (!str || inet_pton (AF_INET, str, &addr) != 1)
+ addr = 0;
+ else
+ success = TRUE;
*out = (guint32)addr;
- return TRUE;
+ return success;
}
static gboolean
@@ -630,7 +633,9 @@ static_stage3_done (NMModemBroadband *self)
GError *error = NULL;
NMIP4Config *config = NULL;
const gchar *address_string;
+ const gchar *gw_string;
guint32 address_network;
+ guint32 gw;
NMPlatformIP4Address address;
const gchar **dns;
guint i;
@@ -651,6 +656,10 @@ static_stage3_done (NMModemBroadband *self)
goto out;
}
+ /* Missing gateway not a hard failure */
+ gw_string = mm_bearer_ip_config_get_gateway (self->priv->ipv4_config);
+ ip_string_to_network_address (gw_string, &gw);
+
config = nm_ip4_config_new ();
memset (&address, 0, sizeof (address));
@@ -659,9 +668,12 @@ static_stage3_done (NMModemBroadband *self)
address.source = NM_PLATFORM_SOURCE_WWAN;
nm_ip4_config_add_address (config, &address);
- nm_log_info (LOGD_MB, " address %s/%d",
- mm_bearer_ip_config_get_address (self->priv->ipv4_config),
- mm_bearer_ip_config_get_prefix (self->priv->ipv4_config));
+ nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen);
+
+ if (gw) {
+ nm_ip4_config_set_gateway (config, gw);
+ nm_log_info (LOGD_MB, " gateway %s", gw_string);
+ }
/* DNS servers */
dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config);
@@ -929,6 +941,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass)
modem_class->check_connection_compatible = check_connection_compatible;
modem_class->complete_connection = complete_connection;
modem_class->act_stage1_prepare = act_stage1_prepare;
+ modem_class->owns_port = owns_port;
/* Properties */
g_object_class_install_property
diff --git a/src/modem-manager/nm-modem-old.c b/src/modem-manager/nm-modem-old.c
index 866a94a122..f8bbcebb85 100644
--- a/src/modem-manager/nm-modem-old.c
+++ b/src/modem-manager/nm-modem-old.c
@@ -538,33 +538,21 @@ G_GNUC_END_IGNORE_DEPRECATIONS
static NMActStageReturn
act_stage1_prepare (NMModem *modem,
- NMActRequest *req,
- GPtrArray **out_hints,
- const char **out_setting_name,
+ NMConnection *connection,
NMDeviceStateReason *reason)
{
NMModemOld *self = NM_MODEM_OLD (modem);
NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self);
- NMConnection *connection;
+ gboolean enabled = nm_modem_get_mm_enabled (modem);
- connection = nm_act_request_get_connection (req);
- g_assert (connection);
-
- *out_setting_name = nm_connection_need_secrets (connection, out_hints);
- if (!*out_setting_name) {
- gboolean enabled = nm_modem_get_mm_enabled (modem);
-
- if (priv->connect_properties)
- g_hash_table_destroy (priv->connect_properties);
- priv->connect_properties = create_connect_properties (connection);
+ if (priv->connect_properties)
+ g_hash_table_destroy (priv->connect_properties);
+ priv->connect_properties = create_connect_properties (connection);
- if (enabled)
- do_connect (self);
- else
- do_enable (self);
- } else {
- /* NMModem will handle requesting secrets... */
- }
+ if (enabled)
+ do_connect (self);
+ else
+ do_enable (self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 998decaa4e..e88ebe1bd7 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -416,9 +416,7 @@ nm_modem_get_secrets (NMModem *self,
static NMActStageReturn
act_stage1_prepare (NMModem *modem,
- NMActRequest *req,
- GPtrArray **out_hints,
- const char **out_setting_name,
+ NMConnection *connection,
NMDeviceStateReason *reason)
{
*reason = NM_DEVICE_STATE_REASON_UNKNOWN;
@@ -435,37 +433,43 @@ nm_modem_act_stage1_prepare (NMModem *self,
GPtrArray *hints = NULL;
const char *setting_name = NULL;
NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+ NMConnection *connection;
if (priv->act_request)
g_object_unref (priv->act_request);
priv->act_request = g_object_ref (req);
- ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self,
- req,
- &hints,
- &setting_name,
- reason);
- if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
- if (priv->secrets_tries++)
- flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
-
- priv->secrets_id = nm_act_request_get_secrets (req,
- setting_name,
- flags,
- hints ? g_ptr_array_index (hints, 0) : NULL,
- modem_secrets_cb,
- self);
- if (priv->secrets_id)
- g_signal_emit (self, signals[AUTH_REQUESTED], 0);
- else {
- *reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
- ret = NM_ACT_STAGE_RETURN_FAILURE;
- }
+ connection = nm_act_request_get_connection (req);
+ g_assert (connection);
+
+ setting_name = nm_connection_need_secrets (connection, &hints);
+ if (!setting_name) {
+ /* Ready to connect */
+ g_assert (!hints);
+ return NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, connection, reason);
+ }
- if (hints)
- g_ptr_array_free (hints, TRUE);
+ /* Secrets required... */
+ if (priv->secrets_tries++)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+
+ priv->secrets_id = nm_act_request_get_secrets (req,
+ setting_name,
+ flags,
+ hints ? g_ptr_array_index (hints, 0) : NULL,
+ modem_secrets_cb,
+ self);
+ if (priv->secrets_id) {
+ g_signal_emit (self, signals[AUTH_REQUESTED], 0);
+ ret = NM_ACT_STAGE_RETURN_POSTPONE;
+ } else {
+ *reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
+ ret = NM_ACT_STAGE_RETURN_FAILURE;
}
+ if (hints)
+ g_ptr_array_free (hints, TRUE);
+
return ret;
}
@@ -581,27 +585,21 @@ nm_modem_device_state_changed (NMModem *self,
g_return_if_fail (NM_IS_MODEM (self));
- if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_ACTIVATED)
+ if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_DEACTIVATING)
was_connected = TRUE;
priv = NM_MODEM_GET_PRIVATE (self);
/* Make sure we don't leave the serial device open */
switch (new_state) {
- case NM_DEVICE_STATE_NEED_AUTH:
- if (priv->ppp_manager)
- break;
- /* else fall through */
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
- case NM_DEVICE_STATE_FAILED:
case NM_DEVICE_STATE_DISCONNECTED:
- if (new_state != NM_DEVICE_STATE_NEED_AUTH) {
- if (priv->act_request) {
- cancel_get_secrets (self);
- g_object_unref (priv->act_request);
- priv->act_request = NULL;
- }
+ case NM_DEVICE_STATE_FAILED:
+ if (priv->act_request) {
+ cancel_get_secrets (self);
+ g_object_unref (priv->act_request);
+ priv->act_request = NULL;
}
if (was_connected) {
@@ -663,6 +661,27 @@ nm_modem_get_data_port (NMModem *self)
NM_MODEM_GET_PRIVATE (self)->ppp_iface : NM_MODEM_GET_PRIVATE (self)->data_port;
}
+gboolean
+nm_modem_owns_port (NMModem *self, const char *iface)
+{
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
+
+ g_return_val_if_fail (iface != NULL, FALSE);
+
+ if (NM_MODEM_GET_CLASS (self)->owns_port)
+ return NM_MODEM_GET_CLASS (self)->owns_port (self, iface);
+
+ /* Fall back to data/control ports */
+ if (priv->ppp_iface && (strcmp (priv->ppp_iface, iface) == 0))
+ return TRUE;
+ if (priv->data_port && (strcmp (priv->data_port, iface) == 0))
+ return TRUE;
+ if (priv->control_port && (strcmp (priv->control_port, iface) == 0))
+ return TRUE;
+
+ return FALSE;
+}
+
/*****************************************************************************/
void
diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h
index 8d754eb35c..db20407006 100644
--- a/src/modem-manager/nm-modem.h
+++ b/src/modem-manager/nm-modem.h
@@ -95,9 +95,7 @@ typedef struct {
GError **error);
NMActStageReturn (*act_stage1_prepare) (NMModem *modem,
- NMActRequest *req,
- GPtrArray **out_hints,
- const char **out_setting_name,
+ NMConnection *connection,
NMDeviceStateReason *reason);
NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self,
@@ -110,6 +108,8 @@ typedef struct {
void (*deactivate) (NMModem *self, NMDevice *device);
+ gboolean (*owns_port) (NMModem *self, const char *iface);
+
/* Signals */
void (*ppp_stats) (NMModem *self, guint32 in_bytes, guint32 out_bytes);
void (*ppp_failed) (NMModem *self, NMDeviceStateReason reason);
@@ -129,6 +129,8 @@ const char *nm_modem_get_control_port (NMModem *modem);
const char *nm_modem_get_data_port (NMModem *modem);
const char *nm_modem_get_driver (NMModem *modem);
+gboolean nm_modem_owns_port (NMModem *modem, const char *iface);
+
void nm_modem_get_capabilities (NMModem *self,
NMDeviceModemCapabilities *modem_caps,
NMDeviceModemCapabilities *current_caps);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 3ae48c8538..7cb71a63c7 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -550,19 +550,22 @@ modem_added (NMModemManager *modem_manager,
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- NMDevice *replace_device, *device = NULL;
+ NMDevice *device = NULL;
const char *modem_iface;
- GSList *iter;
+ GSList *iter, *remove = NULL;
- /* Don't rely only on the data port; use the control port if available */
- modem_iface = nm_modem_get_data_port (modem);
- if (!modem_iface)
- modem_iface = nm_modem_get_control_port (modem);
- g_return_if_fail (modem_iface);
-
- replace_device = find_device_by_ip_iface (NM_MANAGER (user_data), modem_iface);
- if (replace_device)
- remove_device (NM_MANAGER (user_data), replace_device, FALSE);
+ /* Remove ethernet devices that are actually owned by the modem, since
+ * they cannot be used as normal ethernet.
+ */
+ for (iter = priv->devices; iter; iter = iter->next) {
+ if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_ETHERNET) {
+ if (nm_modem_owns_port (modem, nm_device_get_ip_iface (iter->data)))
+ remove = g_slist_prepend (remove, iter->data);
+ }
+ }
+ for (iter = remove; iter; iter = iter->next)
+ remove_device (self, NM_DEVICE (iter->data), FALSE);
+ g_slist_free (remove);
/* Give Bluetooth DUN devices first chance to claim the modem */
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
@@ -577,6 +580,10 @@ modem_added (NMModemManager *modem_manager,
* by the Bluetooth code during the connection process.
*/
if (driver && !strcmp (driver, "bluetooth")) {
+ modem_iface = nm_modem_get_data_port (modem);
+ if (!modem_iface)
+ modem_iface = nm_modem_get_control_port (modem);
+
nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", modem_iface);
return;
}