diff options
Diffstat (limited to 'src/nm-device-modem.c')
-rw-r--r-- | src/nm-device-modem.c | 168 |
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, ¤t_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); } - |