diff options
Diffstat (limited to 'src/devices/wwan')
| -rw-r--r-- | src/devices/wwan/Makefile.am | 13 | ||||
| -rw-r--r-- | src/devices/wwan/Makefile.in | 51 | ||||
| -rw-r--r-- | src/devices/wwan/nm-device-modem.c | 33 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-broadband.c | 158 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-broadband.h | 6 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-enum-types.c | 1 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-manager.c | 372 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-ofono.c | 1202 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem-ofono.h | 53 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 8 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.h | 5 | ||||
| -rw-r--r-- | src/devices/wwan/nm-wwan-factory.c | 4 | ||||
| -rw-r--r-- | src/devices/wwan/nm-wwan-factory.h | 2 |
13 files changed, 1678 insertions, 230 deletions
diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 1777eb36..0d061a79 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -16,6 +16,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) @@ -26,7 +27,7 @@ pkglib_LTLIBRARIES = libnm-wwan.la libnm-device-plugin-wwan.la 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 +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' nm_modem_enum_types_sources = $(srcdir)/nm-modem.h BUILT_SOURCES += $(GLIB_GENERATED) @@ -41,6 +42,13 @@ libnm_wwan_la_SOURCES = \ \ $(GLIB_GENERATED) +if WITH_OFONO +libnm_wwan_la_SOURCES += \ + nm-modem-ofono.c \ + nm-modem-ofono.h \ + $(NULL) +endif + WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ @@ -49,6 +57,7 @@ libnm_wwan_la_LDFLAGS = \ libnm_wwan_la_LIBADD = \ $(top_builddir)/introspection/libnmdbus.la \ $(GLIB_LIBS) \ + $(LIBSYSTEMD_LIBS) \ $(MM_GLIB_LIBS) ########################################################### @@ -79,7 +88,9 @@ if ENABLE_TESTS check-local: $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wwan.so $(SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-wwan.so $(WWAN_SYMBOL_VIS_FILE) + LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null endif diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index 89328665..6d395567 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -88,10 +88,16 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@WITH_OFONO_TRUE@am__append_1 = \ +@WITH_OFONO_TRUE@ nm-modem-ofono.c \ +@WITH_OFONO_TRUE@ nm-modem-ofono.h \ +@WITH_OFONO_TRUE@ $(NULL) + subdir = src/devices/wwan ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -157,10 +163,16 @@ libnm_device_plugin_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ libnm_wwan_la_DEPENDENCIES = \ $(top_builddir)/introspection/libnmdbus.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__libnm_wwan_la_SOURCES_DIST = nm-modem-broadband.c \ + nm-modem-broadband.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-ofono.c nm-modem-ofono.h am__objects_1 = nm-modem-enum-types.lo +@WITH_OFONO_TRUE@am__objects_2 = nm-modem-ofono.lo am_libnm_wwan_la_OBJECTS = nm-modem-broadband.lo nm-modem-manager.lo \ - nm-modem.lo $(am__objects_1) + nm-modem.lo $(am__objects_1) $(am__objects_2) 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) \ @@ -202,7 +214,7 @@ am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ $(libnm_wwan_la_SOURCES) DIST_SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ - $(libnm_wwan_la_SOURCES) + $(am__libnm_wwan_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -264,6 +276,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -320,13 +333,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -338,6 +352,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -398,6 +414,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -433,6 +451,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -508,6 +527,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \ $(GLIB_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) @@ -516,18 +536,11 @@ pkglib_LTLIBRARIES = libnm-wwan.la libnm-device-plugin-wwan.la ########################################################### 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 +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "nm-default.h"\n' nm_modem_enum_types_sources = $(srcdir)/nm-modem.h -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) - +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) $(am__append_1) WWAN_SYMBOL_VIS_FILE = $(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ -avoid-version \ @@ -536,6 +549,7 @@ libnm_wwan_la_LDFLAGS = \ libnm_wwan_la_LIBADD = \ $(top_builddir)/introspection/libnmdbus.la \ $(GLIB_LIBS) \ + $(LIBSYSTEMD_LIBS) \ $(MM_GLIB_LIBS) @@ -646,6 +660,7 @@ 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-ofono.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@ @@ -897,7 +912,9 @@ include $(GLIB_MAKEFILE) @ENABLE_TESTS_TRUE@check-local: @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wwan.so $(SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-device-plugin-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null @ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-wwan.so $(WWAN_SYMBOL_VIS_FILE) +@ENABLE_TESTS_TRUE@ LD_BIND_NOW=1 LD_PRELOAD=$(builddir)/.libs/libnm-wwan.so $(top_builddir)/src/NetworkManager --version >/dev/null # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index a8361c49..0f96dafb 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -60,6 +60,7 @@ static void ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: @@ -73,7 +74,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) case NM_DEVICE_STATE_ACTIVATED: if (nm_device_activate_ip4_state_in_conf (device)) nm_device_activate_schedule_ip4_config_timeout (device); - else { + else if (nm_device_activate_ip6_state_in_conf (device)) + nm_device_activate_schedule_ip6_config_timeout (device); + else if (nm_device_activate_ip4_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else if (nm_device_activate_ip6_state_done (device)) { + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device)); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); @@ -159,8 +171,9 @@ modem_ip4_config_result (NMModem *modem, if (error) { _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message); - - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_ip_method_failed (device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else { nm_device_set_wwan_ip4_config (device, config); nm_device_activate_schedule_ip4_config_result (device, NULL); @@ -184,9 +197,11 @@ modem_ip6_config_result (NMModem *modem, g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); if (error) { - _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message); - - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", + error->message); + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); return; } @@ -201,7 +216,9 @@ modem_ip6_config_result (NMModem *modem, 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); + nm_device_ip_method_failed (device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } return; } @@ -211,7 +228,7 @@ modem_ip6_config_result (NMModem *modem, g_assert (ignored == NULL); switch (ret) { case NM_ACT_STAGE_RETURN_FAILURE: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + nm_device_ip_method_failed (device, AF_INET6, reason); break; case NM_ACT_STAGE_RETURN_STOP: /* all done */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 1a6e6b25..727c8409 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -30,6 +30,8 @@ #include "nm-device-private.h" #include "nm-platform.h" +#define NM_MODEM_BROADBAND_MODEM "modem" + G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) typedef enum { @@ -89,8 +91,35 @@ enum { /*****************************************************************************/ +#define _NMLOG_DOMAIN LOGD_MB +#define _NMLOG_PREFIX_NAME "modem-broadband" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ + NMModemBroadband *const __self = (self); \ + char __prefix_name[128]; \ + const char *__uid; \ + \ + _nm_log (_level, (_NMLOG_DOMAIN), 0, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self \ + ? ({ \ + ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ + ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + static NMDeviceStateReason -translate_mm_error (GError *error) +translate_mm_error (NMModemBroadband *self, GError *error) { NMDeviceStateReason reason; @@ -122,7 +151,7 @@ translate_mm_error (GError *error) 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 error detected: '%s'", error->message); + _LOGD ("unmapped error detected: '%s'", error->message); reason = NM_DEVICE_STATE_REASON_UNKNOWN; } @@ -288,7 +317,7 @@ connect_context_clear (NMModemBroadband *self) g_clear_error (&ctx->first_error); g_clear_pointer (&ctx->ip_types, (GDestroyNotify) g_array_unref); - g_clear_object (&ctx->cancellable); + nm_clear_g_cancellable (&ctx->cancellable); g_clear_object (&ctx->connection); g_clear_object (&ctx->connect_properties); g_clear_object (&ctx->self); @@ -360,8 +389,7 @@ connect_ready (MMModemSimple *simple_iface, 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))); + _LOGW ("failed to connect modem: invalid bearer IP configuration"); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); connect_context_clear (self); return; @@ -389,7 +417,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self) return; if (!self->priv->ctx || self->priv->ctx->step != CONNECT_STEP_UNLOCK) - return; + g_return_if_reached (); if (error) { if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || @@ -397,7 +425,7 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self) mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { ask_for_pin (self); } else { - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, error)); } return; } @@ -459,9 +487,8 @@ connect_context_step (NMModemBroadband *self) else if (MODEM_CAPS_3GPP2 (ctx->caps)) ctx->connect_properties = create_cdma_connect_properties (ctx->connection); else { - nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': not a mobile broadband modem", - nm_modem_get_uid (NM_MODEM (self)), - nm_connection_get_id (ctx->connection)); + _LOGW ("failed to connect '%s': not a mobile broadband modem", + nm_connection_get_id (ctx->connection)); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); connect_context_clear (self); @@ -472,10 +499,9 @@ connect_context_step (NMModemBroadband *self) /* Build up list of IP types that we need to use in the retries */ ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), ctx->connection, &error); if (!ctx->ip_types) { - nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s", - nm_modem_get_uid (NM_MODEM (self)), - nm_connection_get_id (ctx->connection), - error->message); + _LOGW ("failed to connect '%s': %s", + nm_connection_get_id (ctx->connection), + error->message); g_clear_error (&error); g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); @@ -502,10 +528,9 @@ connect_context_step (NMModemBroadband *self) else g_assert_not_reached (); - nm_log_dbg (LOGD_MB, "(%s): launching connection with ip type '%s' (try %d)", - nm_modem_get_uid (NM_MODEM (self)), - nm_modem_ip_type_to_string (current), - ctx->ip_type_tries + 1); + _LOGD ("launching connection with ip type '%s' (try %d)", + nm_modem_ip_type_to_string (current), + ctx->ip_type_tries + 1); mm_modem_simple_connect (self->priv->simple_iface, ctx->connect_properties, @@ -528,10 +553,9 @@ connect_context_step (NMModemBroadband *self) NM_DEVICE_ERROR_INVALID_CONNECTION, "invalid bearer IP configuration"); - nm_log_warn (LOGD_MB, "(%s): failed to connect modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - ctx->first_error->message); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (ctx->first_error)); + _LOGW ("failed to connect modem: %s", + ctx->first_error->message); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (self, ctx->first_error)); } connect_context_clear (self); @@ -550,8 +574,7 @@ act_stage1_prepare (NMModem *_self, if (!self->priv->simple_iface) { self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object); if (!self->priv->simple_iface) { - nm_log_warn (LOGD_MB, "(%s) cannot access the Simple mobile broadband modem interface", - nm_modem_get_uid (NM_MODEM (self))); + _LOGW ("cannot access the Simple mobile broadband modem interface"); *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -745,9 +768,8 @@ set_power_state_low_ready (MMModem *modem, if (!mm_modem_set_power_state_finish (modem, result, &error)) { /* Log but ignore errors; not all modems support low power state */ - nm_log_dbg (LOGD_MB, "(%s): failed to set modem low power state: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _LOGD ("failed to set modem low power state: %s", + NM_G_ERROR_MSG (error)); g_clear_error (&error); } @@ -770,9 +792,8 @@ modem_disable_ready (MMModem *modem_iface, (GAsyncReadyCallback) set_power_state_low_ready, g_object_ref (self)); } else { - nm_log_warn (LOGD_MB, "(%s): failed to disable modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _LOGW ("failed to disable modem: %s", + NM_G_ERROR_MSG (error)); nm_modem_set_prev_state (NM_MODEM (self), "disable failed"); g_clear_error (&error); } @@ -789,9 +810,8 @@ modem_enable_ready (MMModem *modem_iface, GError *error = NULL; if (!mm_modem_enable_finish (modem_iface, res, &error)) { - nm_log_warn (LOGD_MB, "(%s) failed to enable modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _LOGW ("failed to enable modem: %s", + NM_G_ERROR_MSG (error)); nm_modem_set_prev_state (NM_MODEM (self), "enable failed"); g_clear_error (&error); } @@ -854,8 +874,7 @@ static_stage3_ip4_done (NMModemBroadband *self) g_assert (self->priv->ipv4_config); g_assert (self->priv->bearer); - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", - nm_modem_get_uid (NM_MODEM (self))); + _LOGI ("IPv4 static configuration:"); /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config); @@ -880,15 +899,15 @@ static_stage3_ip4_done (NMModemBroadband *self) address.address = address_network; address.peer_address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); - address.source = NM_IP_CONFIG_SOURCE_WWAN; + address.addr_source = NM_IP_CONFIG_SOURCE_WWAN; if (address.plen <= 32) nm_ip4_config_add_address (config, &address); - nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + _LOGI (" address %s/%d", address_string, address.plen); if (gw) { nm_ip4_config_set_gateway (config, gw); - nm_log_info (LOGD_MB, " gateway %s", gw_string); + _LOGI (" gateway %s", gw_string); } /* DNS servers */ @@ -897,7 +916,7 @@ static_stage3_ip4_done (NMModemBroadband *self) 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]); + _LOGI (" DNS %s", dns[i]); } } @@ -964,8 +983,7 @@ stage3_ip6_done (NMModemBroadband *self) goto out; } - nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:", - nm_modem_get_uid (NM_MODEM (self))); + _LOGI ("IPv6 base configuration:"); data_port = mm_bearer_get_interface (self->priv->bearer); g_assert (data_port); @@ -975,7 +993,7 @@ stage3_ip6_done (NMModemBroadband *self) if (address.plen <= 128) nm_ip6_config_add_address (config, &address); - nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + _LOGI (" address %s/%d", address_string, address.plen); address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config); if (address_string) { @@ -987,7 +1005,7 @@ stage3_ip6_done (NMModemBroadband *self) address_string); goto out; } - nm_log_info (LOGD_MB, " gateway %s", address_string); + _LOGI (" 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 */ @@ -1005,7 +1023,7 @@ stage3_ip6_done (NMModemBroadband *self) if (inet_pton (AF_INET6, dns[i], &addr)) { nm_ip6_config_add_nameserver (config, &addr); - nm_log_info (LOGD_MB, " DNS %s", dns[i]); + _LOGI (" DNS %s", dns[i]); } } @@ -1050,19 +1068,6 @@ disconnect_context_complete (DisconnectContext *ctx) } static gboolean -disconnect_context_complete_if_cancelled (DisconnectContext *ctx) -{ - GError *error = NULL; - - if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { - g_simple_async_result_take_error (ctx->result, error); - disconnect_context_complete (ctx); - return TRUE; - } - return FALSE; -} - -static gboolean disconnect_finish (NMModem *self, GAsyncResult *res, GError **error) @@ -1079,9 +1084,10 @@ simple_disconnect_ready (MMModemSimple *modem_iface, if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) { if (ctx->warn && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { - nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s", - nm_modem_get_uid (NM_MODEM (ctx->self)), - error->message); + NMModemBroadband *self = ctx->self; + + _LOGW ("failed to disconnect modem: %s", + error->message); } g_simple_async_result_take_error (ctx->result, error); } @@ -1098,9 +1104,11 @@ disconnect (NMModem *modem, { NMModemBroadband *self = NM_MODEM_BROADBAND (modem); DisconnectContext *ctx; + GError *error = NULL; connect_context_clear (self); ctx = g_slice_new (DisconnectContext); + ctx->cancellable = NULL; ctx->self = g_object_ref (self); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, @@ -1109,10 +1117,12 @@ disconnect (NMModem *modem, /* Don't bother warning on FAILED since the modem is already gone */ ctx->warn = warn; - /* Setup cancellable */ - ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - if (disconnect_context_complete_if_cancelled (ctx)) + /* Already cancelled? */ + if (g_cancellable_set_error_if_cancelled (cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + disconnect_context_complete (ctx); return; + } /* If no simple iface, we're done */ if (!ctx->self->priv->simple_iface) { @@ -1120,14 +1130,13 @@ disconnect (NMModem *modem, return; } - nm_log_dbg (LOGD_MB, "(%s): notifying ModemManager about the modem disconnection", - nm_modem_get_uid (NM_MODEM (ctx->self))); - mm_modem_simple_disconnect ( - ctx->self->priv->simple_iface, - NULL, /* bearer path; if NULL given ALL get disconnected */ - cancellable, - (GAsyncReadyCallback)simple_disconnect_ready, - ctx); + _LOGD ("notifying ModemManager about the modem disconnection"); + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + mm_modem_simple_disconnect (ctx->self->priv->simple_iface, + NULL, /* bearer path; if NULL given ALL get disconnected */ + cancellable, + (GAsyncReadyCallback) simple_disconnect_ready, + ctx); } /*****************************************************************************/ @@ -1274,9 +1283,10 @@ get_sim_ready (MMModem *modem, if (self->priv->ctx && self->priv->ctx->step == CONNECT_STEP_WAIT_FOR_SIM) connect_context_step (self); } else { - nm_log_warn (LOGD_MB, "(%s): failed to retrieve SIM object: %s", - nm_modem_get_uid (NM_MODEM (self)), - NM_G_ERROR_MSG (error)); + _NMLOG (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND) + ? LOGL_INFO : LOGL_WARN, + "failed to retrieve SIM object: %s", + NM_G_ERROR_MSG (error)); } g_clear_error (&error); g_object_unref (self); diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index a54e63a6..6607f7f5 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -23,8 +23,6 @@ #include "nm-modem.h" -G_BEGIN_DECLS - #define NM_TYPE_MODEM_BROADBAND (nm_modem_broadband_get_type ()) #define NM_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadband)) #define NM_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) @@ -32,8 +30,6 @@ G_BEGIN_DECLS #define NM_IS_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_BROADBAND)) #define NM_MODEM_BROADBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) -#define NM_MODEM_BROADBAND_MODEM "modem" - typedef struct _NMModemBroadband NMModemBroadband; typedef struct _NMModemBroadbandClass NMModemBroadbandClass; typedef struct _NMModemBroadbandPrivate NMModemBroadbandPrivate; @@ -51,6 +47,4 @@ GType nm_modem_broadband_get_type (void); NMModem *nm_modem_broadband_new (GObject *object, GError **error); -G_END_DECLS - #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 2d02ede9..f999b084 100644 --- a/src/devices/wwan/nm-modem-enum-types.c +++ b/src/devices/wwan/nm-modem-enum-types.c @@ -6,6 +6,7 @@ #include "config.h" #include "nm-modem-enum-types.h" +#include "nm-default.h" #include "nm-modem.h" diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index e26321b0..964485fc 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -17,20 +17,30 @@ * * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. - * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 - 2013 Canonical Ltd. */ #include "nm-default.h" -#include <string.h> +#include "nm-modem-manager.h" +#include <string.h> #include <libmm-glib.h> -#include "nm-modem-manager.h" +#if HAVE_LIBSYSTEMD +#include <systemd/sd-daemon.h> +#else +#define sd_booted() FALSE +#endif + #include "nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" +#if WITH_OFONO +#include "nm-modem-ofono.h" +#endif + #define MODEM_POKE_INTERVAL 120 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) @@ -39,9 +49,13 @@ struct _NMModemManagerPrivate { GDBusConnection *dbus_connection; MMManager *modem_manager; guint mm_launch_id; - guint mm_name_owner_changed_id; - guint mm_object_added_id; - guint mm_object_removed_id; + gulong mm_name_owner_changed_id; + gulong mm_object_added_id; + gulong mm_object_removed_id; + +#if WITH_OFONO + GDBusProxy *ofono_proxy; +#endif /* Common */ GHashTable *modems; @@ -79,34 +93,14 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) } static void -modem_manager_clear_signals (NMModemManager *self) +clear_modem_manager (NMModemManager *self) { if (!self->priv->modem_manager) return; - - 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->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; - } - - 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; - } + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_name_owner_changed_id); + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_object_added_id); + nm_clear_g_signal_handler (self->priv->modem_manager, &self->priv->mm_object_removed_id); + g_clear_object (&self->priv->modem_manager); } static void @@ -183,7 +177,7 @@ modem_manager_available (NMModemManager *self) static void schedule_modem_manager_relaunch (NMModemManager *self, guint n_seconds); -static void ensure_client (NMModemManager *self); +static void ensure_modem_manager (NMModemManager *self); static void modem_manager_name_owner_changed (MMManager *modem_manager, @@ -199,10 +193,9 @@ modem_manager_name_owner_changed (MMManager *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_relaunch (self, 0); -#endif + if (!sd_booted ()) + schedule_modem_manager_relaunch (self, 0); return; } @@ -214,16 +207,173 @@ modem_manager_name_owner_changed (MMManager *modem_manager, * 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_clear_signals (self); - g_clear_object (&self->priv->modem_manager); - ensure_client (self); + clear_modem_manager (self); + ensure_modem_manager (self); /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: * modem_manager_available (self); */ } -#if !HAVE_SYSTEMD +#if WITH_OFONO +static void +ofono_create_modem (NMModemManager *self, const char *path) +{ + NMModem *modem = NULL; + + /* Ensure duplicate modems aren't created. Because we're not using the + * ObjectManager interface there's a race during oFono startup where we + * receive ModemAdded signals before GetModems() returns, so some of the + * modems returned from GetModems() may already have been created. + */ + if (!g_hash_table_lookup (self->priv->modems, path)) { + modem = nm_modem_ofono_new (path); + if (modem) + handle_new_modem (self, modem); + else + nm_log_warn (LOGD_MB, "Failed to create oFono modem for %s", path); + } +} + +static void +ofono_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMModemManager *self = NM_MODEM_MANAGER (user_data); + gchar *object_path; + NMModem *modem; + + if (g_strcmp0 (signal_name, "ModemAdded") == 0) { + g_variant_get (parameters, "(oa{sv})", &object_path, NULL); + nm_log_info (LOGD_MB, "oFono modem appeared: %s", object_path); + + ofono_create_modem (NM_MODEM_MANAGER (user_data), object_path); + g_free (object_path); + } else if (g_strcmp0 (signal_name, "ModemRemoved") == 0) { + g_variant_get (parameters, "(o)", &object_path); + nm_log_info (LOGD_MB, "oFono modem removed: %s", object_path); + + modem = (NMModem *) g_hash_table_lookup (self->priv->modems, object_path); + if (modem) { + nm_modem_emit_removed (modem); + g_hash_table_remove (self->priv->modems, object_path); + } else { + nm_log_warn (LOGD_MB, "could not remove modem %s, not found in table", + object_path); + } + g_free (object_path); + } +} + +static void +ofono_enumerate_devices_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) +{ + NMModemManager *manager = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + GVariant *results; + GVariantIter *iter; + const char *path; + + results = g_dbus_proxy_call_finish (proxy, res, &error); + if (results) { + g_variant_get (results, "(a(oa{sv}))", &iter); + while (g_variant_iter_loop (iter, "(&oa{sv})", &path, NULL)) + ofono_create_modem (manager, path); + g_variant_iter_free (iter); + g_variant_unref (results); + } + + if (error) { + nm_log_warn (LOGD_MB, "failed to enumerate oFono devices: %s", + error->message); + } +} + +static void +ofono_check_name_owner (NMModemManager *self) +{ + gs_free char *name_owner = NULL; + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (self->priv->ofono_proxy)); + if (name_owner) { + nm_log_info (LOGD_MB, "oFono is now available"); + + g_dbus_proxy_call (self->priv->ofono_proxy, + "GetModems", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) ofono_enumerate_devices_done, + g_object_ref (self)); + } else { + GHashTableIter iter; + NMModem *modem; + + nm_log_info (LOGD_MB, "oFono disappeared from bus"); + + /* Remove any oFono modems that might be left around */ + g_hash_table_iter_init (&iter, self->priv->modems); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &modem)) { + if (NM_IS_MODEM_OFONO (modem)) { + nm_modem_emit_removed (modem); + g_hash_table_iter_remove (&iter); + } + } + } +} + +static void +ofono_name_owner_changed (GDBusProxy *ofono_proxy, + GParamSpec *pspec, + NMModemManager *self) +{ + ofono_check_name_owner (self); +} + +static void +ofono_proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + gs_unref_object NMModemManager *self = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + + self->priv->ofono_proxy = g_dbus_proxy_new_finish (res, &error); + if (error) { + nm_log_warn (LOGD_MB, "error getting oFono bus proxy: %s", error->message); + return; + } + + g_signal_connect (self->priv->ofono_proxy, + "notify::g-name-owner", + G_CALLBACK (ofono_name_owner_changed), + self); + + g_signal_connect (self->priv->ofono_proxy, + "g-signal", + G_CALLBACK (ofono_signal_cb), + self); + + ofono_check_name_owner (self); +} + +static void +ensure_ofono_client (NMModemManager *self) +{ + g_assert (self->priv->dbus_connection); + g_dbus_proxy_new (self->priv->dbus_connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + OFONO_DBUS_PATH, + OFONO_DBUS_INTERFACE, + NULL, + (GAsyncReadyCallback) ofono_proxy_new_cb, + g_object_ref (self)); +} +#endif static void modem_manager_poke_cb (GDBusConnection *connection, @@ -235,19 +385,18 @@ modem_manager_poke_cb (GDBusConnection *connection, result = g_dbus_connection_call_finish (connection, res, &error); if (error) { - /* Ignore common errors when MM is not installed and such */ - if ( !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_EXEC_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FORK_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FAILED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMEOUT) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { - nm_log_dbg (LOGD_MB, "error poking ModemManager: %s", error->message); + nm_log_warn (LOGD_MB, "error poking ModemManager: %s", + error ? error->message : ""); + + /* Don't reschedule poke is MM service doesn't exist. */ + if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) + && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { + + /* Setup timeout to relaunch */ + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } - g_error_free (error); - /* Setup timeout to relaunch */ - schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); + g_error_free (error); } else g_variant_unref (result); @@ -273,25 +422,21 @@ modem_manager_poke (NMModemManager *self) g_object_ref (self)); /* user_data */ } -#endif /* HAVE_SYSTEMD */ - static void modem_manager_check_name_owner (NMModemManager *self) { - gchar *name_owner; + gs_free gchar *name_owner = NULL; 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_available (self); - g_free (name_owner); return; } -#if !HAVE_SYSTEMD /* If the lifecycle is not managed by systemd, poke */ - modem_manager_poke (self); -#endif + if (!sd_booted ()) + modem_manager_poke (self); } static void @@ -303,7 +448,8 @@ manager_new_ready (GObject *source, GError *error = NULL; - g_assert (!self->priv->modem_manager); + g_return_if_fail (!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, @@ -316,20 +462,20 @@ manager_new_ready (GObject *source, } else { /* Setup signals in the GDBusObjectManagerClient */ self->priv->mm_name_owner_changed_id = - g_signal_connect (self->priv->modem_manager, - "notify::name-owner", - G_CALLBACK (modem_manager_name_owner_changed), - self); + g_signal_connect (self->priv->modem_manager, + "notify::name-owner", + G_CALLBACK (modem_manager_name_owner_changed), + self); self->priv->mm_object_added_id = - g_signal_connect (self->priv->modem_manager, - "object-added", - G_CALLBACK (modem_object_added), - self); + g_signal_connect (self->priv->modem_manager, + "object-added", + G_CALLBACK (modem_object_added), + self); self->priv->mm_object_removed_id = - g_signal_connect (self->priv->modem_manager, - "object-removed", - G_CALLBACK (modem_object_removed), - self); + g_signal_connect (self->priv->modem_manager, + "object-removed", + G_CALLBACK (modem_object_removed), + self); modem_manager_check_name_owner (self); } @@ -339,7 +485,7 @@ manager_new_ready (GObject *source, } static void -ensure_client (NMModemManager *self) +ensure_modem_manager (NMModemManager *self) { g_assert (self->priv->dbus_connection); @@ -359,46 +505,12 @@ ensure_client (NMModemManager *self) modem_manager_check_name_owner (self); } -static void -bus_get_ready (GObject *source, - GAsyncResult *res, - NMModemManager *self) -{ - /* Note we always get an extra reference to self here */ - - GError *error = NULL; - - self->priv->dbus_connection = g_bus_get_finish (res, &error); - if (!self->priv->dbus_connection) { - nm_log_warn (LOGD_CORE, "error getting bus connection: %s", error->message); - g_error_free (error); - /* Setup timeout to relaunch */ - schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); - } else { - /* Got the bus, ensure client */ - ensure_client (self); - } - - /* Balance refcount */ - g_object_unref (self); -} - static gboolean -ensure_bus (NMModemManager *self) +mm_launch_cb (NMModemManager *self) { - /* Clear launch ID */ self->priv->mm_launch_id = 0; - - if (!self->priv->dbus_connection) - g_bus_get (G_BUS_TYPE_SYSTEM, - NULL, - (GAsyncReadyCallback)bus_get_ready, - g_object_ref (self)); - else - /* If bus is already available, ensure client */ - ensure_client (self); - - return FALSE; + ensure_modem_manager (self); + return G_SOURCE_REMOVE; } static void @@ -407,11 +519,31 @@ schedule_modem_manager_relaunch (NMModemManager *self, { /* No need to pass an extra reference to self; timeout/idle will be * cancelled if the object gets disposed. */ - if (n_seconds) - self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)mm_launch_cb, self); else - self->priv->mm_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_idle_add ((GSourceFunc)mm_launch_cb, self); +} + +static void +bus_get_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_object NMModemManager *self = NM_MODEM_MANAGER (user_data); + gs_free_error GError *error = NULL; + + self->priv->dbus_connection = g_bus_get_finish (res, &error); + if (!self->priv->dbus_connection) { + nm_log_warn (LOGD_MB, "error getting bus connection: %s", error->message); + return; + } + + /* Got the bus, ensure clients */ + ensure_modem_manager (self); +#if WITH_OFONO + ensure_ofono_client (self); +#endif } /************************************************************************/ @@ -423,7 +555,11 @@ 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); - schedule_modem_manager_relaunch (self, 0); + // FIXME: this doesn't handle bus-daemon restart + g_bus_get (G_BUS_TYPE_SYSTEM, + NULL, + (GAsyncReadyCallback)bus_get_ready, + g_object_ref (self)); } static void @@ -433,8 +569,16 @@ dispose (GObject *object) nm_clear_g_source (&self->priv->mm_launch_id); - modem_manager_clear_signals (self); - g_clear_object (&self->priv->modem_manager); + clear_modem_manager (self); + +#if WITH_OFONO + if (self->priv->ofono_proxy) { + g_signal_handlers_disconnect_by_func (self->priv->ofono_proxy, ofono_name_owner_changed, self); + g_signal_handlers_disconnect_by_func (self->priv->ofono_proxy, ofono_signal_cb, self); + g_clear_object (&self->priv->ofono_proxy); + } +#endif + g_clear_object (&self->priv->dbus_connection); if (self->priv->modems) { diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c new file mode 100644 index 00000000..86492d3d --- /dev/null +++ b/src/devices/wwan/nm-modem-ofono.c @@ -0,0 +1,1202 @@ +/* -*- 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) 2013 - 2016 Canonical Ltd. + */ + +#include "nm-default.h" + +#include "nm-modem-ofono.h" + +#include <string.h> + +#include "nm-core-internal.h" +#include "nm-device-private.h" +#include "nm-modem.h" +#include "nm-platform.h" + +G_DEFINE_TYPE (NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM) + +#define NM_MODEM_OFONO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OFONO, NMModemOfonoPrivate)) + +#define VARIANT_IS_OF_TYPE_BOOLEAN(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_BOOLEAN) )) +#define VARIANT_IS_OF_TYPE_STRING(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING) )) +#define VARIANT_IS_OF_TYPE_OBJECT_PATH(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_OBJECT_PATH) )) +#define VARIANT_IS_OF_TYPE_STRING_ARRAY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING_ARRAY) )) +#define VARIANT_IS_OF_TYPE_DICTIONARY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_DICTIONARY) )) + +typedef struct { + GHashTable *connect_properties; + + GDBusProxy *modem_proxy; + GDBusProxy *connman_proxy; + GDBusProxy *context_proxy; + GDBusProxy *sim_proxy; + + GError *property_error; + + char *context_path; + char *imsi; + + gboolean modem_online; + gboolean gprs_attached; + + NMIP4Config *ip4_config; +} NMModemOfonoPrivate; + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_MB +#define _NMLOG_PREFIX_NAME "modem-ofono" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ + NMModemOfono *const __self = (self); \ + char __prefix_name[128]; \ + const char *__uid; \ + \ + _nm_log (_level, (_NMLOG_DOMAIN), 0, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self \ + ? ({ \ + ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ + ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + +static gboolean +ip_string_to_network_address (const gchar *str, + guint32 *out) +{ + guint32 addr = 0; + gboolean success = FALSE; + + if (!str || inet_pton (AF_INET, str, &addr) != 1) + addr = 0; + else + success = TRUE; + + *out = (guint32)addr; + return success; +} + +static void +get_capabilities (NMModem *_self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) +{ + /* FIXME: auto-detect capabilities to allow LTE */ + *modem_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; + *current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; +} + +static void +update_modem_state (NMModemOfono *self) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemState state = nm_modem_get_state (NM_MODEM (self)); + NMModemState new_state = NM_MODEM_STATE_DISABLED; + const char *reason = NULL; + + _LOGI ("'Attached': %s 'Online': %s 'IMSI': %s", + priv->gprs_attached ? "true" : "false", + priv->modem_online ? "true" : "false", + priv->imsi); + + if (priv->modem_online == FALSE) { + reason = "modem 'Online=false'"; + } else if (priv->imsi == NULL && state != NM_MODEM_STATE_ENABLING) { + reason = "modem not ready"; + } else if (priv->gprs_attached == FALSE) { + new_state = NM_MODEM_STATE_SEARCHING; + reason = "modem searching"; + } else { + new_state = NM_MODEM_STATE_REGISTERED; + reason = "modem ready"; + } + + if (state != new_state) + nm_modem_set_state (NM_MODEM (self), new_state, reason); +} + +/* Disconnect */ +typedef struct { + NMModemOfono *self; + GSimpleAsyncResult *result; + GCancellable *cancellable; + gboolean warn; +} DisconnectContext; + +static void +disconnect_context_complete (DisconnectContext *ctx) +{ + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (DisconnectContext, ctx); +} + +static gboolean +disconnect_context_complete_if_cancelled (DisconnectContext *ctx) +{ + GError *error = NULL; + + if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + disconnect_context_complete (ctx); + return TRUE; + } + + return FALSE; +} + +static gboolean +disconnect_finish (NMModem *self, + GAsyncResult *result, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); +} + +static void +disconnect_done (GDBusProxy *proxy, + GAsyncResult *result, + gpointer user_data) +{ + DisconnectContext *ctx = (DisconnectContext*) user_data; + NMModemOfono *self = ctx->self; + GError *error = NULL; + + g_dbus_proxy_call_finish (proxy, result, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD ("disconnect cancelled"); + return; + } + + if (error) { + if (ctx->warn) + _LOGW ("failed to disconnect modem: %s", error->message); + g_clear_error (&error); + } + + _LOGD ("modem disconnected"); + + update_modem_state (self); + disconnect_context_complete (ctx); +} + +static void +disconnect (NMModem *modem, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + DisconnectContext *ctx; + NMModemState state = nm_modem_get_state (NM_MODEM (self)); + + _LOGD ("warn: %s modem_state: %s", + warn ? "TRUE" : "FALSE", + nm_modem_state_to_string (state)); + + if (state != NM_MODEM_STATE_CONNECTED) + return; + + ctx = g_slice_new (DisconnectContext); + ctx->self = g_object_ref (self); + ctx->warn = warn; + + if (callback) { + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + disconnect); + } + /* Setup cancellable */ + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + if (disconnect_context_complete_if_cancelled (ctx)) + return; + + nm_modem_set_state (NM_MODEM (self), + NM_MODEM_STATE_DISCONNECTING, + nm_modem_state_to_string (NM_MODEM_STATE_DISCONNECTING)); + + g_dbus_proxy_call (priv->context_proxy, + "SetProperty", + g_variant_new ("(sv)", + "Active", + g_variant_new ("b", warn)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) disconnect_done, + ctx); +} + +static void +deactivate_cleanup (NMModem *_self, NMDevice *device) +{ + NMModemOfono *self = NM_MODEM_OFONO (_self); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + /* TODO: cancel SimpleConnect() if any */ + + g_clear_object (&priv->ip4_config); + + /* Chain up parent's */ + NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (_self, device); +} + + +static gboolean +check_connection_compatible (NMModem *modem, + NMConnection *connection) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMSettingConnection *s_con; + NMSettingGsm *s_gsm; + const char *uuid; + const char *id; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + uuid = nm_connection_get_uuid (connection); + id = nm_connection_get_id (connection); + + s_gsm = nm_connection_get_setting_gsm (connection); + if (!s_gsm) + return FALSE; + + if (!priv->imsi) { + _LOGW ("skipping %s/%s: no IMSI", uuid, id); + return FALSE; + } + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME)) { + _LOGD ("skipping %s/%s: not GSM", uuid, id); + return FALSE; + } + + if (!g_strrstr (id, "/context")) { + _LOGD ("skipping %s/%s: unexpected ID", uuid, id); + return FALSE; + } + + if (!g_strrstr (id, priv->imsi)) { + _LOGD ("skipping %s/%s: ID doesn't contain IMSI", uuid, id); + return FALSE; + } + + _LOGD ("%s/%s compatible with IMSI %s", uuid, id, priv->imsi); + return TRUE; +} + +static void +handle_sim_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (g_strcmp0 (property, "SubscriberIdentity") == 0 && VARIANT_IS_OF_TYPE_STRING (v)) { + gsize length; + const char *value_str = g_variant_get_string (v, &length); + + _LOGD ("SubscriberIdentify found"); + + /* Check for empty DBus string value */ + if (length && + g_strcmp0 (value_str, "(null)") != 0 && + g_strcmp0 (value_str, priv->imsi) != 0) { + + if (priv->imsi != NULL) { + _LOGW ("SimManager:'SubscriberIdentity' changed: %s", priv->imsi); + g_free(priv->imsi); + } + + priv->imsi = g_strdup (value_str); + update_modem_state (self); + } + } +} + +static void +sim_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_sim_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +sim_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting sim properties: %s", error->message); + g_error_free (error); + return; + } + + _LOGD ("sim v_properties is type: %s", g_variant_get_type_string (v_properties)); + + v_dict = g_variant_get_child_value (v_properties, 0); + if (!v_dict) { + _LOGW ("error getting sim properties: no v_dict"); + return; + } + + _LOGD ("sim v_dict is type: %s", g_variant_get_type_string (v_dict)); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_sim_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +static void +handle_sim_iface (NMModemOfono *self, gboolean found) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + _LOGD ("SimManager interface %sfound", found ? "" : "not "); + + if (!found && priv->sim_proxy) { + _LOGI ("SimManager interface disappeared"); + g_signal_handlers_disconnect_by_data (priv->sim_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->sim_proxy); + g_clear_pointer (&priv->imsi, g_free); + update_modem_state (self); + } else if (found && !priv->sim_proxy) { + GError *error = NULL; + + _LOGI ("found new SimManager interface"); + + priv->sim_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_SIM_MANAGER, + NULL, /* GCancellable */ + &error); + if (priv->sim_proxy == NULL) { + _LOGW ("failed to create SimManager proxy: %s", error->message); + g_error_free (error); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->sim_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (sim_property_changed), + self); + + g_dbus_proxy_call (priv->sim_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) sim_get_properties_done, + g_object_ref (self)); + } +} + +static void +handle_connman_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (g_strcmp0 (property, "Attached") == 0 && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { + gboolean attached = g_variant_get_boolean (v); + gboolean old_attached = priv->gprs_attached; + + _LOGD ("Attached: %s", attached ? "True" : "False"); + + if (priv->gprs_attached != attached) { + priv->gprs_attached = attached; + + _LOGI ("Attached %s -> %s", + old_attached ? "true" : "false", + attached ? "true" : "false"); + + update_modem_state (self); + } + } +} + +static void +connman_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_connman_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +connman_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting connman properties: %s", error->message); + g_error_free (error); + return; + } + + v_dict = g_variant_get_child_value (v_properties, 0); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_connman_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +static void +handle_connman_iface (NMModemOfono *self, gboolean found) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + _LOGD ("ConnectionManager interface %sfound", found ? "" : "not "); + + if (!found && priv->connman_proxy) { + _LOGI ("ConnectionManager interface disappeared"); + + g_signal_handlers_disconnect_by_data (priv->connman_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->connman_proxy); + + /* The connection manager proxy disappeared, we should + * consider the modem disabled. + */ + priv->gprs_attached = FALSE; + + update_modem_state (self); + } else if (found && !priv->connman_proxy) { + GError *error = NULL; + + _LOGI ("found new ConnectionManager interface"); + + priv->connman_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, + NULL, /* GCancellable */ + &error); + if (priv->connman_proxy == NULL) { + _LOGW ("failed to create ConnectionManager proxy: %s", error->message); + g_error_free (error); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->connman_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (connman_property_changed), + self); + + g_dbus_proxy_call (priv->connman_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) connman_get_properties_done, + g_object_ref (self)); + } +} + +static void +handle_modem_property (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if ((g_strcmp0 (property, "Online") == 0) && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { + gboolean online = g_variant_get_boolean (v); + + _LOGD ("Online: %s", online ? "True" : "False"); + + if (online != priv->modem_online) { + priv->modem_online = online; + _LOGI ("modem is now %s", online ? "Online" : "Offline"); + update_modem_state (self); + } + + } else if ((g_strcmp0 (property, "Interfaces") == 0) && VARIANT_IS_OF_TYPE_STRING_ARRAY (v)) { + const char **array, **iter; + gboolean found_connman = FALSE; + gboolean found_sim = FALSE; + + _LOGD ("Interfaces found"); + + array = g_variant_get_strv (v, NULL); + if (array) { + for (iter = array; *iter; iter++) { + if (g_strcmp0 (OFONO_DBUS_INTERFACE_SIM_MANAGER, *iter) == 0) + found_sim = TRUE; + else if (g_strcmp0 (OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, *iter) == 0) + found_connman = TRUE; + } + g_free (array); + } + + handle_sim_iface (self, found_sim); + handle_connman_iface (self, found_connman); + } +} + +static void +modem_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + GVariant *v_child = g_variant_get_child_value (v, 0); + + handle_modem_property (proxy, property, v_child, user_data); + g_variant_unref (v_child); +} + +static void +modem_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + GError *error = NULL; + GVariant *v_properties, *v_dict, *v; + GVariantIter i; + const char *property; + + v_properties = _nm_dbus_proxy_call_finish (proxy, + result, + G_VARIANT_TYPE ("(a{sv})"), + &error); + if (!v_properties) { + g_dbus_error_strip_remote_error (error); + _LOGW ("error getting modem properties: %s", error->message); + g_error_free (error); + return; + } + + v_dict = g_variant_get_child_value (v_properties, 0); + if (!v_dict) { + _LOGW ("error getting modem properties: no v_dict"); + return; + } + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init (&i, v_dict); + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { + handle_modem_property (NULL, property, v, self); + g_variant_unref (v); + } + + g_variant_unref (v_dict); + g_variant_unref (v_properties); +} + +NMModem * +nm_modem_ofono_new (const char *path) +{ + gs_free char *basename = NULL; + + g_return_val_if_fail (path != NULL, NULL); + + nm_log_info (LOGD_MB, "ofono: creating new Ofono modem path %s", path); + + /* Use short modem name (not its object path) as the NM device name (which + * comes from NM_MODEM_UID)and the device ID. + */ + basename = g_path_get_basename (path); + + return (NMModem *) g_object_new (NM_TYPE_MODEM_OFONO, + NM_MODEM_PATH, path, + NM_MODEM_UID, basename, + NM_MODEM_DEVICE_ID, basename, + NM_MODEM_CONTROL_PORT, "ofono", /* mandatory */ + NM_MODEM_DRIVER, "ofono", + NM_MODEM_STATE, NM_MODEM_STATE_INITIALIZING, + NULL); +} + +static void +stage1_prepare_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + g_clear_pointer (&priv->connect_properties, g_hash_table_destroy); + + g_dbus_proxy_call_finish (proxy, result, &error); + if (error) { + _LOGW ("connection failed: %s", error->message); + + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_BUSY); + /* + * FIXME: add code to check for InProgress so that the + * connection doesn't continue to try and activate, + * leading to the connection being disabled, and a 5m + * timeout... + */ + + g_clear_error (&error); + } +} + +static void +context_property_changed (GDBusProxy *proxy, + const char *property, + GVariant *v, + gpointer user_data) +{ + NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMPlatformIP4Address addr; + gboolean ret = FALSE; + GVariant *v_dict; + const gchar *s, *addr_s; + const gchar **array, **iter; + guint32 address_network, gateway_network; + guint prefix = 0; + + _LOGD ("PropertyChanged: %s", property); + + /* + * TODO: might be a good idea and re-factor this to mimic bluez-device, + * ie. have this function just check the key, and call a sub-func to + * handle the action. + */ + + if (g_strcmp0 (property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value (v, 0); + if (!v_dict) { + _LOGW ("error getting IPv4 Settings: no v_dict"); + goto out; + } + + _LOGI ("IPv4 static Settings:"); + + if (g_variant_lookup (v_dict, "Interface", "&s", &s)) { + if (s && strlen (s)) { + _LOGD ("Interface: %s", s); + g_object_set (self, + NM_MODEM_DATA_PORT, g_strdup (s), + NM_MODEM_IP4_METHOD, NM_MODEM_IP_METHOD_STATIC, + NULL); + } else { + _LOGW ("Settings 'Interface'; empty"); + goto out; + } + + } else { + _LOGW ("Settings 'Interface' missing"); + goto out; + } + + /* TODO: verify handling of ip4_config; check other places it's used... */ + g_clear_object (&priv->ip4_config); + + memset (&addr, 0, sizeof (addr)); + + /* + * TODO: + * + * NM 1.2 changed the NMIP4Config constructor to take an ifindex + * ( vs. void pre 1.2 ), to tie config instance to a specific + * platform interface. + * + * This doesn't work for ofono, as the devices are created + * dynamically ( eg. ril_0, ril_1 ) in NMModemManager. The + * device created doesn't really map directly to a platform + * link. The closest would be one of the devices owned by + * rild ( eg. ccmin0 ), which is passed to us above as + * 'Interface'. + * + * This needs discussion with upstream. + */ + priv->ip4_config = nm_ip4_config_new (0); + + /* TODO: simply if/else error logic! */ + + if (g_variant_lookup (v_dict, "Address", "&s", &addr_s)) { + _LOGD ("Address: %s", addr_s); + + if (ip_string_to_network_address (addr_s, &address_network)) { + addr.address = address_network; + addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN; + } else { + _LOGW ("can't convert 'Address' %s to addr", s); + goto out; + } + + } else { + _LOGW ("Settings 'Address' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "Netmask", "&s", &s)) { + _LOGD ("Netmask: %s", s); + + if (s && ip_string_to_network_address (s, &address_network)) { + prefix = nm_utils_ip4_netmask_to_prefix (address_network); + if (prefix > 0) + addr.plen = prefix; + } else { + _LOGW ("invalid 'Netmask': %s", s); + goto out; + } + } else { + _LOGW ("Settings 'Netmask' missing"); + goto out; + } + + _LOGI ("Address: %s/%d", addr_s, prefix); + + nm_ip4_config_add_address (priv->ip4_config, &addr); + + if (g_variant_lookup (v_dict, "Gateway", "&s", &s)) { + if (s && ip_string_to_network_address (s, &gateway_network)) { + _LOGI ("Gateway: %s", s); + nm_ip4_config_set_gateway (priv->ip4_config, gateway_network); + } else { + _LOGW ("invalid 'Gateway': %s", s); + goto out; + } + nm_ip4_config_set_gateway (priv->ip4_config, gateway_network); + } else { + _LOGW ("Settings 'Gateway' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "DomainNameServers", "^a&s", &array)) { + if (array) { + for (iter = array; *iter; iter++) { + if (ip_string_to_network_address (*iter, &address_network) && address_network > 0) { + _LOGI ("DNS: %s", *iter); + nm_ip4_config_add_nameserver (priv->ip4_config, address_network); + } else { + _LOGW ("invalid NameServer: %s", *iter); + } + } + + if (iter == array) { + _LOGW ("Settings: 'DomainNameServers': none specified"); + g_free (array); + goto out; + } + g_free (array); + } + } else { + _LOGW ("Settings 'DomainNameServers' missing"); + goto out; + } + + if (g_variant_lookup (v_dict, "MessageProxy", "&s", &s)) { + _LOGI ("MessageProxy: %s", s); + if (s && ip_string_to_network_address (s, &address_network)) { + NMPlatformIP4Route mms_route; + + mms_route.network = address_network; + mms_route.plen = 32; + mms_route.gateway = gateway_network; + + mms_route.metric = 1; + + nm_ip4_config_add_route (priv->ip4_config, &mms_route); + } else { + _LOGW ("invalid MessageProxy: %s", s); + } + } + + ret = TRUE; + +out: + if (nm_modem_get_state (NM_MODEM (self)) != NM_MODEM_STATE_CONNECTED) { + _LOGI ("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE"); + if (!ret) + reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, ret, reason); + } else { + _LOGW ("MODEM_PPP_FAILED"); + g_signal_emit_by_name (self, NM_MODEM_PPP_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); + } +} + +static NMActStageReturn +static_stage3_ip4_config_start (NMModem *_self, + NMActRequest *req, + NMDeviceStateReason *reason) +{ + NMModemOfono *self = NM_MODEM_OFONO (_self); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + GError *error = NULL; + + if (priv->ip4_config) { + _LOGD ("IP4 config is done; setting modem_state -> CONNECTED"); + g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error); + + /* Signal listener takes ownership of the IP4Config */ + priv->ip4_config = NULL; + + nm_modem_set_state (NM_MODEM (self), + NM_MODEM_STATE_CONNECTED, + nm_modem_state_to_string (NM_MODEM_STATE_CONNECTED)); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } + + return ret; +} + +static void +context_proxy_new_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + priv->context_proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (error) { + _LOGE ("failed to create ofono ConnectionContext DBus proxy: %s", error->message); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_BUSY); + return; + } + + if (!priv->gprs_attached) { + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return; + } + + /* We have an old copy of the settings from a previous activation, + * clear it so that we can gate getting the IP config from oFono + * on whether or not we have already received them + */ + g_clear_object (&priv->ip4_config); + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (context_property_changed), + self); + + g_dbus_proxy_call (priv->context_proxy, + "SetProperty", + g_variant_new ("(sv)", + "Active", + g_variant_new ("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) stage1_prepare_done, + g_object_ref (self)); +} + +static void +do_context_activate (NMModemOfono *self) +{ + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_MODEM_OFONO (self)); + + g_clear_object (&priv->context_proxy); + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + priv->context_path, + OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT, + NULL, + (GAsyncReadyCallback) context_proxy_new_cb, + g_object_ref (self)); +} + +static GHashTable * +create_connect_properties (NMConnection *connection) +{ + NMSettingGsm *setting; + GHashTable *properties; + const char *str; + + setting = nm_connection_get_setting_gsm (connection); + properties = g_hash_table_new (g_str_hash, g_str_equal); + + str = nm_setting_gsm_get_apn (setting); + if (str) + g_hash_table_insert (properties, "AccessPointName", g_strdup (str)); + + str = nm_setting_gsm_get_username (setting); + if (str) + g_hash_table_insert (properties, "Username", g_strdup (str)); + + str = nm_setting_gsm_get_password (setting); + if (str) + g_hash_table_insert (properties, "Password", g_strdup (str)); + + return properties; +} + +static NMActStageReturn +act_stage1_prepare (NMModem *modem, + NMConnection *connection, + NMDeviceStateReason *reason) +{ + NMModemOfono *self = NM_MODEM_OFONO (modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + const char *context_id; + char **id = NULL; + + context_id = nm_connection_get_id (connection); + id = g_strsplit (context_id, "/", 0); + g_assert (id[2]); + + _LOGD ("trying %s %s", id[1], id[2]); + + g_free (priv->context_path); + priv->context_path = g_strdup_printf ("%s/%s", + nm_modem_get_path (modem), + id[2]); + g_strfreev (id); + + if (!priv->context_path) { + *reason = NM_DEVICE_STATE_REASON_GSM_APN_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (priv->connect_properties) + g_hash_table_destroy (priv->connect_properties); + + priv->connect_properties = create_connect_properties (connection); + + _LOGI ("activating context %s", priv->context_path); + + if (nm_modem_get_state (modem) == NM_MODEM_STATE_REGISTERED) { + do_context_activate (self); + } else { + _LOGW ("could not activate context: modem is not registered."); + *reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +static void +modem_proxy_new_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + GError *error = NULL; + + priv->modem_proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (error) { + _LOGE ("failed to create ofono modem DBus proxy: %s", error->message); + return; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect (priv->modem_proxy, + "PropertyChanged", + G_VARIANT_TYPE ("(sv)"), + G_CALLBACK (modem_property_changed), + self); + + g_dbus_proxy_call (priv->modem_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) modem_get_properties_done, + g_object_ref (self)); +} + +static void +nm_modem_ofono_init (NMModemOfono *self) +{ +} + +static void +constructed (GObject *object) +{ + NMModemOfono *self = NM_MODEM_OFONO (object); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + nm_modem_get_path (NM_MODEM (self)), + OFONO_DBUS_INTERFACE_MODEM, + NULL, + (GAsyncReadyCallback) modem_proxy_new_cb, + g_object_ref (self)); +} + +static void +dispose (GObject *object) +{ + NMModemOfono *self = NM_MODEM_OFONO (object); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + + if (priv->connect_properties) { + g_hash_table_destroy (priv->connect_properties); + priv->connect_properties = NULL; + } + + g_clear_object (&priv->ip4_config); + + if (priv->modem_proxy) { + g_signal_handlers_disconnect_by_data (priv->modem_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->modem_proxy); + } + + g_clear_object (&priv->connman_proxy); + g_clear_object (&priv->context_proxy); + + if (priv->sim_proxy) { + g_signal_handlers_disconnect_by_data (priv->sim_proxy, NM_MODEM_OFONO (self)); + g_clear_object (&priv->sim_proxy); + } + + g_free (priv->imsi); + priv->imsi = NULL; + + G_OBJECT_CLASS (nm_modem_ofono_parent_class)->dispose (object); +} + +static void +nm_modem_ofono_class_init (NMModemOfonoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMModemClass *modem_class = NM_MODEM_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMModemOfonoPrivate)); + + /* Virtual methods */ + object_class->constructed = constructed; + object_class->dispose = dispose; + + modem_class->get_capabilities = get_capabilities; + modem_class->disconnect = disconnect; + modem_class->disconnect_finish = disconnect_finish; + modem_class->deactivate_cleanup = deactivate_cleanup; + modem_class->check_connection_compatible = check_connection_compatible; + + /* same as nm-modem-broadband */ + modem_class->act_stage1_prepare = act_stage1_prepare; + + /* same as nm-modem-broadband */ + modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; +} diff --git a/src/devices/wwan/nm-modem-ofono.h b/src/devices/wwan/nm-modem-ofono.h new file mode 100644 index 00000000..5965526d --- /dev/null +++ b/src/devices/wwan/nm-modem-ofono.h @@ -0,0 +1,53 @@ +/* -*- 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) 2013 - Canonical Ltd. + */ + +#ifndef NM_MODEM_OFONO_H +#define NM_MODEM_OFONO_H + +#include "nm-modem.h" + +#define NM_TYPE_MODEM_OFONO (nm_modem_ofono_get_type ()) +#define NM_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OFONO, NMModemOfono)) +#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) +#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) + +#define OFONO_DBUS_SERVICE "org.ofono" +#define OFONO_DBUS_PATH "/" +#define OFONO_DBUS_INTERFACE "org.ofono.Manager" +#define OFONO_DBUS_INTERFACE_MODEM "org.ofono.Modem" +#define OFONO_DBUS_INTERFACE_CONNECTION_MANAGER "org.ofono.ConnectionManager" +#define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" +#define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" + +typedef struct { + NMModem parent; +} NMModemOfono; + +typedef struct { + NMModemClass parent; +} NMModemOfonoClass; + +GType nm_modem_ofono_get_type (void); + +NMModem *nm_modem_ofono_new (const char *path); + +#endif /* NM_MODEM_OFONO_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index a6c77007..2e3d63bb 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -202,7 +202,9 @@ nm_modem_set_mm_enabled (NMModem *self, return; } - NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); + /* Not all modem classes support set_mm_enabled */ + if (NM_MODEM_GET_CLASS (self)->set_mm_enabled) + NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); /* Pre-empt the state change signal */ nm_modem_set_state (self, @@ -573,6 +575,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, const char *method; NMActStageReturn ret; + nm_log_dbg (LOGD_MB, "ip4_config_start"); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_DEVICE (device), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_DEVICE_CLASS (device_class), NM_ACT_STAGE_RETURN_FAILURE); @@ -602,9 +606,11 @@ nm_modem_stage3_ip4_config_start (NMModem *self, ret = ppp_stage3_ip_config_start (self, req, reason); break; case NM_MODEM_IP_METHOD_STATIC: + nm_log_dbg (LOGD_MB, "MODEM_IP_METHOD_STATIC"); ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; case NM_MODEM_IP_METHOD_AUTO: + nm_log_dbg (LOGD_MB, "MODEM_IP_METHOD_AUTO"); ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index 60e5589b..8f797d44 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -22,12 +22,9 @@ #ifndef __NETWORKMANAGER_MODEM_H__ #define __NETWORKMANAGER_MODEM_H__ -#include "nm-default.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-device.h" -G_BEGIN_DECLS - #define NM_TYPE_MODEM (nm_modem_get_type ()) #define NM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM, NMModem)) #define NM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM, NMModemClass)) @@ -268,6 +265,4 @@ void nm_modem_emit_ip6_config_result (NMModem *self, const gchar *nm_modem_ip_type_to_string (NMModemIPType ip_type); -G_END_DECLS - #endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index 805aea69..507935fc 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -90,7 +90,7 @@ modem_added_cb (NMModemManager *manager, NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WWAN_ETHERNET) + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WWAN_NET) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME) ) @@ -102,7 +102,7 @@ create_device (NMDeviceFactory *factory, gboolean *out_ignore) { g_return_val_if_fail (plink, NULL); - g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_ETHERNET, NULL); + g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_NET, NULL); *out_ignore = TRUE; return NULL; } diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h index 78031e60..61bdcb1e 100644 --- a/src/devices/wwan/nm-wwan-factory.h +++ b/src/devices/wwan/nm-wwan-factory.h @@ -21,8 +21,6 @@ #ifndef __NETWORKMANAGER_WWAN_FACTORY_H__ #define __NETWORKMANAGER_WWAN_FACTORY_H__ -#include "nm-default.h" - #define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type ()) #define NM_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory)) |