diff options
Diffstat (limited to 'src/devices/wwan')
| -rw-r--r-- | src/devices/wwan/Makefile.am | 19 | ||||
| -rw-r--r-- | src/devices/wwan/Makefile.in | 46 | ||||
| -rw-r--r-- | src/devices/wwan/README | 45 | ||||
| -rw-r--r-- | src/devices/wwan/exports.ver | 1 | ||||
| -rw-r--r-- | src/devices/wwan/nm-device-modem.c | 207 | ||||
| -rw-r--r-- | src/devices/wwan/nm-device-modem.h | 6 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-broadband.c | 283 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-broadband.h | 7 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-enum-types.c | 34 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-enum-types.h | 6 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-manager.c | 460 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-manager.h | 6 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-old-types.h | 70 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-old.c | 1139 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-old.h | 53 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 482 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.h | 74 | ||||
| -rw-r--r-- | src/devices/wwan/nm-wwan-factory.c | 28 | ||||
| -rw-r--r-- | src/devices/wwan/nm-wwan-factory.h | 6 | ||||
| -rw-r--r-- | src/devices/wwan/wwan-exports.ver | 2 |
20 files changed, 993 insertions, 1981 deletions
diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 988f4679..7e5b190b 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -5,18 +5,16 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) @@ -33,9 +31,8 @@ nm_modem_enum_types_sources = $(srcdir)/nm-modem.h BUILT_SOURCES += $(GLIB_GENERATED) libnm_wwan_la_SOURCES = \ - nm-modem-old.c \ - nm-modem-old.h \ - nm-modem-old-types.h \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ nm-modem-manager.c \ nm-modem-manager.h \ nm-modem.c \ @@ -43,12 +40,6 @@ libnm_wwan_la_SOURCES = \ \ $(GLIB_GENERATED) -if WITH_MODEM_MANAGER_1 -libnm_wwan_la_SOURCES += \ - nm-modem-broadband.c \ - nm-modem-broadband.h -endif - WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index ae33d1c8..18cbfdd3 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -78,13 +78,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_MODEM_MANAGER_1_TRUE@am__append_1 = \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.c \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.h - subdir = src/devices/wwan DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp README + $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -151,15 +147,9 @@ libnm_device_plugin_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ libnm_wwan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) -am__libnm_wwan_la_SOURCES_DIST = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h nm-modem-enum-types.h \ - nm-modem-enum-types.c nm-modem-broadband.c \ - nm-modem-broadband.h am__objects_1 = nm-modem-enum-types.lo -@WITH_MODEM_MANAGER_1_TRUE@am__objects_2 = nm-modem-broadband.lo -am_libnm_wwan_la_OBJECTS = nm-modem-old.lo nm-modem-manager.lo \ - nm-modem.lo $(am__objects_1) $(am__objects_2) +am_libnm_wwan_la_OBJECTS = nm-modem-broadband.lo nm-modem-manager.lo \ + nm-modem.lo $(am__objects_1) libnm_wwan_la_OBJECTS = $(am_libnm_wwan_la_OBJECTS) libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -201,7 +191,7 @@ am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ $(libnm_wwan_la_SOURCES) DIST_SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ - $(am__libnm_wwan_la_SOURCES_DIST) + $(libnm_wwan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -236,6 +226,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -359,6 +351,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -378,6 +371,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -404,7 +398,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -486,18 +480,16 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) nm-device-modem-glue.h @@ -508,9 +500,16 @@ GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM nm_modem_enum_types_sources = $(srcdir)/nm-modem.h -libnm_wwan_la_SOURCES = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h $(GLIB_GENERATED) $(am__append_1) +libnm_wwan_la_SOURCES = \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ + nm-modem-manager.c \ + nm-modem-manager.h \ + nm-modem.c \ + nm-modem.h \ + \ + $(GLIB_GENERATED) + WWAN_SYMBOL_VIS_FILE = $(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ -avoid-version \ @@ -624,7 +623,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-broadband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-enum-types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-old.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wwan-factory.Plo@am__quote@ diff --git a/src/devices/wwan/README b/src/devices/wwan/README deleted file mode 100644 index 4661c042..00000000 --- a/src/devices/wwan/README +++ /dev/null @@ -1,45 +0,0 @@ - -ModemManager integration is organized as follows: - - -Common source -******************************************************************************** - - * nm-modem.[h|c]: - Defines the basic `NMModem' object. The core NetworkManager implementation - will use this interface exclusively, regardless of the real final type of - the modem object. - - * nm-modem-manager.[h|c]: - Defines the `NMModemManager' object, which takes care of listening to - signals from the DBus interface notifying about added or removed modems. - It also takes care of creating proper `NMModem' objects from the - information retrieved from the DBus interface. - - -ModemManager 0.7 integration -******************************************************************************** - - * nm-modem-broadband.[h|c]: - Defines the `NMModemBroadband' object, which is a subclass of `NMModem'. - This object handles both 3GPP and 3GPP2 modems exposed in the new - `ModemManager1' interface. - - -ModemManager 0.4/0.5/0.6 integration -******************************************************************************** - - * nm-modem-old-types.h: - Defines helper types to use with the (old) ModemManager DBus API. - - * nm-modem-old.[h|c]: - Defines the `NMModemGeneric' object. All modem objects based on the old - ModemManager interface are subclasses of this one. - - * nm-modem-gsm.[h|c]: - Defines the `NMModemGsm' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP-specific (GSM, UMTS, HSPA, LTE) modems. - - * nm-modem-cdma.[h|c]: - Defines the `NMModemCdma' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP2-specific modems (CDMA, EV-DO). diff --git a/src/devices/wwan/exports.ver b/src/devices/wwan/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wwan/exports.ver +++ b/src/devices/wwan/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 678f7795..f681e59c 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -20,20 +20,22 @@ #include "config.h" +#include <string.h> #include <glib.h> #include "nm-device-modem.h" #include "nm-modem.h" -#include "nm-modem-old.h" #include "nm-device-private.h" #include "nm-rfkill-manager.h" #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-settings-connection.h" - -#if WITH_MODEM_MANAGER_1 #include "nm-modem-broadband.h" -#endif +#include "NetworkManagerUtils.h" +#include "nm-core-internal.h" + +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceModem); G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) @@ -91,7 +93,8 @@ modem_prepare_result (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); NMDeviceState state; state = nm_device_get_state (device); @@ -106,8 +109,7 @@ modem_prepare_result (NMModem *modem, * the SIM if the incorrect PIN continues to be used. */ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL); - nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN", - nm_device_get_iface (device)); + _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN"); } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); @@ -147,33 +149,110 @@ modem_auth_result (NMModem *modem, GError *error, gpointer user_data) } static void -modem_ip4_config_result (NMModem *self, +modem_ip4_config_result (NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { - nm_log_warn (LOGD_MB | LOGD_IP4, "retrieving IP4 configuration failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else - nm_device_activate_schedule_ip4_config_result (device, config); + } else { + nm_device_set_wwan_ip4_config (device, config); + nm_device_activate_schedule_ip4_config_result (device, NULL); + } +} + +static void +modem_ip6_config_result (NMModem *modem, + NMIP6Config *config, + gboolean do_slaac, + GError *error, + gpointer user_data) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); + NMActStageReturn ret; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMIP6Config *ignored = NULL; + gboolean got_config = !!config; + + g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); + + if (error) { + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); + + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + /* Re-enable IPv6 on the interface */ + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "0"); + + if (config) + nm_device_set_wwan_ip6_config (device, config); + + if (do_slaac == FALSE) { + if (got_config) + nm_device_activate_schedule_ip6_config_result (device); + else { + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + return; + } + + /* Start SLAAC now that we have a link-local address from the modem */ + ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip6_config_start (device, &ignored, &reason); + g_assert (ignored == NULL); + switch (ret) { + case NM_ACT_STAGE_RETURN_FAILURE: + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + break; + case NM_ACT_STAGE_RETURN_STOP: + /* all done */ + nm_device_activate_schedule_ip6_config_result (device); + break; + case NM_ACT_STAGE_RETURN_POSTPONE: + /* let SLAAC run */ + break; + default: + /* Should never get here since we've assured that the IPv6 method + * will either be "auto" or "ignored" when starting IPv6 configuration. + */ + g_assert_not_reached (); + } } static void data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); + const char *old = nm_device_get_ip_iface (self); + const char *new = nm_modem_get_data_port (modem); + gboolean changed = FALSE; + + if (new && g_strcmp0 (new, old)) + changed = TRUE; /* 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)); + nm_device_set_ip_iface (self, new); + + /* Disable IPv6 immediately on the interface since NM handles IPv6 + * internally, and leaving it enabled could allow the kernel's IPv6 + * RA handling code to run before NM is ready. + */ + if (changed) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); } static void @@ -258,6 +337,7 @@ device_state_changed (NMDevice *device, NMDeviceState old_state, NMDeviceStateReason reason) { + NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMConnection *connection = nm_device_get_connection (device); @@ -266,9 +346,8 @@ device_state_changed (NMDevice *device, if (new_state == NM_DEVICE_STATE_UNAVAILABLE && old_state < NM_DEVICE_STATE_UNAVAILABLE) { /* Log initial modem state */ - nm_log_info (LOGD_MB, "(%s): modem state '%s'", - nm_device_get_iface (device), - nm_modem_state_to_string (nm_modem_get_state (priv->modem))); + _LOGI (LOGD_MB, "modem state '%s'", + nm_modem_state_to_string (nm_modem_get_state (priv->modem))); } nm_modem_device_state_changed (priv->modem, new_state, old_state, reason); @@ -294,10 +373,10 @@ device_state_changed (NMDevice *device, } } -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) +static guint32 +get_generic_capabilities (NMDevice *device) { - return 0; + return NM_DEVICE_CAP_IS_NON_KERNEL; } static gboolean @@ -404,11 +483,24 @@ act_stage3_ip6_config_start (NMDevice *device, NMDeviceStateReason *reason) { return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), + nm_device_get_act_request (device), reason); } +static gboolean +get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + gboolean success; + + g_return_val_if_fail (priv->modem, FALSE); + success = nm_modem_get_iid (priv->modem, out_iid); + if (!success) + success = NM_DEVICE_CLASS (nm_device_modem_parent_class)->get_ip_iface_identifier (device, out_iid); + return success; +} + /*****************************************************************************/ static gboolean @@ -444,23 +536,22 @@ set_enabled (NMDevice *device, gboolean enabled) } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (dev); + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMModemState modem_state; if (!priv->rf_enabled) { - nm_log_dbg (LOGD_MB, "(%s): not available because WWAN airplane mode is on", - nm_device_get_iface (dev)); + _LOGD (LOGD_MB, "not available because WWAN airplane mode is on"); return FALSE; } g_assert (priv->modem); modem_state = nm_modem_get_state (priv->modem); if (modem_state <= NM_MODEM_STATE_INITIALIZING) { - nm_log_dbg (LOGD_MB, "(%s): not available because modem is not ready (%s)", - nm_device_get_iface (dev), - nm_modem_state_to_string (modem_state)); + _LOGD (LOGD_MB, "not available because modem is not ready (%s)", + nm_modem_state_to_string (modem_state)); return FALSE; } @@ -496,8 +587,10 @@ nm_device_modem_new (NMModem *modem) /* If the data port is known, set it as the IP interface immediately */ data_port = nm_modem_get_data_port (modem); - if (data_port) + if (data_port) { nm_device_set_ip_iface (device, data_port); + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); + } return device; } @@ -508,6 +601,18 @@ nm_device_modem_init (NMDeviceModem *self) } static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object); + + /* DHCP is always done by the modem firmware, not by the network, and + * by the time we get around to DHCP the firmware should already know + * the IP addressing details. So the DHCP timeout can be much shorter. + */ + nm_device_set_dhcp_timeout (NM_DEVICE (object), 15); +} + +static void set_modem (NMDeviceModem *self, NMModem *modem) { NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); @@ -519,6 +624,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); + g_signal_connect (modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK (modem_ip6_config_result), self); 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, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); @@ -599,8 +705,9 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; + object_class->constructed = constructed; - device_class->get_hw_address_length = get_hw_address_length; + device_class->get_generic_capabilities = get_generic_capabilities; device_class->check_connection_compatible = check_connection_compatible; device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; @@ -614,31 +721,31 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->set_enabled = set_enabled; device_class->owns_iface = owns_iface; device_class->is_available = is_available; + device_class->get_ip_iface_identifier = get_ip_iface_identifier; device_class->state_changed = device_state_changed; /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_DEVICE_MODEM_MODEM, - "Modem", - "Modem", + g_param_spec_object (NM_DEVICE_MODEM_MODEM, "", "", NM_TYPE_MODEM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, - "Modem Capabilities", - "Modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CURRENT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, - "Current modem Capabilities", - "Current modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CURRENT_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (mclass), diff --git a/src/devices/wwan/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h index ee6b2988..996195c4 100644 --- a/src/devices/wwan/nm-device-modem.h +++ b/src/devices/wwan/nm-device-modem.h @@ -18,8 +18,8 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_MODEM_H -#define NM_DEVICE_MODEM_H +#ifndef __NETWORKMANAGER_DEVICE_MODEM_H__ +#define __NETWORKMANAGER_DEVICE_MODEM_H__ #include <glib.h> #include <glib-object.h> @@ -51,4 +51,4 @@ GType nm_device_modem_get_type (void); NMDevice *nm_device_modem_new (NMModem *modem); -#endif /* NM_DEVICE_MODEM_H */ +#endif /* __NETWORKMANAGER_DEVICE_MODEM_H__ */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 807b8924..f8239b79 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -18,14 +18,19 @@ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> */ +#include "config.h" + #include <glib/gi18n.h> #include <string.h> +#include <arpa/inet.h> #include <libmm-glib.h> + #include "nm-modem-broadband.h" -#include "nm-setting-connection.h" +#include "nm-core-internal.h" #include "nm-logging.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" +#include "nm-platform.h" G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) @@ -156,13 +161,29 @@ ask_for_pin (NMModemBroadband *self) NM_SETTING_GSM_PIN); } +static NMModemIPMethod +get_bearer_ip_method (MMBearerIpConfig *config) +{ + MMBearerIpMethod mm_method; + + mm_method = mm_bearer_ip_config_get_method (config); + if (mm_method == MM_BEARER_IP_METHOD_PPP) + return NM_MODEM_IP_METHOD_PPP; + else if (mm_method == MM_BEARER_IP_METHOD_STATIC) + return NM_MODEM_IP_METHOD_STATIC; + else if (mm_method == MM_BEARER_IP_METHOD_DHCP) + return NM_MODEM_IP_METHOD_AUTO; + return NM_MODEM_IP_METHOD_UNKNOWN; +} + static void connect_ready (MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { GError *error = NULL; - guint ip_method; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_clear_object (&self->priv->connect_properties); @@ -195,35 +216,31 @@ connect_ready (MMModemSimple *simple_iface, /* Grab IP configurations */ self->priv->ipv4_config = mm_bearer_get_ipv4_config (self->priv->bearer); - self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv4_config) + ip4_method = get_bearer_ip_method (self->priv->ipv4_config); - switch (mm_bearer_ip_config_get_method (self->priv->ipv4_config)) { - case MM_BEARER_IP_METHOD_PPP: - ip_method = MM_MODEM_IP_METHOD_PPP; - break; - case MM_BEARER_IP_METHOD_STATIC: - ip_method = MM_MODEM_IP_METHOD_STATIC; - break; - case MM_BEARER_IP_METHOD_DHCP: - ip_method = MM_MODEM_IP_METHOD_DHCP; - break; - default: - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, - "invalid IP config"); - nm_log_warn (LOGD_MB, "(%s) failed to connect modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - error->message); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv6_config) + ip6_method = get_bearer_ip_method (self->priv->ipv6_config); + + if (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN && + ip6_method == NM_MODEM_IP_METHOD_UNKNOWN) { + nm_log_warn (LOGD_MB, "(%s) failed to connect modem: invalid bearer IP configuration", + nm_modem_get_uid (NM_MODEM (self))); + + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "invalid bearer IP configuration"); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, error); g_error_free (error); g_object_unref (self); return; } - /* IPv4 for now only */ g_object_set (self, NM_MODEM_DATA_PORT, mm_bearer_get_interface (self->priv->bearer), - NM_MODEM_IP_METHOD, ip_method, + NM_MODEM_IP4_METHOD, ip4_method, + NM_MODEM_IP6_METHOD, ip6_method, NM_MODEM_IP_TIMEOUT, mm_bearer_get_ip_timeout (self->priv->bearer), NULL); @@ -249,12 +266,15 @@ create_cdma_connect_properties (NMConnection *connection) } static MMSimpleConnectProperties * -create_gsm_connect_properties (NMConnection *connection) +create_gsm_connect_properties (NMModem *modem, + NMConnection *connection, + GError **error) { NMSettingGsm *setting; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; MMSimpleConnectProperties *properties; const gchar *str; + NMModemIPType ip_type; setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); @@ -264,9 +284,9 @@ create_gsm_connect_properties (NMConnection *connection) if (str) mm_simple_connect_properties_set_number (properties, str); + /* Blank APN ("") means the default subscription APN */ str = nm_setting_gsm_get_apn (setting); - if (str) - mm_simple_connect_properties_set_apn (properties, str); + mm_simple_connect_properties_set_apn (properties, str ? str : ""); str = nm_setting_gsm_get_network_id (setting); if (str) @@ -309,6 +329,22 @@ create_gsm_connect_properties (NMConnection *connection) mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); } + /* Determine IP types to use when connecting */ + ip_type = nm_modem_get_connection_ip_type (modem, connection, error); + if (ip_type == NM_MODEM_IP_TYPE_UNKNOWN) { + g_object_unref (properties); + return NULL; + } + + if (ip_type == NM_MODEM_IP_TYPE_IPV4) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4); + else if (ip_type == NM_MODEM_IP_TYPE_IPV6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV6); + else if (ip_type == NM_MODEM_IP_TYPE_IPV4V6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4V6); + else + g_assert_not_reached (); + return properties; } @@ -319,17 +355,29 @@ act_stage1_prepare (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability caps; + GError *error = NULL; g_clear_object (&self->priv->connect_properties); caps = mm_modem_get_current_capabilities (self->priv->modem_iface); if (MODEM_CAPS_3GPP (caps)) - self->priv->connect_properties = create_gsm_connect_properties (connection); + self->priv->connect_properties = create_gsm_connect_properties (_self, connection, &error); 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))); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (error) { + nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s", + nm_modem_get_uid (NM_MODEM (self)), + nm_connection_get_id (connection), + error->message); + g_clear_error (&error); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -400,14 +448,14 @@ complete_connection (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability modem_caps; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); /* PPP settings common to 3GPP and 3GPP2 */ s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); g_object_set (G_OBJECT (s_ppp), NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, @@ -419,12 +467,13 @@ complete_connection (NMModem *_self, NMSettingGsm *s_gsm; s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ + if (!s_gsm) { + /* Need a GSM setting at least */ g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("GSM mobile broadband connection requires a 'gsm' setting")); + g_prefix_error (error, "%s: ", NM_SETTING_GSM_SETTING_NAME); return FALSE; } @@ -435,7 +484,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_GSM_SETTING_NAME, existing_connections, - _("GSM connection %d"), + NULL, + _("GSM connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -457,7 +507,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_CDMA_SETTING_NAME, existing_connections, - _("CDMA connection %d"), + NULL, + _("CDMA connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -465,8 +516,8 @@ complete_connection (NMModem *_self, } g_set_error (error, - NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Device is not a mobile broadband modem"); return FALSE; } @@ -590,11 +641,10 @@ set_mm_enabled (NMModem *_self, } /*****************************************************************************/ -/* IP method static */ +/* IPv4 method static */ static gboolean -ip_string_to_network_address (const gchar *str, - guint32 *out) +ip4_string_to_num (const gchar *str, guint32 *out) { guint32 addr = 0; gboolean success = FALSE; @@ -609,7 +659,7 @@ ip_string_to_network_address (const gchar *str, } static gboolean -static_stage3_done (NMModemBroadband *self) +static_stage3_ip4_done (NMModemBroadband *self) { GError *error = NULL; NMIP4Config *config = NULL; @@ -628,9 +678,9 @@ static_stage3_done (NMModemBroadband *self) /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config); - if (!ip_string_to_network_address (address_string, &address_network)) { - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, + if (!ip4_string_to_num (address_string, &address_network)) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IP4 configuration failed: invalid address given '%s'", nm_modem_get_uid (NM_MODEM (self)), address_string); @@ -639,14 +689,14 @@ static_stage3_done (NMModemBroadband *self) /* 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); + ip4_string_to_num (gw_string, &gw); config = nm_ip4_config_new (); memset (&address, 0, sizeof (address)); address.address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); - address.source = NM_PLATFORM_SOURCE_WWAN; + address.source = NM_IP_CONFIG_SOURCE_WWAN; nm_ip4_config_add_address (config, &address); nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); @@ -659,7 +709,7 @@ static_stage3_done (NMModemBroadband *self) /* DNS servers */ dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config); for (i = 0; dns[i]; i++) { - if ( ip_string_to_network_address (dns[i], &address_network) + if ( ip4_string_to_num (dns[i], &address_network) && address_network > 0) { nm_ip4_config_add_nameserver (config, address_network); nm_log_info (LOGD_MB, " DNS %s", dns[i]); @@ -681,7 +731,110 @@ static_stage3_ip4_config_start (NMModem *_self, /* We schedule it in an idle just to follow the same logic as in the * generic modem implementation. */ - g_idle_add ((GSourceFunc)static_stage3_done, self); + g_idle_add ((GSourceFunc) static_stage3_ip4_done, self); + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +/*****************************************************************************/ +/* IPv6 method static */ + +static gboolean +stage3_ip6_done (NMModemBroadband *self) +{ + GError *error = NULL; + NMIP6Config *config = NULL; + const gchar *address_string; + NMPlatformIP6Address address; + NMModemIPMethod ip_method; + const gchar **dns; + guint i; + + g_assert (self->priv->ipv6_config); + + memset (&address, 0, sizeof (address)); + + ip_method = get_bearer_ip_method (self->priv->ipv6_config); + + address_string = mm_bearer_ip_config_get_address (self->priv->ipv6_config); + if (!address_string) { + /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ + if (ip_method != NM_MODEM_IP_METHOD_AUTO) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: no address given", + nm_modem_get_uid (NM_MODEM (self))); + } + goto out; + } + + /* Fail if invalid IP address retrieved */ + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + + nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:", + nm_modem_get_uid (NM_MODEM (self))); + + config = nm_ip6_config_new (); + + address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv6_config); + nm_ip6_config_add_address (config, &address); + + nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + + address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config); + if (address_string) { + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + nm_log_info (LOGD_MB, " gateway %s", address_string); + nm_ip6_config_set_gateway (config, &address.address); + } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { + /* Gateway required for the 'static' method */ + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: missing gateway", + nm_modem_get_uid (NM_MODEM (self))); + goto out; + } + + /* DNS servers */ + dns = mm_bearer_ip_config_get_dns (self->priv->ipv6_config); + for (i = 0; dns[i]; i++) { + struct in6_addr addr; + + if (inet_pton (AF_INET6, dns[i], &addr)) { + nm_ip6_config_add_nameserver (config, &addr); + nm_log_info (LOGD_MB, " DNS %s", dns[i]); + } + } + +out: + nm_modem_emit_ip6_config_result (NM_MODEM (self), config, error); + g_clear_object (&config); + g_clear_error (&error); + return FALSE; +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *_self, NMDeviceStateReason *reason) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + + /* We schedule it in an idle just to follow the same logic as in the + * generic modem implementation. */ + g_idle_add ((GSourceFunc) stage3_ip6_done, self); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -720,11 +873,15 @@ simple_disconnect_ready (MMModemSimple *modem_iface, } static void -disconnect (NMModem *self, +disconnect (NMModem *modem, gboolean warn) { + NMModemBroadband *self = NM_MODEM_BROADBAND (modem); SimpleDisconnectContext *ctx; + if (!self->priv->simple_iface) + return; + ctx = g_slice_new (SimpleDisconnectContext); ctx->self = g_object_ref (self); @@ -806,6 +963,21 @@ modem_state_changed (MMModem *modem, /*****************************************************************************/ +static NMModemIPType +mm_ip_family_to_nm (MMBearerIpFamily family) +{ + NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN; + + if (family & MM_BEARER_IP_FAMILY_IPV4) + nm_type |= NM_MODEM_IP_TYPE_IPV4; + if (family & MM_BEARER_IP_FAMILY_IPV6) + nm_type |= NM_MODEM_IP_TYPE_IPV6; + if (family & MM_BEARER_IP_FAMILY_IPV4V6) + nm_type |= MM_BEARER_IP_FAMILY_IPV4V6; + + return nm_type; +} + NMModem * nm_modem_broadband_new (GObject *object, GError **error) { @@ -830,6 +1002,7 @@ nm_modem_broadband_new (GObject *object, GError **error) NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), NM_MODEM_DATA_PORT, NULL, /* We don't know it until bearer created */ + NM_MODEM_IP_TYPES, mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem_iface)), NM_MODEM_STATE, mm_state_to_nm (mm_modem_get_state (modem_iface)), NM_MODEM_DEVICE_ID, mm_modem_get_device_identifier (modem_iface), NM_MODEM_BROADBAND_MODEM, modem_object, @@ -967,6 +1140,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->get_capabilities = get_capabilities; modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; + modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; modem_class->deactivate = deactivate; modem_class->set_mm_enabled = set_mm_enabled; @@ -979,9 +1153,8 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_MODEM_BROADBAND_MODEM, - "Modem", - "Broadband modem object", + g_param_spec_object (NM_MODEM_BROADBAND_MODEM, "", "", MM_GDBUS_TYPE_OBJECT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index e12ca68c..2268bac4 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -18,10 +18,9 @@ * Copyright (C) 2012 - Aleksander Morgado <aleksander@gnu.org> */ -#ifndef NM_MODEM_BROADBAND_H -#define NM_MODEM_BROADBAND_H +#ifndef __NETWORKMANAGER_MODEM_BROADBAND_H__ +#define __NETWORKMANAGER_MODEM_BROADBAND_H__ -#include <dbus/dbus-glib.h> #include <glib-object.h> #include "nm-modem.h" @@ -55,4 +54,4 @@ NMModem *nm_modem_broadband_new (GObject *object, GError **error); G_END_DECLS -#endif /* NM_MODEM_BROADBAND_H */ +#endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */ diff --git a/src/devices/wwan/nm-modem-enum-types.c b/src/devices/wwan/nm-modem-enum-types.c index cf59ba2b..6fbb3b6d 100644 --- a/src/devices/wwan/nm-modem-enum-types.c +++ b/src/devices/wwan/nm-modem-enum-types.c @@ -8,22 +8,42 @@ #include "nm-modem.h" GType -nm_modem_error_get_type (void) +nm_modem_ip_method_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_MODEM_ERROR_CONNECTION_NOT_GSM, "NM_MODEM_ERROR_CONNECTION_NOT_GSM", "ConnectionNotGsm" }, - { NM_MODEM_ERROR_CONNECTION_NOT_CDMA, "NM_MODEM_ERROR_CONNECTION_NOT_CDMA", "ConnectionNotCdma" }, - { NM_MODEM_ERROR_CONNECTION_INVALID, "NM_MODEM_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, "NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_MODEM_ERROR_INITIALIZATION_FAILED, "NM_MODEM_ERROR_INITIALIZATION_FAILED", "InitializationFailed" }, + { NM_MODEM_IP_METHOD_UNKNOWN, "NM_MODEM_IP_METHOD_UNKNOWN", "unknown" }, + { NM_MODEM_IP_METHOD_PPP, "NM_MODEM_IP_METHOD_PPP", "ppp" }, + { NM_MODEM_IP_METHOD_STATIC, "NM_MODEM_IP_METHOD_STATIC", "static" }, + { NM_MODEM_IP_METHOD_AUTO, "NM_MODEM_IP_METHOD_AUTO", "auto" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMModemError"), values); + g_enum_register_static (g_intern_static_string ("NMModemIPMethod"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_modem_ip_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_MODEM_IP_TYPE_UNKNOWN, "NM_MODEM_IP_TYPE_UNKNOWN", "unknown" }, + { NM_MODEM_IP_TYPE_IPV4, "NM_MODEM_IP_TYPE_IPV4", "ipv4" }, + { NM_MODEM_IP_TYPE_IPV6, "NM_MODEM_IP_TYPE_IPV6", "ipv6" }, + { NM_MODEM_IP_TYPE_IPV4V6, "NM_MODEM_IP_TYPE_IPV4V6", "ipv4v6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMModemIPType"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } diff --git a/src/devices/wwan/nm-modem-enum-types.h b/src/devices/wwan/nm-modem-enum-types.h index 81ccd8d2..ccbe6201 100644 --- a/src/devices/wwan/nm-modem-enum-types.h +++ b/src/devices/wwan/nm-modem-enum-types.h @@ -9,8 +9,10 @@ #include <glib-object.h> G_BEGIN_DECLS -GType nm_modem_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_MODEM_ERROR (nm_modem_error_get_type ()) +GType nm_modem_ip_method_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_METHOD (nm_modem_ip_method_get_type ()) +GType nm_modem_ip_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_TYPE (nm_modem_ip_type_get_type ()) GType nm_modem_state_get_type (void) G_GNUC_CONST; #define NM_TYPE_MODEM_STATE (nm_modem_state_get_type ()) G_END_DECLS diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index c4811700..f0e56926 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -20,42 +20,28 @@ * Copyright (C) 2009 Canonical Ltd. */ -#include <string.h> #include "config.h" + +#include <string.h> + +#include <libmm-glib.h> + #include "nm-modem-manager.h" #include "nm-logging.h" #include "nm-modem.h" -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-modem-old-types.h" -#include "nm-dbus-glib-types.h" - -#if WITH_MODEM_MANAGER_1 -#include <libmm-glib.h> #include "nm-modem-broadband.h" -#endif #define MODEM_POKE_INTERVAL 120 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) struct _NMModemManagerPrivate { - /* ModemManager < 0.7 */ - NMDBusManager *dbus_mgr; - DBusGProxy *proxy; - guint poke_id; - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ GDBusConnection *dbus_connection; - MMManager *modem_manager_1; - guint modem_manager_1_launch_id; - gboolean old_modem_manager_found; - gboolean new_modem_manager_found; - guint modem_manager_1_name_owner_changed_id; - guint modem_manager_1_object_added_id; - guint modem_manager_1_object_removed_id; -#endif + MMManager *modem_manager; + guint mm_launch_id; + guint mm_name_owner_changed_id; + guint mm_object_added_id; + guint mm_object_removed_id; /* Common */ GHashTable *modems; @@ -85,191 +71,6 @@ handle_new_modem (NMModemManager *self, NMModem *modem) g_signal_emit (self, signals[MODEM_ADDED], 0, modem); } -/************************************************************************/ -/* Support for ModemManager < 0.7 */ - -static void -clear_modem_manager_support (NMModemManager *self) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } -} - -static void -create_modem (NMModemManager *self, const char *path) -{ - DBusGProxy *proxy; - GError *error = NULL; - NMModem *modem = NULL; - GHashTable *properties; - - if (g_hash_table_lookup (self->priv->modems, path)) { - nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); - return; - } - - proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, - path, - DBUS_INTERFACE_PROPERTIES); - g_assert (proxy); - if (dbus_g_proxy_call_with_timeout (proxy, "GetAll", 15000, &error, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_VARIANT, &properties, - G_TYPE_INVALID)) { - /* Success, create the modem */ - modem = nm_modem_old_new (path, properties, &error); - if (modem) - handle_new_modem (self, modem); - else { - nm_log_warn (LOGD_MB, "failed to create modem: %s", - error ? error->message : "(unknown)"); - } - g_hash_table_destroy (properties); - } else { - nm_log_warn (LOGD_MB, "could not get modem properties: %s %s", - error ? dbus_g_error_get_name (error) : "(none)", - error ? error->message : "(unknown)"); - } - - g_object_unref (proxy); - g_clear_error (&error); -} - -static void -modem_added (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - create_modem (NM_MODEM_MANAGER (user_data), path); -} - -static void -modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - NMModem *modem; - - modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); - if (modem) { - nm_modem_emit_removed (modem); - g_hash_table_remove (self->priv->modems, path); - } -} - -static void -mm_poke_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - GPtrArray *modems; - int i; - - if (dbus_g_proxy_end_call (proxy, call, NULL, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &modems, - G_TYPE_INVALID)) { - /* Don't care about the returned value, just free it */ - for (i = 0; i < modems->len; i++) - g_free ((char *) g_ptr_array_index (modems, i)); - g_ptr_array_free (modems, TRUE); - } - g_object_unref (proxy); -} - -static gboolean -poke_modem_cb (gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - DBusGConnection *g_connection; - DBusGProxy *proxy; - - g_connection = nm_dbus_manager_get_connection (self->priv->dbus_mgr); - proxy = dbus_g_proxy_new_for_name (g_connection, - MM_OLD_DBUS_SERVICE, - MM_OLD_DBUS_PATH, - MM_OLD_DBUS_INTERFACE); - - nm_log_dbg (LOGD_MB, "Requesting to (re)launch modem-manager..."); - - dbus_g_proxy_begin_call_with_timeout (proxy, - "EnumerateDevices", - mm_poke_cb, - NULL, - NULL, - 5000, - G_TYPE_INVALID); - return TRUE; -} - -static void -enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data) -{ - NMModemManager *manager = NM_MODEM_MANAGER (data); - GPtrArray *modems; - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "could not get modem list: %s", error->message); - g_error_free (error); - } else { - int i; - - for (i = 0; i < modems->len; i++) { - char *path = (char *) g_ptr_array_index (modems, i); - - create_modem (manager, path); - g_free (path); - } - - g_ptr_array_free (modems, TRUE); - } -} - -#if WITH_MODEM_MANAGER_1 -static void clear_modem_manager_1_support (NMModemManager *self); -#endif - -static void -modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - nm_log_info (LOGD_MB, "modem-manager is now available"); - -#if WITH_MODEM_MANAGER_1 - self->priv->old_modem_manager_found = TRUE; - if (self->priv->new_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_1_support (self); -#endif - - self->priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, MM_OLD_DBUS_PATH, MM_OLD_DBUS_INTERFACE); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceAdded", - G_CALLBACK (modem_added), self, - NULL); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceRemoved", - G_CALLBACK (modem_removed), self, - NULL); - - if (enumerate_devices) - dbus_g_proxy_begin_call (self->priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); -} - static gboolean remove_one_modem (gpointer key, gpointer value, gpointer user_data) { @@ -278,93 +79,34 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) } static void -modem_manager_disappeared (NMModemManager *self) +modem_manager_clear_signals (NMModemManager *self) { - g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, self); - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } - - /* Try to activate the modem-manager */ - nm_log_dbg (LOGD_MB, "trying to start the modem manager..."); - poke_modem_cb (self); - self->priv->poke_id = g_timeout_add_seconds (MODEM_POKE_INTERVAL, poke_modem_cb, self); -} - -static void -nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) -{ - gboolean old_owner_good; - gboolean new_owner_good; - - /* Can't handle the signal if its not from the modem service */ - if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0) + if (!self->priv->modem_manager) return; - old_owner_good = (old_owner && strlen (old_owner)); - new_owner_good = (new_owner && strlen (new_owner)); - - if (!old_owner_good && new_owner_good) { - modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE); - } else if (old_owner_good && !new_owner_good) { - nm_log_info (LOGD_MB, "the modem manager disappeared"); - modem_manager_disappeared (NM_MODEM_MANAGER (user_data)); - } -} - -/************************************************************************/ -/* Support for ModemManager >= 0.7 */ - -#if WITH_MODEM_MANAGER_1 - -static void -modem_manager_1_clear_signals (NMModemManager *self) -{ - if (!self->priv->modem_manager_1) - return; - - if (self->priv->modem_manager_1_name_owner_changed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id); - self->priv->modem_manager_1_name_owner_changed_id = 0; - } - - if (self->priv->modem_manager_1_object_added_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id); - self->priv->modem_manager_1_object_added_id = 0; + if (self->priv->mm_name_owner_changed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id); + self->priv->mm_name_owner_changed_id = 0; } - if (self->priv->modem_manager_1_object_removed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id); - self->priv->modem_manager_1_object_removed_id = 0; + if (self->priv->mm_object_added_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_added_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_added_id); + self->priv->mm_object_added_id = 0; } -} -static void -clear_modem_manager_1_support (NMModemManager *self) -{ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_object_removed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_removed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_removed_id); + self->priv->mm_object_removed_id = 0; } - - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); - g_clear_object (&self->priv->dbus_connection); } static void @@ -426,49 +168,43 @@ modem_object_removed (MMManager *manager, } static void -modem_manager_1_available (NMModemManager *self) +modem_manager_available (NMModemManager *self) { GList *modems, *l; nm_log_info (LOGD_MB, "ModemManager available in the bus"); - self->priv->new_modem_manager_found = TRUE; - if (self->priv->old_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_support (self); - /* Update initial modems list */ - modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager_1)); - for (l = modems; l; l = g_list_next (l)) - modem_object_added (self->priv->modem_manager_1, MM_OBJECT (l->data), self); - g_list_free_full (modems, (GDestroyNotify) g_object_unref); + modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager)); + for (l = modems; l; l = g_list_next (l)) + modem_object_added (self->priv->modem_manager, MM_OBJECT (l->data), self); + g_list_free_full (modems, (GDestroyNotify) g_object_unref); } -static void schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds); -static void ensure_client (NMModemManager *self); +static void schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds); +static void ensure_client (NMModemManager *self); static void -modem_manager_1_name_owner_changed (MMManager *modem_manager_1, - GParamSpec *pspec, - NMModemManager *self) +modem_manager_name_owner_changed (MMManager *modem_manager, + GParamSpec *pspec, + NMModemManager *self) { gchar *name_owner; /* Quit poking, if any */ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; } - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager)); if (!name_owner) { nm_log_info (LOGD_MB, "ModemManager disappeared from bus"); #if !HAVE_SYSTEMD /* If not managed by systemd, schedule relaunch */ - schedule_modem_manager_1_relaunch (self, 0); + schedule_modem_manager_relaunch (self, 0); #endif return; @@ -481,21 +217,21 @@ modem_manager_1_name_owner_changed (MMManager *modem_manager_1, * nor 'object-removed' if it was created while there was no ModemManager in * the bus. This hack avoids this issue until we get a GIO with the fix * included... */ - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); ensure_client (self); /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: - * modem_manager_1_available (self); + * modem_manager_available (self); */ } #if !HAVE_SYSTEMD static void -modem_manager_1_poke_cb (GDBusConnection *connection, - GAsyncResult *res, - NMModemManager *self) +modem_manager_poke_cb (GDBusConnection *connection, + GAsyncResult *res, + NMModemManager *self) { GError *error = NULL; GVariant *result; @@ -514,7 +250,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else g_variant_unref (result); @@ -523,7 +259,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, } static void -modem_manager_1_poke (NMModemManager *self) +modem_manager_poke (NMModemManager *self) { /* If there is no current owner right away, ensure we poke to get one */ g_dbus_connection_call (self->priv->dbus_connection, @@ -536,28 +272,28 @@ modem_manager_1_poke (NMModemManager *self) G_DBUS_CALL_FLAGS_NONE, -1, NULL, /* cancellable */ - (GAsyncReadyCallback)modem_manager_1_poke_cb, /* callback */ + (GAsyncReadyCallback)modem_manager_poke_cb, /* callback */ g_object_ref (self)); /* user_data */ } #endif /* HAVE_SYSTEMD */ static void -modem_manager_1_check_name_owner (NMModemManager *self) +modem_manager_check_name_owner (NMModemManager *self) { gchar *name_owner; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager)); if (name_owner) { /* Available! */ - modem_manager_1_available (self); + modem_manager_available (self); g_free (name_owner); return; } #if !HAVE_SYSTEMD /* If the lifecycle is not managed by systemd, poke */ - modem_manager_1_poke (self); + modem_manager_poke (self); #endif } @@ -570,38 +306,35 @@ manager_new_ready (GObject *source, GError *error = NULL; - g_assert (!self->priv->modem_manager_1); - self->priv->modem_manager_1 = mm_manager_new_finish (res, &error); - if (!self->priv->modem_manager_1) { + g_assert (!self->priv->modem_manager); + self->priv->modem_manager = mm_manager_new_finish (res, &error); + if (!self->priv->modem_manager) { /* We're not really supposed to get any error here. If we do get one, * though, just re-schedule the MMManager creation after some time. * During this period, name-owner changes won't be followed. */ nm_log_warn (LOGD_MB, "error creating ModemManager client: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Setup signals in the GDBusObjectManagerClient */ - self->priv->modem_manager_1_name_owner_changed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_name_owner_changed_id = + g_signal_connect (self->priv->modem_manager, "notify::name-owner", - G_CALLBACK (modem_manager_1_name_owner_changed), + G_CALLBACK (modem_manager_name_owner_changed), self); - self->priv->modem_manager_1_object_added_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_added_id = + g_signal_connect (self->priv->modem_manager, "object-added", G_CALLBACK (modem_object_added), self); - self->priv->modem_manager_1_object_removed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_removed_id = + g_signal_connect (self->priv->modem_manager, "object-removed", G_CALLBACK (modem_object_removed), self); - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } /* Balance refcount */ @@ -616,7 +349,7 @@ ensure_client (NMModemManager *self) /* Create the GDBusObjectManagerClient. We do not request to autostart, as * we don't really want the MMManager creation to fail. We can always poke * later on if we want to request the autostart */ - if (!self->priv->modem_manager_1) { + if (!self->priv->modem_manager) { mm_manager_new (self->priv->dbus_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, NULL, @@ -626,7 +359,7 @@ ensure_client (NMModemManager *self) } /* If already available, recheck name owner! */ - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } static void @@ -643,10 +376,7 @@ bus_get_ready (GObject *source, nm_log_warn (LOGD_CORE, "error getting bus connection: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Got the bus, ensure client */ ensure_client (self); @@ -660,7 +390,7 @@ static gboolean ensure_bus (NMModemManager *self) { /* Clear launch ID */ - self->priv->modem_manager_1_launch_id = 0; + self->priv->mm_launch_id = 0; if (!self->priv->dbus_connection) g_bus_get (G_BUS_TYPE_SYSTEM, @@ -675,20 +405,18 @@ ensure_bus (NMModemManager *self) } static void -schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds) +schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds) { /* No need to pass an extra reference to self; timeout/idle will be * cancelled if the object gets disposed. */ if (n_seconds) - self->priv->modem_manager_1_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); else - self->priv->modem_manager_1_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); } -#endif /* WITH_MODEM_MANAGER_1 */ - /************************************************************************/ static void @@ -698,20 +426,7 @@ nm_modem_manager_init (NMModemManager *self) self->priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - /* ModemManager < 0.7 */ - self->priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (self->priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (nm_modem_manager_name_owner_changed), - self); - if (nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, MM_OLD_DBUS_SERVICE)) - modem_manager_appeared (self, TRUE); - else - modem_manager_disappeared (self); - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - schedule_modem_manager_1_relaunch (self, 0); -#endif + schedule_modem_manager_relaunch (self, 0); } static void @@ -719,21 +434,20 @@ dispose (GObject *object) { NMModemManager *self = NM_MODEM_MANAGER (object); - /* ModemManager < 0.7 */ - clear_modem_manager_support (self); + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; + } -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - clear_modem_manager_1_support (self); -#endif + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); + g_clear_object (&self->priv->dbus_connection); if (self->priv->modems) { g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, object); g_hash_table_destroy (self->priv->modems); } - self->priv->dbus_mgr = NULL; - /* Chain up to the parent class */ G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object); } diff --git a/src/devices/wwan/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h index 3082bdb3..9e0db41e 100644 --- a/src/devices/wwan/nm-modem-manager.h +++ b/src/devices/wwan/nm-modem-manager.h @@ -20,8 +20,8 @@ * Copyright (C) 2009 Canonical Ltd. */ -#ifndef NM_MODEM_MANAGER_H -#define NM_MODEM_MANAGER_H +#ifndef __NETWORKMANAGER_MODEM_MANAGER_H__ +#define __NETWORKMANAGER_MODEM_MANAGER_H__ #include <glib-object.h> #include "nm-modem.h" @@ -46,4 +46,4 @@ typedef struct { GType nm_modem_manager_get_type (void); -#endif /* NM_MODEM_MANAGER_H */ +#endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */ diff --git a/src/devices/wwan/nm-modem-old-types.h b/src/devices/wwan/nm-modem-old-types.h deleted file mode 100644 index 84065a68..00000000 --- a/src/devices/wwan/nm-modem-old-types.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_TYPES_H -#define NM_MODEM_OLD_TYPES_H - -#define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_PATH "/org/freedesktop/ModemManager" -#define MM_OLD_DBUS_INTERFACE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" -#define MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE "org.freedesktop.ModemManager.Modem.Simple" -#define MM_OLD_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" - -#define MM_OLD_MODEM_TYPE_UNKNOWN 0 -#define MM_OLD_MODEM_TYPE_GSM 1 -#define MM_OLD_MODEM_TYPE_CDMA 2 - -/* Errors */ - -#define MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER MM_OLD_DBUS_INTERFACE_MODEM ".NoCarrier" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE MM_OLD_DBUS_INTERFACE_MODEM ".NoDialtone" -#define MM_OLD_MODEM_CONNECT_ERROR_BUSY MM_OLD_DBUS_INTERFACE_MODEM ".Busy" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER MM_OLD_DBUS_INTERFACE_MODEM ".NoAnswer" - -#define MM_OLD_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" - -#define MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_OLD_MODEM_ERROR ".NetworkNotAllowed" -#define MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT MM_OLD_MODEM_ERROR ".NetworkTimeout" -#define MM_OLD_MODEM_ERROR_NO_NETWORK MM_OLD_MODEM_ERROR ".NoNetwork" -#define MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED MM_OLD_MODEM_ERROR ".SimNotInserted" -#define MM_OLD_MODEM_ERROR_SIM_PIN MM_OLD_MODEM_ERROR ".SimPinRequired" -#define MM_OLD_MODEM_ERROR_SIM_PUK MM_OLD_MODEM_ERROR ".SimPukRequired" -#define MM_OLD_MODEM_ERROR_SIM_WRONG MM_OLD_MODEM_ERROR ".SimWrong" -#define MM_OLD_MODEM_ERROR_WRONG_PASSWORD MM_OLD_MODEM_ERROR ".IncorrectPassword" - -typedef enum { - MM_OLD_MODEM_STATE_UNKNOWN = 0, - MM_OLD_MODEM_STATE_DISABLED = 10, - MM_OLD_MODEM_STATE_DISABLING = 20, - MM_OLD_MODEM_STATE_ENABLING = 30, - MM_OLD_MODEM_STATE_ENABLED = 40, - MM_OLD_MODEM_STATE_SEARCHING = 50, - MM_OLD_MODEM_STATE_REGISTERED = 60, - MM_OLD_MODEM_STATE_DISCONNECTING = 70, - MM_OLD_MODEM_STATE_CONNECTING = 80, - MM_OLD_MODEM_STATE_CONNECTED = 90, - - MM_OLD_MODEM_STATE_LAST = MM_OLD_MODEM_STATE_CONNECTED -} MMOldModemState; - -#endif /* NM_MODEM_OLD_TYPES_H */ diff --git a/src/devices/wwan/nm-modem-old.c b/src/devices/wwan/nm-modem-old.c deleted file mode 100644 index ce1a382e..00000000 --- a/src/devices/wwan/nm-modem-old.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#include <string.h> -#include <glib/gi18n.h> - -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-setting-connection.h" -#include "nm-properties-changed-signal.h" -#include "nm-modem-old-types.h" -#include "nm-logging.h" -#include "NetworkManagerUtils.h" -#include "nm-device-private.h" -#include "nm-dbus-glib-types.h" -#include "nm-glib-compat.h" - -G_DEFINE_TYPE (NMModemOld, nm_modem_old, NM_TYPE_MODEM) - -#define NM_MODEM_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OLD, NMModemOldPrivate)) - -typedef struct { - DBusGProxy *proxy; - DBusGProxy *props_proxy; - - MMOldModemState state; - NMDeviceModemCapabilities caps; - char *unlock_required; - - DBusGProxyCall *call; - GHashTable *connect_properties; - - guint32 pin_tries; - guint enable_delay_id; -} NMModemOldPrivate; - -#define CAPS_3GPP (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE) - -/*****************************************************************************/ - -typedef enum { - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY = 0, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_GPRS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_EDGE, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_UMTS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSDPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA, - - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA -} MMModemDeprecatedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_MODE_ANY = 0, - MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED = 1, - MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED = 2, - MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY = 3, - MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY = 4, - MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED = 5, - MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY = 6, - - MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY -} MMModemGsmAllowedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN = 0x0000, - /* bits 0..4 order match Ericsson device bitmap */ - MM_MODEM_GSM_ALLOWED_AUTH_NONE = 0x0001, - MM_MODEM_GSM_ALLOWED_AUTH_PAP = 0x0002, - MM_MODEM_GSM_ALLOWED_AUTH_CHAP = 0x0004, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP = 0x0008, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2 = 0x0010, - MM_MODEM_GSM_ALLOWED_AUTH_EAP = 0x0020, - - MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP -} MMModemGsmAllowedAuth; - -static NMDeviceStateReason -translate_mm_error (GError *error) -{ - NMDeviceStateReason reason; - - if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_BUSY)) - reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER)) - reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NO_NETWORK)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PUK)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_WRONG_PASSWORD)) - reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT; - else { - /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ - nm_log_dbg (LOGD_MB, "unmapped dbus error detected: '%s'", dbus_g_error_get_name (error)); - reason = NM_DEVICE_STATE_REASON_UNKNOWN; - } - - /* FIXME: We have only GSM error messages here, and we have no idea which - activation state failed. Reasons like: - NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, - NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, - NM_DEVICE_STATE_REASON_GSM_APN_FAILED, - NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, - NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED - are not used. - */ - return reason; -} - -#define MAP_STATE(name) case MM_OLD_MODEM_STATE_##name: return NM_MODEM_STATE_##name; - -static NMModemState -mm_state_to_nm (MMOldModemState mm_state, const char *unlock_required) -{ - if (unlock_required && *unlock_required) - return NM_MODEM_STATE_LOCKED; - - switch (mm_state) { - MAP_STATE(UNKNOWN) - MAP_STATE(DISABLED) - MAP_STATE(DISABLING) - MAP_STATE(ENABLING) - MAP_STATE(ENABLED) - MAP_STATE(SEARCHING) - MAP_STATE(REGISTERED) - MAP_STATE(DISCONNECTING) - MAP_STATE(CONNECTING) - MAP_STATE(CONNECTED) - } - return NM_MODEM_STATE_UNKNOWN; -}; - -/*****************************************************************************/ - -static DBusGProxy * -nm_modem_old_get_proxy (NMModemOld *self, const char *interface) -{ - - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *current_iface; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), NULL); - - /* Default to the default interface. */ - if (interface == NULL) - interface = MM_OLD_DBUS_INTERFACE_MODEM; - - if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES)) - return priv->props_proxy; - - current_iface = dbus_g_proxy_get_interface (priv->proxy); - if (!current_iface || strcmp (current_iface, interface)) - dbus_g_proxy_set_interface (priv->proxy, interface); - - return priv->proxy; -} - -/*****************************************************************************/ -/* Query/Update enabled state */ - -static void -set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - nm_modem_set_prev_state (NM_MODEM (user_data), "enable/disable failed"); - } - /* Wait for the state change signal to indicate enabled state changed */ -} - -static void -set_mm_enabled (NMModem *self, gboolean enabled) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM), - "Enable", set_mm_enabled_done, - g_object_ref (self), g_object_unref, - G_TYPE_BOOLEAN, enabled, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -ask_for_pin (NMModemOld *self, gboolean always_ask) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - guint32 tries = 0; - - g_return_if_fail (NM_IS_MODEM_OLD (self)); - - if (!always_ask) - tries = priv->pin_tries++; - - nm_modem_get_secrets (NM_MODEM (self), - NM_SETTING_GSM_SETTING_NAME, - (tries || always_ask) ? TRUE : FALSE, - NM_SETTING_GSM_PIN); -} - -static void -stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GError *error = NULL; - gboolean asked = FALSE; - - priv->call = NULL; - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); - else { - if (priv->caps & CAPS_3GPP) { - if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) { - ask_for_pin (self, FALSE); - asked = TRUE; - } else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) { - ask_for_pin (self, TRUE); - asked = TRUE; - } - } - - if (!asked) { - nm_log_warn (LOGD_MB, "Mobile connection failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); - } - g_error_free (error); - } -} - -static void -do_connect (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - DBusGProxy *proxy; - - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); - priv->call = dbus_g_proxy_begin_call_with_timeout (proxy, - "Connect", stage1_prepare_done, - self, NULL, 120000, - DBUS_TYPE_G_MAP_OF_VARIANT, priv->connect_properties, - G_TYPE_INVALID); -} - -static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data); - -/* do_enable() is used as a GSourceFunc, hence the gboolean return */ -static gboolean -do_enable (NMModemOld *self) -{ - DBusGProxy *proxy; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), FALSE); - - NM_MODEM_OLD_GET_PRIVATE (self)->enable_delay_id = 0; - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM); - dbus_g_proxy_begin_call_with_timeout (proxy, - "Enable", stage1_enable_done, - self, NULL, 20000, - G_TYPE_BOOLEAN, TRUE, - G_TYPE_INVALID); - return FALSE; -} - -static void -stage1_pin_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - /* Success; try to enable the modem again. Wait a few seconds to ensure - * that ModemManager is ready for the enable right after the unlock. - */ - if (priv->enable_delay_id == 0) - priv->enable_delay_id = g_timeout_add_seconds (4, (GSourceFunc) do_enable, self); - } else { - nm_log_warn (LOGD_MB, "GSM PIN unlock failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - g_error_free (error); - } -} - -static void -handle_enable_pin_required (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *pin = NULL; - GValue *value; - DBusGProxy *proxy; - - g_assert (priv->caps & CAPS_3GPP); - - /* See if we have a PIN already */ - value = g_hash_table_lookup (priv->connect_properties, "pin"); - if (value && G_VALUE_HOLDS_STRING (value)) - pin = g_value_get_string (value); - - /* If we do, send it */ - if (pin) { - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD); - dbus_g_proxy_begin_call_with_timeout (proxy, - "SendPin", stage1_pin_done, - self, NULL, 10000, - G_TYPE_STRING, pin, - G_TYPE_INVALID); - } else - ask_for_pin (self, FALSE); -} - -static void -stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) - do_connect (self); - else { - if ((priv->caps & CAPS_3GPP) && dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - handle_enable_pin_required (self); - else { - nm_log_warn (LOGD_MB, "Modem enable failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - } - - g_error_free (error); - } -} - -static GHashTable * -create_connect_properties (NMConnection *connection) -{ - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - NMSettingPPP *s_ppp; - GHashTable *properties; - const char *str; - - properties = value_hash_create (); - - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - str = nm_setting_cdma_get_number (s_cdma); - if (str) - value_hash_add_str (properties, "number", str); - return properties; - } - - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - str = nm_setting_gsm_get_number (s_gsm); - if (str) - value_hash_add_str (properties, "number", str); - - str = nm_setting_gsm_get_apn (s_gsm); - if (str) - value_hash_add_str (properties, "apn", str); - - str = nm_setting_gsm_get_network_id (s_gsm); - if (str) - value_hash_add_str (properties, "network_id", str); - - str = nm_setting_gsm_get_pin (s_gsm); - if (str) - value_hash_add_str (properties, "pin", str); - - str = nm_setting_gsm_get_username (s_gsm); - if (str) - value_hash_add_str (properties, "username", str); - - str = nm_setting_gsm_get_password (s_gsm); - if (str) - value_hash_add_str (properties, "password", str); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* Add both old and new preferred modes */ - switch (nm_setting_gsm_get_network_type (s_gsm)) { - case NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY); - break; - default: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_ANY); - break; - } -G_GNUC_END_IGNORE_DEPRECATIONS - - /* Roaming */ - if (nm_setting_gsm_get_home_only (s_gsm)) - value_hash_add_bool (properties, "home_only", TRUE); - - /* For IpMethod == STATIC or DHCP */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - guint32 auth = MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN; - - if (nm_setting_ppp_get_noauth (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_NONE; - if (!nm_setting_ppp_get_refuse_pap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_PAP; - if (!nm_setting_ppp_get_refuse_chap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_CHAP; - if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP; - if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2; - if (!nm_setting_ppp_get_refuse_eap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_EAP; - - if (auth != MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN) - value_hash_add_uint (properties, "allowed_auth", auth); - } - - return properties; - } - - g_hash_table_destroy (properties); - return NULL; -} - -static NMActStageReturn -act_stage1_prepare (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *reason) -{ - NMModemOld *self = NM_MODEM_OLD (modem); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - if (priv->connect_properties) - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = create_connect_properties (connection); - - if (nm_modem_get_state (modem) >= NM_MODEM_STATE_ENABLING) - do_connect (self); - else - do_enable (self); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ -/* IP method static */ - -static char addr_to_string_buf[INET6_ADDRSTRLEN + 1]; - -static const char * -ip_address_to_string (guint32 numeric) -{ - guint32 temp_addr; - - memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf)); - temp_addr = numeric; - - if (inet_ntop (AF_INET, &temp_addr, addr_to_string_buf, INET_ADDRSTRLEN)) { - return addr_to_string_buf; - } else { - nm_log_warn (LOGD_VPN, "error converting IP4 address 0x%X", - ntohl (temp_addr)); - return NULL; - } -} - -static void -static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValueArray *ret_array = NULL; - GError *error = NULL; - NMIP4Config *config = NULL; - - priv->call = NULL; - - /* Returned value array is (uuuu): [IP, DNS1, DNS2, DNS3], all in - * network byte order. - */ - if (dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_VALUE_ARRAY, &ret_array, - G_TYPE_INVALID)) { - NMPlatformIP4Address address; - int i; - - config = nm_ip4_config_new (); - memset (&address, 0, sizeof (address)); - - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", - nm_modem_get_uid (NM_MODEM (self))); - - /* IP address */ - address.address = g_value_get_uint (g_value_array_get_nth (ret_array, 0)); - address.plen = 32; - address.source = NM_PLATFORM_SOURCE_WWAN; - nm_ip4_config_add_address (config, &address); - - nm_log_info (LOGD_MB, " address %s/%d", - ip_address_to_string (address.address), - address.plen); - - /* DNS servers */ - for (i = 1; i < ret_array->n_values; i++) { - GValue *value = g_value_array_get_nth (ret_array, i); - guint32 tmp = g_value_get_uint (value); - - if (tmp > 0) { - nm_ip4_config_add_nameserver (config, tmp); - nm_log_info (LOGD_MB, " DNS %s", ip_address_to_string (tmp)); - } - } - g_value_array_free (ret_array); - } - - g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, config, error); - g_clear_error (&error); -} - -static NMActStageReturn -static_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) -{ - NMModemOldPrivate *priv; - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->call = dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "GetIP4Config", static_stage3_done, - self, NULL, - G_TYPE_INVALID); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ - -static void -disconnect_done (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) -{ - GError *error = NULL; - gboolean warn = GPOINTER_TO_UINT (user_data); - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) && warn) { - nm_log_info (LOGD_MB, "disconnect failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } -} - -static void -disconnect (NMModem *self, - gboolean warn) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "Disconnect", - disconnect_done, - GUINT_TO_POINTER (warn), - NULL, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -deactivate (NMModem *self, NMDevice *device) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->pin_tries = 0; - - if (priv->call) { - dbus_g_proxy_cancel_call (priv->proxy, priv->call); - priv->call = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - /* Chain up parent */ - NM_MODEM_CLASS (nm_modem_old_parent_class)->deactivate (self, device); -} - -/*****************************************************************************/ - -static void -modem_properties_changed (DBusGProxy *proxy, - const char *interface, - GHashTable *props, - gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValue *value; - gboolean update_state = FALSE; - - if (strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM) && - strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD)) - return; - - value = g_hash_table_lookup (props, "IpMethod"); - if (value && G_VALUE_HOLDS_UINT (value)) { - g_object_set (self, - NM_MODEM_IP_METHOD, g_value_get_uint (value), - NULL); - } - - value = g_hash_table_lookup (props, "SimIdentifier"); - if (value && G_VALUE_HOLDS_STRING (value)) { - const char *sim_id = g_value_get_string (value); - - g_object_set (self, - NM_MODEM_SIM_ID, (sim_id && *sim_id) ? sim_id : NULL, - NULL); - } - - value = g_hash_table_lookup (props, "UnlockRequired"); - if (value && G_VALUE_HOLDS_STRING (value)) { - g_free (priv->unlock_required); - priv->unlock_required = g_value_dup_string (value); - update_state = TRUE; - } - - value = g_hash_table_lookup (props, "State"); - if (value && G_VALUE_HOLDS_UINT (value)) { - priv->state = g_value_get_uint (value); - update_state = TRUE; - } - - if (update_state) { - nm_modem_set_state (NM_MODEM (self), - mm_state_to_nm (priv->state, priv->unlock_required), - NULL); - } -} - -/*****************************************************************************/ - -static gboolean -check_connection_compatible (NMModem *modem, NMConnection *connection) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingConnection *s_con; - gboolean valid_cdma = FALSE, valid_gsm = FALSE; - const char *ctype; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - ctype = nm_setting_connection_get_connection_type (s_con); - g_assert (ctype); - - /* Check for valid CDMA first */ - if (strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) == 0) - valid_cdma = !!nm_connection_get_setting_cdma (connection); - - if (strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) == 0) - valid_gsm = !!nm_connection_get_setting_gsm (connection); - - /* Validate CDMA */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - if (valid_cdma) - return TRUE; - - /* If the modem is only CDMA and the connection is not CDMA, error */ - if ((priv->caps ^ NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) == 0) - return FALSE; - } - - /* Validate 3GPP */ - if (priv->caps & CAPS_3GPP) - return valid_gsm; - - return FALSE; -} - -/*****************************************************************************/ - -static void -complete_ppp_setting (NMConnection *connection) -{ - NMSettingPPP *s_ppp; - - s_ppp = nm_connection_get_setting_ppp (connection); - if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); - g_object_set (G_OBJECT (s_ppp), - NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, - NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - } -} - -static gboolean -complete_connection_3gpp (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingGsm *s_gsm; - - s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ - g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); - return FALSE; - } - - if (!nm_setting_gsm_get_number (s_gsm)) - g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_GSM_SETTING_NAME, - existing_connections, - _("GSM connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection_cdma (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingCdma *s_cdma; - - s_cdma = nm_connection_get_setting_cdma (connection); - if (!s_cdma) { - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - } - - if (!nm_setting_cdma_get_number (s_cdma)) - g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_CDMA_SETTING_NAME, - existing_connections, - _("CDMA connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection (NMModem *modem, - NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - - /* If the modem has LTE, complete as 3GPP */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_LTE) - return complete_connection_3gpp (connection, existing_connections, error); - - /* Otherwise, prefer CDMA on the theory that if the modem has CDMA/EVDO - * that's most likely what the user will be using. - */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) - return complete_connection_cdma (connection, existing_connections, error); - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) - return complete_connection_3gpp (connection, existing_connections, error); - - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, - "Modem had no WWAN capabilities."); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - if (user) - *user = nm_setting_cdma_get_username (s_cdma); - if (pass) - *pass = nm_setting_cdma_get_password (s_cdma); - return TRUE; - } - } - - /* Fall back to GSM; will be used for CDMA devices on LTE networks too */ - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - if (user) - *user = nm_setting_gsm_get_username (s_gsm); - if (pass) - *pass = nm_setting_gsm_get_password (s_gsm); - return TRUE; - } - - return FALSE; -} - -/*****************************************************************************/ - -static void -get_capabilities (NMModem *_self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) -{ - NMModemOld *self = NM_MODEM_OLD (_self); - - *current_caps = *modem_caps = NM_MODEM_OLD_GET_PRIVATE (self)->caps; -} - -/*****************************************************************************/ - -NMModem * -nm_modem_old_new (const char *path, GHashTable *properties, GError **error) -{ - NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; - NMModemOld *self; - GHashTableIter iter; - const char *prop; - GValue *value; - const char *data_device = NULL; - const char *driver = NULL; - const char *master_device = NULL; - const char *unlock_required = NULL; - const char *device_id = NULL; - guint32 modem_type = MM_OLD_MODEM_TYPE_UNKNOWN; - guint32 ip_method = MM_MODEM_IP_METHOD_PPP; - guint32 ip_timeout = 0; - MMOldModemState state = MM_OLD_MODEM_STATE_UNKNOWN; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (properties != NULL, NULL); - - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, (gpointer) &prop, (gpointer) &value)) { - if (g_strcmp0 (prop, "Type") == 0) - modem_type = g_value_get_uint (value); - else if (g_strcmp0 (prop, "MasterDevice") == 0) - master_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpMethod") == 0) - ip_method = g_value_get_uint (value); - else if (g_strcmp0 (prop, "Device") == 0) - data_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "Driver") == 0) - driver = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpTimeout") == 0) - ip_timeout = g_value_get_uint (value); - else if (g_strcmp0 (prop, "State") == 0) - state = g_value_get_uint (value); - else if (g_strcmp0 (prop, "UnlockRequired") == 0) - unlock_required = g_value_get_string (value); - else if (g_strcmp0 (prop, "DeviceIdentifier") == 0) - device_id = g_value_get_string (value); - } - - if (modem_type == MM_OLD_MODEM_TYPE_UNKNOWN) { - g_set_error (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Unhandled modem type %d", modem_type); - return NULL; - } - - if (!master_device || !strlen (master_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem master device."); - return NULL; - } - - if (!driver || !strlen (driver)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem driver."); - return NULL; - } - - if (!data_device || !strlen (data_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem data device."); - return NULL; - } - - self = (NMModemOld *) g_object_new (NM_TYPE_MODEM_OLD, - NM_MODEM_PATH, path, - NM_MODEM_DRIVER, driver, - NM_MODEM_UID, data_device, - NM_MODEM_CONTROL_PORT, NULL, - NM_MODEM_DATA_PORT, data_device, - NM_MODEM_IP_METHOD, ip_method, - NM_MODEM_IP_TIMEOUT, ip_timeout, - NM_MODEM_DEVICE_ID, device_id, - NM_MODEM_STATE, mm_state_to_nm (state, unlock_required), - NULL); - if (self) { - if (modem_type == MM_OLD_MODEM_TYPE_CDMA) - caps |= NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO; - if (modem_type == MM_OLD_MODEM_TYPE_GSM) - caps |= NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; - - NM_MODEM_OLD_GET_PRIVATE (self)->caps = caps; - NM_MODEM_OLD_GET_PRIVATE (self)->state = state; - NM_MODEM_OLD_GET_PRIVATE (self)->unlock_required = g_strdup (unlock_required); - } - - return (NMModem *) self; -} - -static void -nm_modem_old_init (NMModemOld *self) -{ -} - -static void -get_sim_id_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - GValue value = G_VALUE_INIT; - - if (dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - if (G_VALUE_HOLDS_STRING (&value)) { - const char *sim_id = g_value_get_string (&value); - - if (sim_id && *sim_id) - g_object_set (G_OBJECT (self), NM_MODEM_SIM_ID, sim_id, NULL); - } - g_value_unset (&value); - } -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMModemOldPrivate *priv; - DBusGConnection *bus; - - object = G_OBJECT_CLASS (nm_modem_old_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - priv = NM_MODEM_OLD_GET_PRIVATE (object); - - bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - priv->proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - MM_OLD_DBUS_INTERFACE_MODEM); - - priv->props_proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - DBUS_INTERFACE_PROPERTIES); - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged", - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged", - G_CALLBACK (modem_properties_changed), - object, - NULL); - - /* Request the SIM ID */ - dbus_g_proxy_begin_call (priv->props_proxy, - "Get", - get_sim_id_done, - g_object_ref (object), g_object_unref, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD, - G_TYPE_STRING, "SimIdentifier", - G_TYPE_INVALID); - - return object; -} - -static void -dispose (GObject *object) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (object); - - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; - } - - if (priv->props_proxy) { - g_object_unref (priv->props_proxy); - priv->props_proxy = NULL; - } - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - g_free (priv->unlock_required); - priv->unlock_required = NULL; - - G_OBJECT_CLASS (nm_modem_old_parent_class)->dispose (object); -} - -static void -nm_modem_old_class_init (NMModemOldClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMModemClass *modem_class = NM_MODEM_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMModemOldPrivate)); - - /* Virtual methods */ - object_class->constructor = constructor; - object_class->dispose = dispose; - - modem_class->get_capabilities = get_capabilities; - modem_class->get_user_pass = get_user_pass; - modem_class->complete_connection = complete_connection; - modem_class->check_connection_compatible = check_connection_compatible; - modem_class->act_stage1_prepare = act_stage1_prepare; - modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; - modem_class->disconnect = disconnect; - modem_class->deactivate = deactivate; - modem_class->set_mm_enabled = set_mm_enabled; -} diff --git a/src/devices/wwan/nm-modem-old.h b/src/devices/wwan/nm-modem-old.h deleted file mode 100644 index 65e3db2d..00000000 --- a/src/devices/wwan/nm-modem-old.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 - 2011 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_H -#define NM_MODEM_OLD_H - -#include <dbus/dbus-glib.h> -#include <glib-object.h> -#include "nm-modem.h" -#include "nm-modem-old-types.h" - -G_BEGIN_DECLS - -#define NM_TYPE_MODEM_OLD (nm_modem_old_get_type ()) -#define NM_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OLD, NMModemOld)) -#define NM_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OLD, NMModemOldClass)) -#define NM_IS_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OLD)) -#define NM_IS_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OLD)) -#define NM_MODEM_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OLD, NMModemOldClass)) - -typedef struct { - NMModem parent; -} NMModemOld; - -typedef struct { - NMModemClass parent; -} NMModemOldClass; - -GType nm_modem_old_get_type (void); - -NMModem *nm_modem_old_new (const char *path, GHashTable *properties, GError **error); - -G_END_DECLS - -#endif /* NM_MODEM_OLD_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index fd3b4a36..ba1db8a4 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -19,6 +19,8 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include <string.h> #include "nm-modem.h" #include "nm-platform.h" @@ -42,11 +44,13 @@ enum { PROP_PATH, PROP_UID, PROP_DRIVER, - PROP_IP_METHOD, + PROP_IP4_METHOD, + PROP_IP6_METHOD, PROP_IP_TIMEOUT, PROP_STATE, PROP_DEVICE_ID, PROP_SIM_ID, + PROP_IP_TYPES, LAST_PROP }; @@ -58,11 +62,14 @@ typedef struct { char *control_port; char *data_port; char *ppp_iface; - guint32 ip_method; + NMModemIPMethod ip4_method; + NMModemIPMethod ip6_method; + NMUtilsIPv6IfaceId iid; NMModemState state; NMModemState prev_state; /* revert to this state if enable/disable fails */ char *device_id; char *sim_id; + NMModemIPType ip_types; NMPPPManager *ppp_manager; @@ -82,6 +89,7 @@ enum { PPP_FAILED, PREPARE_RESULT, IP4_CONFIG_RESULT, + IP6_CONFIG_RESULT, AUTH_REQUESTED, AUTH_RESULT, REMOVED, @@ -94,17 +102,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; /*****************************************************************************/ - -GQuark -nm_modem_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-modem-error"); - return quark; -} - -/*****************************************************************************/ /* State/enabled/connected */ static const char *state_table[] = { @@ -126,7 +123,7 @@ static const char *state_table[] = { const char * nm_modem_state_to_string (NMModemState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return NULL; } @@ -218,6 +215,102 @@ nm_modem_emit_removed (NMModem *self) g_signal_emit (self, signals[REMOVED], 0); } +NMModemIPType +nm_modem_get_supported_ip_types (NMModem *self) +{ + return NM_MODEM_GET_PRIVATE (self)->ip_types; +} + +/** + * nm_modem_get_connection_ip_type: + * @self: the #NMModem + * @connection: the #NMConnection to determine IP type to use + * + * Given a modem and a connection, determine which NMModemIpType to use + * when connecting. + * + * Returns: a single %NMModemIpType value + */ +NMModemIPType +nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMSettingIPConfig *s_ip4, *s_ip6; + const char *method; + gboolean ip4 = TRUE, ip6 = TRUE; + gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4) { + method = nm_setting_ip_config_get_method (s_ip4); + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + ip4 = FALSE; + ip4_may_fail = nm_setting_ip_config_get_may_fail (s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) { + method = nm_setting_ip_config_get_method (s_ip6); + if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + ip6 = FALSE; + ip6_may_fail = nm_setting_ip_config_get_may_fail (s_ip6); + } + + if (ip4 && !ip6) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv4 but IPv4 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV4; + } + + if (ip6 && !ip4) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv6 but IPv6 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV6; + } + + if (ip4 && ip6) { + /* Modem supports dual-stack */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) + return NM_MODEM_IP_TYPE_IPV4V6; + + /* Both IPv4 and IPv6 requested, but modem doesn't support dual-stack; + * if one method is marked "may-fail" then use the other. + */ + if (ip6_may_fail) + return NM_MODEM_IP_TYPE_IPV4; + else if (ip4_may_fail) + return NM_MODEM_IP_TYPE_IPV6; + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested both IPv4 and IPv6 " + "but dual-stack addressing is unsupported " + "by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection specified no IP configuration!"); + return NM_MODEM_IP_TYPE_UNKNOWN; +} + /*****************************************************************************/ /* IP method PPP */ @@ -237,13 +330,24 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ } static void +set_data_port (NMModem *self, const char *new_data_port) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + + if (g_strcmp0 (priv->data_port, new_data_port) != 0) { + g_free (priv->data_port); + priv->data_port = g_strdup (new_data_port); + g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + } +} + +static void ppp_ip4_config (NMPPPManager *ppp_manager, const char *iface, NMIP4Config *config, gpointer user_data) { NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); guint32 i, num; guint32 bad_dns1 = htonl (0x0A0B0C0D); guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ @@ -252,9 +356,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gboolean dns_workaround = FALSE; /* Notify about the new data port to use */ - g_free (priv->ppp_iface); - priv->ppp_iface = g_strdup (iface); - g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + set_data_port (self, iface); /* Work around a PPP bug (#1732) which causes many mobile broadband * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. @@ -296,6 +398,23 @@ ppp_ip4_config (NMPPPManager *ppp_manager, } static void +ppp_ip6_config (NMPPPManager *ppp_manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config, + gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + + /* Notify about the new data port to use */ + set_data_port (self, iface); + + NM_MODEM_GET_PRIVATE (self)->iid = *iid; + + nm_modem_emit_ip6_config_result (self, config, NULL); +} + +static void ppp_stats (NMPPPManager *ppp_manager, guint32 in_bytes, guint32 out_bytes, @@ -313,20 +432,27 @@ ppp_stats (NMPPPManager *ppp_manager, } static NMActStageReturn -ppp_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) +ppp_stage3_ip_config_start (NMModem *self, + NMActRequest *req, + NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; - guint ip_timeout = 20; + guint ip_timeout = 30; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* If we're already running PPP don't restart it; for example, if both + * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the + * same pppd for both v4 and v6. + */ + if (priv->ppp_manager) + return NM_ACT_STAGE_RETURN_POSTPONE; + if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); @@ -336,7 +462,7 @@ ppp_stage3_ip4_config_start (NMModem *self, } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, - * use the default one (20s) */ + * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); @@ -351,6 +477,9 @@ ppp_stage3_ip4_config_start (NMModem *self, g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); + g_signal_connect (priv->ppp_manager, "ip6-config", + G_CALLBACK (ppp_ip6_config), + self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); @@ -382,6 +511,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, { NMModemPrivate *priv; NMActRequest *req; + NMConnection *connection; + const char *method; NMActStageReturn ret; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -391,21 +522,36 @@ nm_modem_stage3_ip4_config_start (NMModem *self, req = nm_device_get_act_request (device); g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + + /* Only Disabled and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP4, + "(%s): unhandled WWAN IPv4 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip4_config_start (self, req, reason); + switch (priv->ip4_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_STATIC: ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_DHCP: + case NM_MODEM_IP_METHOD_AUTO: ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - ret = NM_ACT_STAGE_RETURN_FAILURE; + nm_log_info (LOGD_MB, "(%s): IPv4 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; break; } @@ -423,8 +569,8 @@ nm_modem_ip4_pre_commit (NMModem *modem, * not point-to-point) and IP config has a /32 prefix, then we assume that * ARP will be pointless and we turn it off. */ - if ( priv->ip_method == MM_MODEM_IP_METHOD_STATIC - || priv->ip_method == MM_MODEM_IP_METHOD_DHCP) { + if ( priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, 0); g_assert (address); @@ -435,15 +581,100 @@ nm_modem_ip4_pre_commit (NMModem *modem, /*****************************************************************************/ +void +nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + guint i, num; + gboolean do_slaac = TRUE; + + if (error) { + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); + return; + } + + if (config) { + /* If the IPv6 configuration only included a Link-Local address, then + * we have to run SLAAC to get the full IPv6 configuration. + */ + num = nm_ip6_config_get_num_addresses (config); + g_assert (num > 0); + for (i = 0; i < num; i++) { + const NMPlatformIP6Address * addr = nm_ip6_config_get_address (config, i); + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + if (!priv->iid.id) + priv->iid.id = ((guint64 *)(&addr->address.s6_addr))[1]; + } else + do_slaac = FALSE; + } + } + g_assert (config || do_slaac); + + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *self, NMDeviceStateReason *reason) +{ + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; +} + NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason) { - /* FIXME: We don't support IPv6 on modems quite yet... */ - nm_device_activate_schedule_ip6_config_timeout (device); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMModemPrivate *priv; + NMActStageReturn ret; + NMConnection *connection; + const char *method; + + g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + + /* Only Ignore and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP6, + "(%s): unhandled WWAN IPv6 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE (self); + switch (priv->ip6_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_AUTO: + /* Both static and DHCP/Auto retrieve a base IP config from the modem + * which in the static case is the full config, and the DHCP/Auto case + * is just the IPv6LL address to use for SLAAC. + */ + ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, reason); + break; + default: + nm_log_info (LOGD_MB, "(%s): IPv6 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; + break; + } + + return ret; } /*****************************************************************************/ @@ -486,12 +717,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -524,7 +755,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; NMConnection *connection; if (priv->act_request) @@ -543,7 +774,7 @@ nm_modem_act_stage1_prepare (NMModem *self, /* Secrets required... */ if (priv->secrets_tries++) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, @@ -633,22 +864,19 @@ deactivate (NMModem *self, NMDevice *device) priv->ppp_manager = NULL; } - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - break; - case MM_MODEM_IP_METHOD_STATIC: - case MM_MODEM_IP_METHOD_DHCP: + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || + priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { ifindex = nm_device_get_ip_ifindex (device); if (ifindex > 0) { nm_platform_route_flush (ifindex); nm_platform_address_flush (ifindex); nm_platform_link_set_down (ifindex); } - break; - default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - break; } + priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_free (priv->ppp_iface); priv->ppp_iface = NULL; @@ -772,6 +1000,15 @@ nm_modem_owns_port (NMModem *self, const char *iface) return FALSE; } +gboolean +nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid) +{ + g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + + *out_iid = NM_MODEM_GET_PRIVATE (self)->iid; + return TRUE; +} + /*****************************************************************************/ void @@ -846,8 +1083,11 @@ get_property (GObject *object, guint prop_id, case PROP_UID: g_value_set_string (value, priv->uid); break; - case PROP_IP_METHOD: - g_value_set_uint (value, priv->ip_method); + case PROP_IP4_METHOD: + g_value_set_uint (value, priv->ip4_method); + break; + case PROP_IP6_METHOD: + g_value_set_uint (value, priv->ip6_method); break; case PROP_IP_TIMEOUT: g_value_set_uint (value, priv->mm_ip_timeout); @@ -861,6 +1101,9 @@ get_property (GObject *object, guint prop_id, case PROP_SIM_ID: g_value_set_string (value, priv->sim_id); break; + case PROP_IP_TYPES: + g_value_set_uint (value, priv->ip_types); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,8 +1135,11 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->uid = g_value_dup_string (value); break; - case PROP_IP_METHOD: - priv->ip_method = g_value_get_uint (value); + case PROP_IP4_METHOD: + priv->ip4_method = g_value_get_uint (value); + break; + case PROP_IP6_METHOD: + priv->ip6_method = g_value_get_uint (value); break; case PROP_IP_TIMEOUT: priv->mm_ip_timeout = g_value_get_uint (value); @@ -909,6 +1155,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->sim_id); priv->sim_id = g_value_dup_string (value); break; + case PROP_IP_TYPES: + priv->ip_types = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -959,92 +1208,100 @@ nm_modem_class_init (NMModemClass *klass) object_class->finalize = finalize; klass->act_stage1_prepare = act_stage1_prepare; + klass->stage3_ip6_config_request = stage3_ip6_config_request; klass->deactivate = deactivate; /* Properties */ g_object_class_install_property (object_class, PROP_UID, - g_param_spec_string (NM_MODEM_UID, - "UID", - "Modem unique ID", + g_param_spec_string (NM_MODEM_UID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_MODEM_PATH, - "DBus path", - "DBus path", + g_param_spec_string (NM_MODEM_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_MODEM_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_MODEM_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONTROL_PORT, - g_param_spec_string (NM_MODEM_CONTROL_PORT, - "Control port", - "The port controlling the modem", + g_param_spec_string (NM_MODEM_CONTROL_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DATA_PORT, - g_param_spec_string (NM_MODEM_DATA_PORT, - "Data port", - "The port to connect to", + g_param_spec_string (NM_MODEM_DATA_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property - (object_class, PROP_IP_METHOD, - g_param_spec_uint (NM_MODEM_IP_METHOD, - "IP method", - "IP method", - MM_MODEM_IP_METHOD_PPP, - MM_MODEM_IP_METHOD_DHCP, - MM_MODEM_IP_METHOD_PPP, - G_PARAM_READWRITE)); + (object_class, PROP_IP4_METHOD, + g_param_spec_uint (NM_MODEM_IP4_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP6_METHOD, + g_param_spec_uint (NM_MODEM_IP6_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_TIMEOUT, - g_param_spec_uint (NM_MODEM_IP_TIMEOUT, - "IP timeout", - "IP timeout", + g_param_spec_uint (NM_MODEM_IP_TIMEOUT, "", "", 0, 360, 20, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_enum (NM_MODEM_STATE, - "State", - "State", - NM_TYPE_MODEM_STATE, - NM_MODEM_STATE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_enum (NM_MODEM_STATE, "", "", + NM_TYPE_MODEM_STATE, + NM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_ID, - g_param_spec_string (NM_MODEM_DEVICE_ID, - "DeviceId", - "Device ID", + g_param_spec_string (NM_MODEM_DEVICE_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIM_ID, - g_param_spec_string (NM_MODEM_SIM_ID, - "SimId", - "Sim ID", + g_param_spec_string (NM_MODEM_SIM_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP_TYPES, + g_param_spec_uint (NM_MODEM_IP_TYPES, + "IP Types", + "Supported IP types", + 0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /* Signals */ @@ -1073,6 +1330,27 @@ nm_modem_class_init (NMModemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); + /** + * NMModem::ip6-config-result: + * @modem: the #NMModem on which the signal is emitted + * @config: the #NMIP6Config to apply to the modem's data port + * @do_slaac: %TRUE if IPv6 SLAAC should be started + * @error: a #GError if any error occurred during IP configuration + * + * This signal is emitted when IPv6 configuration has completed or failed. + * If @error is set the configuration failed. If @config is set, then + * the details should be applied to the data port before any further + * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC + * should be started after applying @config to the data port. + */ + signals[IP6_CONFIG_RESULT] = + g_signal_new (NM_MODEM_IP6_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ip6_config_result), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_POINTER); + signals[PREPARE_RESULT] = g_signal_new (NM_MODEM_PREPARE_RESULT, G_OBJECT_CLASS_TYPE (object_class), @@ -1112,8 +1390,4 @@ nm_modem_class_init (NMModemClass *klass) G_STRUCT_OFFSET (NMModemClass, state_changed), NULL, NULL, NULL, G_TYPE_NONE, 2, NM_TYPE_MODEM_STATE, NM_TYPE_MODEM_STATE); - - dbus_g_error_domain_register (NM_MODEM_ERROR, - NM_DBUS_INTERFACE_DEVICE_MODEM, - NM_TYPE_MODEM_ERROR); } diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c992cf72..2a4d9173 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -19,10 +19,9 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_MODEM_H -#define NM_MODEM_H +#ifndef __NETWORKMANAGER_MODEM_H__ +#define __NETWORKMANAGER_MODEM_H__ -#include <dbus/dbus-glib.h> #include <glib-object.h> #include "ppp-manager/nm-ppp-manager.h" #include "nm-device.h" @@ -42,33 +41,50 @@ G_BEGIN_DECLS #define NM_MODEM_DRIVER "driver" #define NM_MODEM_CONTROL_PORT "control-port" #define NM_MODEM_DATA_PORT "data-port" -#define NM_MODEM_IP_METHOD "ip-method" +#define NM_MODEM_IP4_METHOD "ip4-method" +#define NM_MODEM_IP6_METHOD "ip6-method" #define NM_MODEM_IP_TIMEOUT "ip-timeout" #define NM_MODEM_STATE "state" #define NM_MODEM_DEVICE_ID "device-id" #define NM_MODEM_SIM_ID "sim-id" +#define NM_MODEM_IP_TYPES "ip-types" /* Supported IP types */ /* Signals */ #define NM_MODEM_PPP_STATS "ppp-stats" #define NM_MODEM_PPP_FAILED "ppp-failed" #define NM_MODEM_PREPARE_RESULT "prepare-result" #define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result" +#define NM_MODEM_IP6_CONFIG_RESULT "ip6-config-result" #define NM_MODEM_AUTH_REQUESTED "auth-requested" #define NM_MODEM_AUTH_RESULT "auth-result" #define NM_MODEM_REMOVED "removed" #define NM_MODEM_STATE_CHANGED "state-changed" -#define MM_MODEM_IP_METHOD_PPP 0 -#define MM_MODEM_IP_METHOD_STATIC 1 -#define MM_MODEM_IP_METHOD_DHCP 2 - typedef enum { - NM_MODEM_ERROR_CONNECTION_NOT_GSM, /*< nick=ConnectionNotGsm >*/ - NM_MODEM_ERROR_CONNECTION_NOT_CDMA, /*< nick=ConnectionNotCdma >*/ - NM_MODEM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_MODEM_ERROR_INITIALIZATION_FAILED, /*< nick=InitializationFailed >*/ -} NMModemError; + NM_MODEM_IP_METHOD_UNKNOWN = 0, + NM_MODEM_IP_METHOD_PPP, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */ +} NMModemIPMethod; + +/** + * NMModemIPType: + * @NM_MODEM_IP_TYPE_UNKNOWN: unknown or no IP support + * @NM_MODEM_IP_TYPE_IPV4: IPv4-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV6: IPv6-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV4V6: dual-stack IPv4 + IPv6 bearers are supported + * + * Indicates what IP protocols the modem supports for an IP bearer. Any + * combination of flags is possible. For example, (%NM_MODEM_IP_TYPE_IPV4 | + * %NM_MODEM_IP_TYPE_IPV6) indicates that the modem supports IPv4 and IPv6 + * but not simultaneously on the same bearer. + */ +typedef enum { + NM_MODEM_IP_TYPE_UNKNOWN = 0x0, + NM_MODEM_IP_TYPE_IPV4 = 0x1, + NM_MODEM_IP_TYPE_IPV6 = 0x2, + NM_MODEM_IP_TYPE_IPV4V6 = 0x4 +} NMModemIPType; typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_UNKNOWN = 0, @@ -86,9 +102,6 @@ typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_CONNECTED = 12, } NMModemState; -#define NM_MODEM_ERROR (nm_modem_error_quark ()) -GQuark nm_modem_error_quark (void); - typedef struct { GObject parent; @@ -122,6 +135,12 @@ typedef struct { NMActRequest *req, NMDeviceStateReason *reason); + /* Request the IP6 config; when the config returns the modem + * subclass should emit the ip6_config_result signal. + */ + NMActStageReturn (*stage3_ip6_config_request) (NMModem *self, + NMDeviceStateReason *reason); + void (*set_mm_enabled) (NMModem *self, gboolean enabled); void (*disconnect) (NMModem *self, gboolean warn); @@ -136,6 +155,10 @@ typedef struct { void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason); void (*ip4_config_result) (NMModem *self, NMIP4Config *config, GError *error); + void (*ip6_config_result) (NMModem *self, + NMIP6Config *config, + gboolean do_slaac, + GError *error); void (*auth_requested) (NMModem *self); void (*auth_result) (NMModem *self, GError *error); @@ -154,6 +177,7 @@ const char *nm_modem_get_uid (NMModem *modem); 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_get_iid (NMModem *modem, NMUtilsIPv6IfaceId *out_iid); gboolean nm_modem_owns_port (NMModem *modem, const char *iface); @@ -182,8 +206,7 @@ NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem, NMDeviceStateReason *reason); NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason); void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config); @@ -209,9 +232,20 @@ void nm_modem_set_state (NMModem *self, void nm_modem_set_prev_state (NMModem *self, const char *reason); const char * nm_modem_state_to_string (NMModemState state); +NMModemIPType nm_modem_get_supported_ip_types (NMModem *self); + /* For the modem-manager only */ void nm_modem_emit_removed (NMModem *self); +NMModemIPType nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error); + +/* For subclasses */ +void nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error); + G_END_DECLS -#endif /* NM_MODEM_H */ +#endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index b1e2307e..2b9c3d4d 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -18,10 +18,11 @@ * Copyright (C) 2014 Red Hat, Inc. */ +#include "config.h" + #include <string.h> #include <gmodule.h> -#include "config.h" #include "nm-device-factory.h" #include "nm-wwan-factory.h" #include "nm-modem-manager.h" @@ -43,20 +44,12 @@ typedef struct { /************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_MODEM - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WWAN_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ static void @@ -93,9 +86,17 @@ modem_added_cb (NMModemManager *manager, g_object_unref (device); } + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_MODEM; +} + static void -nm_wwan_factory_init (NMWwanFactory *self) +start (NMDeviceFactory *factory) { + NMWwanFactory *self = NM_WWAN_FACTORY (factory); NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); priv->mm = g_object_new (NM_TYPE_MODEM_MANAGER, NULL); @@ -107,8 +108,15 @@ nm_wwan_factory_init (NMWwanFactory *self) } static void +nm_wwan_factory_init (NMWwanFactory *self) +{ +} + +static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h index b7aee01f..c6c03f1f 100644 --- a/src/devices/wwan/nm-wwan-factory.h +++ b/src/devices/wwan/nm-wwan-factory.h @@ -18,8 +18,8 @@ * Copyright (C) 2014 Red Hat, Inc. */ -#ifndef NM_WWAN_FACTORY_H -#define NM_WWAN_FACTORY_H +#ifndef __NETWORKMANAGER_WWAN_FACTORY_H__ +#define __NETWORKMANAGER_WWAN_FACTORY_H__ #include <glib-object.h> @@ -34,4 +34,4 @@ typedef struct { GObjectClass parent; } NMWwanFactoryClass; -#endif /* NM_WWAN_FACTORY_H */ +#endif /* __NETWORKMANAGER_WWAN_FACTORY_H__ */ diff --git a/src/devices/wwan/wwan-exports.ver b/src/devices/wwan/wwan-exports.ver index dc505d17..c23ab24b 100644 --- a/src/devices/wwan/wwan-exports.ver +++ b/src/devices/wwan/wwan-exports.ver @@ -6,11 +6,11 @@ global: nm_modem_complete_connection; nm_modem_deactivate; nm_modem_device_state_changed; - nm_modem_error_quark; nm_modem_get_capabilities; nm_modem_get_control_port; nm_modem_get_data_port; nm_modem_get_driver; + nm_modem_get_iid; nm_modem_get_path; nm_modem_get_secrets; nm_modem_get_state; |