summaryrefslogtreecommitdiff
path: root/src/nm-device-modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-device-modem.c')
-rw-r--r--src/nm-device-modem.c168
1 files changed, 112 insertions, 56 deletions
diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c
index e7cd9259b..57f0bf8ef 100644
--- a/src/nm-device-modem.c
+++ b/src/nm-device-modem.c
@@ -18,6 +18,8 @@
* Copyright (C) 2009 - 2011 Red Hat, Inc.
*/
+#include "config.h"
+
#include <glib.h>
#include "nm-device-modem.h"
@@ -29,6 +31,11 @@
#include "nm-rfkill.h"
#include "nm-marshal.h"
#include "nm-logging.h"
+#include "nm-system.h"
+
+#if WITH_MODEM_MANAGER_1
+#include "nm-modem-broadband.h"
+#endif
G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE)
@@ -56,7 +63,7 @@ enum {
};
static guint signals[LAST_SIGNAL] = { 0 };
-static void real_set_enabled (NMDevice *device, gboolean enabled);
+static void set_enabled (NMDevice *device, gboolean enabled);
/*****************************************************************************/
@@ -132,7 +139,6 @@ modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
static void
modem_ip4_config_result (NMModem *self,
- const char *iface,
NMIP4Config *config,
GError *error,
gpointer user_data)
@@ -147,12 +153,18 @@ modem_ip4_config_result (NMModem *self,
error && error->message ? error->message : "(unknown)");
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
- } else {
- if (iface)
- nm_device_set_ip_iface (device, iface);
-
+ } else
nm_device_activate_schedule_ip4_config_result (device, config);
- }
+}
+
+static void
+data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
+{
+ NMDevice *self = NM_DEVICE (user_data);
+
+ /* We set the IP iface in the device as soon as we know it, so that we
+ * properly ifup it if needed */
+ nm_device_set_ip_iface (self, nm_modem_get_data_port (modem));
}
static void
@@ -161,11 +173,24 @@ modem_enabled_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
- real_set_enabled (NM_DEVICE (self), nm_modem_get_mm_enabled (priv->modem));
+ set_enabled (NM_DEVICE (self), nm_modem_get_mm_enabled (priv->modem));
g_signal_emit (G_OBJECT (self), signals[ENABLE_CHANGED], 0);
}
+static void
+modem_connected_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
+{
+ NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
+
+ if ( nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED
+ && !nm_modem_get_mm_connected (priv->modem)) {
+ /* Fail the device if the modem disconnects unexpectedly */
+ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
+ }
+}
+
/*****************************************************************************/
NMModem *
@@ -183,8 +208,7 @@ static void
device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
- NMDeviceStateReason reason,
- gpointer user_data)
+ NMDeviceStateReason reason)
{
nm_modem_device_state_changed (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
new_state,
@@ -193,15 +217,15 @@ device_state_changed (NMDevice *device,
}
static guint32
-real_get_generic_capabilities (NMDevice *device)
+get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_NM_SUPPORTED;
}
static NMConnection *
-real_get_best_auto_connection (NMDevice *device,
- GSList *connections,
- char **specific_object)
+get_best_auto_connection (NMDevice *device,
+ GSList *connections,
+ char **specific_object)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
@@ -209,9 +233,9 @@ real_get_best_auto_connection (NMDevice *device,
}
static gboolean
-real_check_connection_compatible (NMDevice *device,
- NMConnection *connection,
- GError **error)
+check_connection_compatible (NMDevice *device,
+ NMConnection *connection,
+ GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
@@ -219,11 +243,11 @@ real_check_connection_compatible (NMDevice *device,
}
static gboolean
-real_complete_connection (NMDevice *device,
- NMConnection *connection,
- const char *specific_object,
- const GSList *existing_connections,
- GError **error)
+complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
@@ -231,25 +255,29 @@ real_complete_connection (NMDevice *device,
}
static gboolean
-real_hw_is_up (NMDevice *device)
+hw_is_up (NMDevice *device)
{
- return nm_modem_hw_is_up (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device);
+ int ifindex = nm_device_get_ip_ifindex (device);
+
+ return ifindex > 0 ? nm_system_iface_is_up (ifindex) : TRUE;
}
static gboolean
-real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
+hw_bring_up (NMDevice *device, gboolean *no_firmware)
{
- return nm_modem_hw_bring_up (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, no_firmware);
+ int ifindex = nm_device_get_ip_ifindex (device);
+
+ return ifindex > 0 ? nm_system_iface_set_up (ifindex, TRUE, no_firmware) : TRUE;
}
static void
-real_deactivate (NMDevice *device)
+deactivate (NMDevice *device)
{
nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device);
}
static NMActStageReturn
-real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
+act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
NMActRequest *req;
@@ -260,7 +288,7 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
}
static NMActStageReturn
-real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
+act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{
NMActRequest *req;
@@ -271,9 +299,9 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
}
static NMActStageReturn
-real_act_stage3_ip4_config_start (NMDevice *device,
- NMIP4Config **out_config,
- NMDeviceStateReason *reason)
+act_stage3_ip4_config_start (NMDevice *device,
+ NMIP4Config **out_config,
+ NMDeviceStateReason *reason)
{
return nm_modem_stage3_ip4_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
device,
@@ -281,10 +309,16 @@ real_act_stage3_ip4_config_start (NMDevice *device,
reason);
}
+static void
+ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
+{
+ nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, config);
+}
+
static NMActStageReturn
-real_act_stage3_ip6_config_start (NMDevice *device,
- NMIP6Config **out_config,
- NMDeviceStateReason *reason)
+act_stage3_ip6_config_start (NMDevice *device,
+ NMIP6Config **out_config,
+ NMDeviceStateReason *reason)
{
return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
device,
@@ -295,13 +329,13 @@ real_act_stage3_ip6_config_start (NMDevice *device,
/*****************************************************************************/
static gboolean
-real_get_enabled (NMDevice *device)
+get_enabled (NMDevice *device)
{
return nm_modem_get_mm_enabled (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem);
}
static void
-real_set_enabled (NMDevice *device, gboolean enabled)
+set_enabled (NMDevice *device, gboolean enabled)
{
NMDeviceModem *self = NM_DEVICE_MODEM (device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
@@ -328,7 +362,9 @@ NMDevice *
nm_device_modem_new (NMModem *modem, const char *driver)
{
NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE;
- const char *type_desc = NULL;
+ NMDeviceModemCapabilities current_caps = NM_DEVICE_MODEM_CAPABILITY_NONE;
+ const gchar *type_desc = NULL;
+ const gchar *ip_iface = NULL;
g_return_val_if_fail (modem != NULL, NULL);
g_return_val_if_fail (NM_IS_MODEM (modem), NULL);
@@ -336,18 +372,31 @@ nm_device_modem_new (NMModem *modem, const char *driver)
if (NM_IS_MODEM_CDMA (modem)) {
caps = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
+ current_caps = caps;
type_desc = "CDMA/EVDO";
+ ip_iface = nm_modem_get_data_port (modem);
} else if (NM_IS_MODEM_GSM (modem)) {
caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
+ current_caps = caps;
type_desc = "GSM/UMTS";
- } else {
+ ip_iface = nm_modem_get_data_port (modem);
+ }
+#if WITH_MODEM_MANAGER_1
+ else if (NM_IS_MODEM_BROADBAND (modem)) {
+ nm_modem_broadband_get_capabilities (NM_MODEM_BROADBAND (modem), &caps, &current_caps);
+ type_desc = "Broadband";
+ /* data port not yet known in broadband modems */
+ }
+#endif
+ else {
nm_log_warn (LOGD_MB, "unhandled modem type %s", G_OBJECT_TYPE_NAME (modem));
return NULL;
}
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MODEM,
NM_DEVICE_UDI, nm_modem_get_path (modem),
- NM_DEVICE_IFACE, nm_modem_get_iface (modem),
+ NM_DEVICE_IFACE, nm_modem_get_uid (modem),
+ NM_DEVICE_IP_IFACE, ip_iface,
NM_DEVICE_DRIVER, driver,
NM_DEVICE_TYPE_DESC, type_desc,
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM,
@@ -361,7 +410,6 @@ nm_device_modem_new (NMModem *modem, const char *driver)
static void
nm_device_modem_init (NMDeviceModem *self)
{
- g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), self);
}
static void
@@ -379,6 +427,12 @@ set_modem (NMDeviceModem *self, NMModem *modem)
g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);
g_signal_connect (modem, "notify::" NM_MODEM_ENABLED, G_CALLBACK (modem_enabled_cb), self);
+ g_signal_connect (modem, "notify::" NM_MODEM_CONNECTED, G_CALLBACK (modem_connected_cb), self);
+
+ /* In the old ModemManager the data port is known from the very beginning;
+ * while in the new ModemManager the data port is set afterwards when the bearer gets
+ * created */
+ g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self);
}
static void
@@ -450,19 +504,22 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
object_class->get_property = get_property;
object_class->set_property = set_property;
- device_class->get_generic_capabilities = real_get_generic_capabilities;
- device_class->get_best_auto_connection = real_get_best_auto_connection;
- device_class->check_connection_compatible = real_check_connection_compatible;
- device_class->complete_connection = real_complete_connection;
- device_class->hw_is_up = real_hw_is_up;
- device_class->hw_bring_up = real_hw_bring_up;
- device_class->deactivate = real_deactivate;
- device_class->act_stage1_prepare = real_act_stage1_prepare;
- device_class->act_stage2_config = real_act_stage2_config;
- device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
- device_class->act_stage3_ip6_config_start = real_act_stage3_ip6_config_start;
- device_class->get_enabled = real_get_enabled;
- device_class->set_enabled = real_set_enabled;
+ device_class->get_generic_capabilities = get_generic_capabilities;
+ device_class->get_best_auto_connection = get_best_auto_connection;
+ device_class->check_connection_compatible = check_connection_compatible;
+ device_class->complete_connection = complete_connection;
+ device_class->hw_is_up = hw_is_up;
+ device_class->hw_bring_up = hw_bring_up;
+ device_class->deactivate = deactivate;
+ device_class->act_stage1_prepare = act_stage1_prepare;
+ device_class->act_stage2_config = act_stage2_config;
+ device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
+ device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
+ device_class->ip4_config_pre_commit = ip4_config_pre_commit;
+ device_class->get_enabled = get_enabled;
+ device_class->set_enabled = set_enabled;
+
+ device_class->state_changed = device_state_changed;
/* Properties */
g_object_class_install_property
@@ -488,7 +545,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */
- signals[PROPERTIES_CHANGED] =
+ signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMDeviceModemClass, properties_changed));
@@ -503,4 +560,3 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (mclass),
&dbus_glib_nm_device_modem_object_info);
}
-