diff options
| author | Michael Biebl <biebl@debian.org> | 2013-02-03 14:49:22 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2013-02-03 14:49:22 +0100 |
| commit | 9c202e3e860b3be9e1f8882630b69affbb130102 (patch) | |
| tree | 8202bf39f2129486971fa7d5ae0dee61a561aa53 /src/modem-manager | |
| parent | 36cb2f364a821e1be50b23e03a18891ec55adb06 (diff) | |
Imported Upstream version 0.9.7.995 upstream/0.9.7.995
Diffstat (limited to 'src/modem-manager')
| -rw-r--r-- | src/modem-manager/Makefile.am | 10 | ||||
| -rw-r--r-- | src/modem-manager/Makefile.in | 146 | ||||
| -rw-r--r-- | src/modem-manager/README | 45 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-broadband.c | 1033 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-broadband.h | 69 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-cdma.c | 77 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-cdma.h | 21 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-generic.c | 445 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-generic.h | 69 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-gsm.c | 99 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-gsm.h | 23 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-manager.c | 451 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-manager.h | 13 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem-types.h | 39 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem.c | 629 | ||||
| -rw-r--r-- | src/modem-manager/nm-modem.h | 59 |
16 files changed, 2529 insertions, 699 deletions
diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am index b9cc7644..aa5534fc 100644 --- a/src/modem-manager/Makefile.am +++ b/src/modem-manager/Makefile.am @@ -15,6 +15,8 @@ noinst_LTLIBRARIES = libmodem-manager.la libmodem_manager_la_SOURCES = \ nm-modem.c \ nm-modem.h \ + nm-modem-generic.c \ + nm-modem-generic.h \ nm-modem-cdma.c \ nm-modem-cdma.h \ nm-modem-gsm.c \ @@ -33,3 +35,11 @@ libmodem_manager_la_LIBADD = \ $(LIBNL_LIBS) \ $(DBUS_LIBS) +# Support for the new ModemManager1 interface +if WITH_MODEM_MANAGER_1 +libmodem_manager_la_SOURCES += \ + nm-modem-broadband.h \ + nm-modem-broadband.c +libmodem_manager_la_CPPFLAGS += $(MM_GLIB_CFLAGS) +libmodem_manager_la_LIBADD += $(MM_GLIB_LIBS) +endif diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in index 6da50ed0..0546ee2e 100644 --- a/src/modem-manager/Makefile.in +++ b/src/modem-manager/Makefile.in @@ -51,20 +51,30 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ + +# Support for the new ModemManager1 interface +@WITH_MODEM_MANAGER_1_TRUE@am__append_1 = \ +@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.h \ +@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.c + +@WITH_MODEM_MANAGER_1_TRUE@am__append_2 = $(MM_GLIB_CFLAGS) +@WITH_MODEM_MANAGER_1_TRUE@am__append_3 = $(MM_GLIB_LIBS) subdir = src/modem-manager -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/vapigen.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -73,14 +83,23 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = +@WITH_MODEM_MANAGER_1_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libmodem_manager_la_DEPENDENCIES = \ $(top_builddir)/src/generated/libnm-generated.la \ $(top_builddir)/src/logging/libnm-logging.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am__libmodem_manager_la_SOURCES_DIST = nm-modem.c nm-modem.h \ + nm-modem-generic.c nm-modem-generic.h nm-modem-cdma.c \ + nm-modem-cdma.h nm-modem-gsm.c nm-modem-gsm.h \ + nm-modem-manager.h nm-modem-manager.c nm-modem-types.h \ + nm-modem-broadband.h nm-modem-broadband.c +@WITH_MODEM_MANAGER_1_TRUE@am__objects_1 = libmodem_manager_la-nm-modem-broadband.lo am_libmodem_manager_la_OBJECTS = libmodem_manager_la-nm-modem.lo \ + libmodem_manager_la-nm-modem-generic.lo \ libmodem_manager_la-nm-modem-cdma.lo \ libmodem_manager_la-nm-modem-gsm.lo \ - libmodem_manager_la-nm-modem-manager.lo + libmodem_manager_la-nm-modem-manager.lo $(am__objects_1) libmodem_manager_la_OBJECTS = $(am_libmodem_manager_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -112,7 +131,7 @@ AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libmodem_manager_la_SOURCES) -DIST_SOURCES = $(libmodem_manager_la_SOURCES) +DIST_SOURCES = $(am__libmodem_manager_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -133,6 +152,10 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ @@ -147,9 +170,7 @@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ -DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ @@ -159,17 +180,14 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GENHTML = @GENHTML@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GIO_CFLAGS = @GIO_CFLAGS@ -GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MAKEFILE = @GLIB_MAKEFILE@ GLIB_MKENUMS = @GLIB_MKENUMS@ -GMODULE_CFLAGS = @GMODULE_CFLAGS@ -GMODULE_LIBS = @GMODULE_LIBS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ @@ -210,6 +228,7 @@ IPTABLES_PATH = @IPTABLES_PATH@ IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBDL = @LIBDL@ @@ -226,11 +245,7 @@ LIBNL2_LIBS = @LIBNL2_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@ -LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@ LIBNL_LIBS = @LIBNL_LIBS@ -LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@ -LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ @@ -245,6 +260,8 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ @@ -254,6 +271,7 @@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ NM_VERSION = @NM_VERSION@ NSS_CFLAGS = @NSS_CFLAGS@ NSS_LIBS = @NSS_LIBS@ @@ -280,13 +298,14 @@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ -RESOLVCONF_PATH = @RESOLVCONF_PATH@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ -SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ -SYSTEMD_LIBS = @SYSTEMD_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +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@ USE_NLS = @USE_NLS@ @@ -341,6 +360,11 @@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -355,6 +379,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ INCLUDES = \ -I${top_srcdir}/src \ -I${top_builddir}/src/generated \ @@ -366,27 +394,16 @@ INCLUDES = \ -I${top_srcdir}/libnm-util noinst_LTLIBRARIES = libmodem-manager.la -libmodem_manager_la_SOURCES = \ - nm-modem.c \ - nm-modem.h \ - nm-modem-cdma.c \ - nm-modem-cdma.h \ - nm-modem-gsm.c \ - nm-modem-gsm.h \ - nm-modem-manager.h \ - nm-modem-manager.c \ - nm-modem-types.h - -libmodem_manager_la_CPPFLAGS = \ - $(LIBNL_CFLAGS) \ - $(DBUS_CFLAGS) - -libmodem_manager_la_LIBADD = \ +libmodem_manager_la_SOURCES = nm-modem.c nm-modem.h nm-modem-generic.c \ + nm-modem-generic.h nm-modem-cdma.c nm-modem-cdma.h \ + nm-modem-gsm.c nm-modem-gsm.h nm-modem-manager.h \ + nm-modem-manager.c nm-modem-types.h $(am__append_1) +libmodem_manager_la_CPPFLAGS = $(LIBNL_CFLAGS) $(DBUS_CFLAGS) \ + $(am__append_2) +libmodem_manager_la_LIBADD = \ $(top_builddir)/src/generated/libnm-generated.la \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(LIBNL_LIBS) \ - $(DBUS_LIBS) - + $(top_builddir)/src/logging/libnm-logging.la $(LIBNL_LIBS) \ + $(DBUS_LIBS) $(am__append_3) all: all-am .SUFFIXES: @@ -439,31 +456,30 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem-broadband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem-cdma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem-generic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem-gsm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmodem_manager_la-nm-modem.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @@ -475,6 +491,13 @@ libmodem_manager_la-nm-modem.lo: nm-modem.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmodem_manager_la-nm-modem.lo `test -f 'nm-modem.c' || echo '$(srcdir)/'`nm-modem.c +libmodem_manager_la-nm-modem-generic.lo: nm-modem-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmodem_manager_la-nm-modem-generic.lo -MD -MP -MF $(DEPDIR)/libmodem_manager_la-nm-modem-generic.Tpo -c -o libmodem_manager_la-nm-modem-generic.lo `test -f 'nm-modem-generic.c' || echo '$(srcdir)/'`nm-modem-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmodem_manager_la-nm-modem-generic.Tpo $(DEPDIR)/libmodem_manager_la-nm-modem-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-modem-generic.c' object='libmodem_manager_la-nm-modem-generic.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmodem_manager_la-nm-modem-generic.lo `test -f 'nm-modem-generic.c' || echo '$(srcdir)/'`nm-modem-generic.c + libmodem_manager_la-nm-modem-cdma.lo: nm-modem-cdma.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmodem_manager_la-nm-modem-cdma.lo -MD -MP -MF $(DEPDIR)/libmodem_manager_la-nm-modem-cdma.Tpo -c -o libmodem_manager_la-nm-modem-cdma.lo `test -f 'nm-modem-cdma.c' || echo '$(srcdir)/'`nm-modem-cdma.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmodem_manager_la-nm-modem-cdma.Tpo $(DEPDIR)/libmodem_manager_la-nm-modem-cdma.Plo @@ -496,6 +519,13 @@ libmodem_manager_la-nm-modem-manager.lo: nm-modem-manager.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmodem_manager_la-nm-modem-manager.lo `test -f 'nm-modem-manager.c' || echo '$(srcdir)/'`nm-modem-manager.c +libmodem_manager_la-nm-modem-broadband.lo: nm-modem-broadband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmodem_manager_la-nm-modem-broadband.lo -MD -MP -MF $(DEPDIR)/libmodem_manager_la-nm-modem-broadband.Tpo -c -o libmodem_manager_la-nm-modem-broadband.lo `test -f 'nm-modem-broadband.c' || echo '$(srcdir)/'`nm-modem-broadband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmodem_manager_la-nm-modem-broadband.Tpo $(DEPDIR)/libmodem_manager_la-nm-modem-broadband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-modem-broadband.c' object='libmodem_manager_la-nm-modem-broadband.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmodem_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmodem_manager_la-nm-modem-broadband.lo `test -f 'nm-modem-broadband.c' || echo '$(srcdir)/'`nm-modem-broadband.c + mostlyclean-libtool: -rm -f *.lo diff --git a/src/modem-manager/README b/src/modem-manager/README new file mode 100644 index 00000000..c9f0f5f1 --- /dev/null +++ b/src/modem-manager/README @@ -0,0 +1,45 @@ + +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 inteface 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-types.h: + Defines helper types to use with the (old) ModemManager DBus API. + + * nm-modem-generic.[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/modem-manager/nm-modem-broadband.c b/src/modem-manager/nm-modem-broadband.c new file mode 100644 index 00000000..05cd3565 --- /dev/null +++ b/src/modem-manager/nm-modem-broadband.c @@ -0,0 +1,1033 @@ +/* -*- 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) 2012 Aleksander Morgado <aleksander@gnu.org> + */ + +#include <glib/gi18n.h> +#include <string.h> +#include <libmm-glib.h> +#include "nm-modem-broadband.h" +#include "nm-system.h" +#include "nm-setting-connection.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" + +G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) + +struct _NMModemBroadbandPrivate { + /* The modem object from dbus */ + MMObject *modem_object; + /* Per-interface objects */ + MMModem *modem_iface; + MMModemSimple *simple_iface; + + /* Connection setup */ + MMSimpleConnectProperties *connect_properties; + MMBearer *bearer; + MMBearerIpConfig *ipv4_config; + MMBearerIpConfig *ipv6_config; + + guint32 pin_tries; +}; + +enum { + PROP_0, + PROP_MODEM, +}; + +#define MODEM_CAPS_3GPP(caps) (caps & (MM_MODEM_CAPABILITY_GSM_UMTS | \ + MM_MODEM_CAPABILITY_LTE | \ + MM_MODEM_CAPABILITY_LTE_ADVANCED)) + +#define MODEM_CAPS_3GPP2(caps) (caps & (MM_MODEM_CAPABILITY_CDMA_EVDO)) + +/*****************************************************************************/ + +#define NM_MODEM_BROADBAND_ERROR (nm_modem_broadband_error_quark ()) + +static GQuark +nm_modem_broadband_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-modem-broadband-error"); + return quark; +} + +static NMDeviceStateReason +translate_mm_error (GError *error) +{ + NMDeviceStateReason reason; + + if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_CARRIER)) + reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; + else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_DIALTONE)) + reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; + else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_BUSY)) + reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; + else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_ANSWER)) + reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; + else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; + else { + /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ + nm_log_dbg (LOGD_MB, "unmapped error detected: '%s'", error->message); + reason = NM_DEVICE_STATE_REASON_UNKNOWN; + } + + return reason; +} + +/*****************************************************************************/ + +void +nm_modem_broadband_get_capabilities (NMModemBroadband *self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) +{ + *modem_caps = (NMDeviceModemCapabilities)mm_modem_get_modem_capabilities (self->priv->modem_iface); + *current_caps = (NMDeviceModemCapabilities)mm_modem_get_current_capabilities (self->priv->modem_iface); +} + +/*****************************************************************************/ + +static void +ask_for_pin (NMModemBroadband *self) +{ + guint32 tries; + + tries = self->priv->pin_tries++; + nm_modem_get_secrets (NM_MODEM (self), + NM_SETTING_GSM_SETTING_NAME, + tries ? TRUE : FALSE, + NM_SETTING_GSM_PIN); +} + +static void +connect_ready (MMModemSimple *simple_iface, + GAsyncResult *res, + NMModemBroadband *self) +{ + GError *error = NULL; + guint ip_method; + + g_clear_object (&self->priv->connect_properties); + + self->priv->bearer = mm_modem_simple_connect_finish (simple_iface, res, &error); + if (!self->priv->bearer) { + if (g_error_matches (error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || + (g_error_matches (error, + MM_CORE_ERROR, + MM_CORE_ERROR_UNAUTHORIZED) && + mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { + /* Request PIN */ + ask_for_pin (self); + } else { + /* Strip remote error info before logging it */ + if (g_dbus_error_is_remote_error (error)) + g_dbus_error_strip_remote_error (error); + + nm_log_warn (LOGD_MB, "(%s) failed to connect modem: %s", + nm_modem_get_uid (NM_MODEM (self)), + error && error->message ? error->message : "(unknown)"); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + } + + g_clear_error (&error); + g_object_unref (self); + return; + } + + /* 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); + + 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_BROADBAND_ERROR, + NM_MODEM_BROADBAND_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)); + 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_IP_TIMEOUT, mm_bearer_get_ip_timeout (self->priv->bearer), + NULL); + + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); + g_object_unref (self); +} + +static MMSimpleConnectProperties * +create_cdma_connect_properties (NMConnection *connection) +{ + NMSettingCdma *setting; + MMSimpleConnectProperties *properties; + const gchar *str; + + setting = nm_connection_get_setting_cdma (connection); + properties = mm_simple_connect_properties_new (); + + str = nm_setting_cdma_get_number (setting); + if (str) + mm_simple_connect_properties_set_number (properties, str); + + return properties; +} + +static MMSimpleConnectProperties * +create_gsm_connect_properties (NMConnection *connection) +{ + NMSettingGsm *setting; + NMSettingPPP *s_ppp; + MMSimpleConnectProperties *properties; + const gchar *str; + + setting = nm_connection_get_setting_gsm (connection); + properties = mm_simple_connect_properties_new (); + + /* TODO: not needed */ + str = nm_setting_gsm_get_number (setting); + if (str) + mm_simple_connect_properties_set_number (properties, str); + + str = nm_setting_gsm_get_apn (setting); + if (str) + mm_simple_connect_properties_set_apn (properties, str); + + str = nm_setting_gsm_get_network_id (setting); + if (str) + mm_simple_connect_properties_set_operator_id (properties, str); + + str = nm_setting_gsm_get_pin (setting); + if (str) + mm_simple_connect_properties_set_pin (properties, str); + + str = nm_setting_gsm_get_username (setting); + if (str) + mm_simple_connect_properties_set_user (properties, str); + + str = nm_setting_gsm_get_password (setting); + if (str) + mm_simple_connect_properties_set_password (properties, str); + + /* TODO: We should check SUPPORTED MODES here */ + switch (nm_setting_gsm_get_network_type (setting)) { + case NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_3G, + MM_MODEM_MODE_NONE); + break; + case NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_2G, + MM_MODEM_MODE_NONE); + break; + case NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_ANY, + MM_MODEM_MODE_3G); + break; + case NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_ANY, + MM_MODEM_MODE_2G); + break; + case NM_SETTING_GSM_NETWORK_TYPE_PREFER_4G: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_ANY, + MM_MODEM_MODE_4G); + break; + case NM_SETTING_GSM_NETWORK_TYPE_4G: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_4G, + MM_MODEM_MODE_NONE); + break; + default: + mm_simple_connect_properties_set_allowed_modes (properties, + MM_MODEM_MODE_ANY, + MM_MODEM_MODE_NONE); + break; + } + + /* Roaming */ + if (nm_setting_gsm_get_home_only (setting)) + mm_simple_connect_properties_set_allow_roaming (properties, FALSE); + + /* For IpMethod == STATIC or DHCP */ + s_ppp = nm_connection_get_setting_ppp (connection); + if (s_ppp) { + MMBearerAllowedAuth allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN; + + if (nm_setting_ppp_get_noauth (s_ppp)) + allowed_auth = MM_BEARER_ALLOWED_AUTH_NONE; + if (!nm_setting_ppp_get_refuse_pap (s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_PAP; + if (!nm_setting_ppp_get_refuse_chap (s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_CHAP; + if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAP; + if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAPV2; + if (!nm_setting_ppp_get_refuse_eap (s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_EAP; + + mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); + } + + return properties; +} + +static NMActStageReturn +act_stage1_prepare (NMModem *_self, + NMActRequest *req, + GPtrArray **out_hints, + const char **out_setting_name, + NMDeviceStateReason *reason) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + NMConnection *connection; + + connection = nm_act_request_get_connection (req); + g_assert (connection); + + *out_setting_name = nm_connection_need_secrets (connection, out_hints); + if (!*out_setting_name) { + MMModemCapability caps; + + caps = mm_modem_get_current_capabilities (self->priv->modem_iface); + + g_clear_object (&self->priv->connect_properties); + + if (MODEM_CAPS_3GPP (caps)) + self->priv->connect_properties = create_gsm_connect_properties (connection); + else if (MODEM_CAPS_3GPP2 (caps)) + self->priv->connect_properties = create_cdma_connect_properties (connection); + else { + nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem", + nm_modem_get_uid (NM_MODEM (self))); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (!self->priv->simple_iface) + self->priv->simple_iface = mm_object_get_modem_simple (self->priv->modem_object); + + mm_modem_simple_connect (self->priv->simple_iface, + self->priv->connect_properties, + NULL, + (GAsyncReadyCallback)connect_ready, + g_object_ref (self)); + } else { + /* NMModem will handle requesting secrets... */ + } + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +/*****************************************************************************/ + +static NMConnection * +get_best_auto_connection (NMModem *_self, + GSList *connections, + char **specific_object) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + MMModemCapability modem_caps; + GSList *iter; + + modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (!nm_setting_connection_get_autoconnect (s_con)) + continue; + + /* If GSM settings given and our modem is 3GPP, those are the best ones */ + if ( g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_GSM_SETTING_NAME) + && MODEM_CAPS_3GPP (modem_caps)) + return connection; + + /* If CDMA settings given and our modem is 3GPP2, return those */ + if ( g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_CDMA_SETTING_NAME) + && MODEM_CAPS_3GPP2 (modem_caps)) + return connection; + + /* continue */ + } + + return NULL; +} + +/*****************************************************************************/ + +static gboolean +check_connection_compatible (NMModem *_self, + NMConnection *connection, + GError **error) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + MMModemCapability modem_caps; + NMSettingConnection *s_con; + + modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (MODEM_CAPS_3GPP (modem_caps)) { + NMSettingGsm *s_gsm; + + if (!g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_GSM_SETTING_NAME)) { + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_NOT_GSM, + "The connection was not a 3GPP connection."); + return FALSE; + } + + s_gsm = nm_connection_get_setting_gsm (connection); + if (!s_gsm) { + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_INVALID, + "The connection was not a valid 3GPP connection."); + return FALSE; + } + + return TRUE; + } + + if (MODEM_CAPS_3GPP2 (modem_caps)) { + NMSettingCdma *s_cdma; + + if (!g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_CDMA_SETTING_NAME)) { + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_NOT_CDMA, + "The connection was not a 3GPP2 connection."); + return FALSE; + } + + s_cdma = nm_connection_get_setting_cdma (connection); + if (!s_cdma) { + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_INVALID, + "The connection was not a valid 3GPP2 connection."); + return FALSE; + } + + return TRUE; + } + + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_INCOMPATIBLE, + "Device is not a mobile broadband modem"); + return FALSE; +} + +/*****************************************************************************/ + +static gboolean +complete_connection (NMModem *_self, + NMConnection *connection, + const GSList *existing_connections, + GError **error) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + MMModemCapability modem_caps; + 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 (); + 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)); + } + + if (MODEM_CAPS_3GPP (modem_caps)) { + 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; + } + + /* TODO: This is not needed */ + if (!nm_setting_gsm_get_number (s_gsm)) + g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); + + nm_utils_complete_generic (connection, + NM_SETTING_GSM_SETTING_NAME, + existing_connections, + _("GSM connection %d"), + NULL, + FALSE); /* No IPv6 yet by default */ + + return TRUE; + } + + if (MODEM_CAPS_3GPP2 (modem_caps)) { + 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); + + nm_utils_complete_generic (connection, + NM_SETTING_CDMA_SETTING_NAME, + existing_connections, + _("CDMA connection %d"), + NULL, + FALSE); /* No IPv6 yet by default */ + + return TRUE; + } + + g_set_error (error, + NM_MODEM_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_INCOMPATIBLE, + "Device is not a mobile broadband modem"); + return FALSE; +} + +/*****************************************************************************/ + +static gboolean +get_user_pass (NMModem *modem, + NMConnection *connection, + const char **user, + const char **pass) +{ + NMSettingGsm *s_gsm; + NMSettingCdma *s_cdma; + + s_gsm = nm_connection_get_setting_gsm (connection); + s_cdma = nm_connection_get_setting_cdma (connection); + if (!s_gsm && !s_cdma) + return FALSE; + + if (user) { + if (s_gsm) + *user = nm_setting_gsm_get_username (s_gsm); + else if (s_cdma) + *user = nm_setting_cdma_get_username (s_cdma); + } + if (pass) { + if (s_gsm) + *pass = nm_setting_gsm_get_password (s_gsm); + else if (s_cdma) + *pass = nm_setting_cdma_get_password (s_cdma); + } + + return TRUE; +} + +/*****************************************************************************/ + +static const char * +get_setting_name (NMModem *_self) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + MMModemCapability modem_caps; + + modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); + if (MODEM_CAPS_3GPP (modem_caps)) + return NM_SETTING_GSM_SETTING_NAME; + + if (MODEM_CAPS_3GPP2 (modem_caps)) + return NM_SETTING_CDMA_SETTING_NAME; + + return "unknown"; +} + +/*****************************************************************************/ +/* Query/Update enabled state */ + +static void +update_mm_enabled (NMModem *self, + gboolean new_enabled) +{ + if (nm_modem_get_mm_enabled (self) != new_enabled) { + g_object_set (self, + NM_MODEM_ENABLED, new_enabled, + NULL); + } +} + +static void +modem_disable_ready (MMModem *modem_iface, + GAsyncResult *res, + NMModemBroadband *self) +{ + GError *error = NULL; + + if (!mm_modem_disable_finish (modem_iface, res, &error)) { + nm_log_warn (LOGD_MB, "(%s) failed to disable modem: %s", + nm_modem_get_uid (NM_MODEM (self)), + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } else + /* Update enabled/disabled state again */ + update_mm_enabled (NM_MODEM (self), FALSE); + + /* Balance refcount */ + g_object_unref (self); +} + +static void +modem_enable_ready (MMModem *modem_iface, + GAsyncResult *res, + NMModemBroadband *self) +{ + 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)), + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } else + update_mm_enabled (NM_MODEM (self), TRUE); + + /* Balance refcount */ + g_object_unref (self); +} + +static void +set_mm_enabled (NMModem *_self, + gboolean enabled) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + + if (enabled) { + /* Don't even try to enable if we're known to be already locked */ + if (mm_modem_get_state (self->priv->modem_iface) == MM_MODEM_STATE_LOCKED) { + nm_log_warn (LOGD_MB, "(%s) cannot enable modem: locked", + nm_modem_get_uid (NM_MODEM (self))); + g_signal_emit_by_name (self, NM_MODEM_AUTH_REQUESTED, 0); + return; + } + + mm_modem_enable (self->priv->modem_iface, + NULL, /* cancellable */ + (GAsyncReadyCallback)modem_enable_ready, + g_object_ref (self)); + } else { + mm_modem_disable (self->priv->modem_iface, + NULL, /* cancellable */ + (GAsyncReadyCallback)modem_disable_ready, + g_object_ref (self)); + + /* When disabling don't say we're enabled */ + update_mm_enabled (NM_MODEM (self), enabled); + } +} + +/*****************************************************************************/ +/* IP method static */ + +static gboolean +ip_string_to_network_address (const gchar *str, + guint32 *out) +{ + struct in_addr addr; + + /* IP address */ + if (inet_pton (AF_INET, str, &addr) <= 0) + return FALSE; + + *out = (guint32)addr.s_addr; + return TRUE; +} + +static gboolean +static_stage3_done (NMModemBroadband *self) +{ + GError *error = NULL; + NMIP4Config *config = NULL; + const gchar *address_string; + guint32 address_network; + NMIP4Address *addr; + const gchar **dns; + guint i; + guint prefix; + + g_assert (self->priv->ipv4_config); + + nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", + nm_modem_get_uid (NM_MODEM (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_BROADBAND_ERROR, + NM_MODEM_BROADBAND_ERROR_CONNECTION_INVALID, + "(%s) retrieving IP4 configuration failed: invalid address given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + + config = nm_ip4_config_new (); + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, address_network); + prefix = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); + if (prefix > 0) + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_config_take_address (config, addr); + + nm_log_info (LOGD_MB, " address %s/%d", + mm_bearer_ip_config_get_address (self->priv->ipv4_config), + mm_bearer_ip_config_get_prefix (self->priv->ipv4_config)); + + /* 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) + && address_network > 0) { + nm_ip4_config_add_nameserver (config, address_network); + nm_log_info (LOGD_MB, " DNS %s", dns[i]); + } + } + +out: + g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, config, error); + g_clear_error (&error); + return FALSE; +} + +static NMActStageReturn +static_stage3_ip4_config_start (NMModem *_self, + NMActRequest *req, + 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)static_stage3_done, self); + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +/*****************************************************************************/ +/* Disconnect */ + +typedef struct { + NMModemBroadband *self; + gboolean warn; +} SimpleDisconnectContext; + +static void +simple_disconnect_context_free (SimpleDisconnectContext *ctx) +{ + g_object_unref (ctx->self); + g_slice_free (SimpleDisconnectContext, ctx); +} + +static void +simple_disconnect_ready (MMModemSimple *modem_iface, + GAsyncResult *res, + SimpleDisconnectContext *ctx) +{ + GError *error = NULL; + + if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) { + if (ctx->warn) + nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s", + nm_modem_get_uid (NM_MODEM (ctx->self)), + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + simple_disconnect_context_free (ctx); +} + +static void +disconnect (NMModem *self, + gboolean warn) +{ + SimpleDisconnectContext *ctx; + + ctx = g_slice_new (SimpleDisconnectContext); + ctx->self = g_object_ref (self); + + /* Don't bother warning on FAILED since the modem is already gone */ + ctx->warn = warn; + + mm_modem_simple_disconnect ( + ctx->self->priv->simple_iface, + NULL, /* bearer path; if NULL given ALL get disconnected */ + NULL, /* cancellable */ + (GAsyncReadyCallback)simple_disconnect_ready, + ctx); +} + +/*****************************************************************************/ + +static void +deactivate (NMModem *_self, NMDevice *device) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + + /* TODO: cancel SimpleConnect() if any */ + + /* Cleanup IPv4 addresses and routes */ + g_clear_object (&self->priv->ipv4_config); + g_clear_object (&self->priv->ipv6_config); + g_clear_object (&self->priv->bearer); + + self->priv->pin_tries = 0; + + /* Chain up parent's */ + NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate (_self, device); +} + +/*****************************************************************************/ + +static void +modem_state_changed (MMModem *modem, + MMModemState old_state, + MMModemState new_state, + MMModemStateChangeReason reason, + NMModemBroadband *self) +{ + gboolean old; + gboolean new; + + nm_log_info (LOGD_MB, "(%s) state changed, '%s' --> '%s' (reason: %s)\n", + nm_modem_get_uid (NM_MODEM (self)), + mm_modem_state_get_string (old_state), + mm_modem_state_get_string (new_state), + mm_modem_state_change_reason_get_string (reason)); + + old = nm_modem_get_mm_enabled (NM_MODEM (self)); + new = (mm_modem_get_state (self->priv->modem_iface) >= MM_MODEM_STATE_ENABLED); + if (old != new) + g_object_set (self, + NM_MODEM_ENABLED, new, + NULL); + + old = nm_modem_get_mm_connected (NM_MODEM (self)); + new = (mm_modem_get_state (self->priv->modem_iface) >= MM_MODEM_STATE_CONNECTED); + if (old != new) + g_object_set (self, + NM_MODEM_CONNECTED, new, + NULL); +} + +/*****************************************************************************/ + +NMModem * +nm_modem_broadband_new (GObject *object) +{ + MMObject *modem_object; + MMModem *modem_iface; + + g_return_val_if_fail (MM_IS_OBJECT (object), NULL); + modem_object = MM_OBJECT (object); + + /* Ensure we have the 'Modem' interface and the primary port at least */ + modem_iface = mm_object_peek_modem (modem_object); + g_return_val_if_fail (!!modem_iface, NULL); + g_return_val_if_fail (!!mm_modem_get_primary_port (modem_iface), NULL); + + /* If the modem is in 'FAILED' state we cannot do anything with it. + * This happens when a severe error happened when trying to initialize it, + * like missing SIM. */ + if (mm_modem_get_state (modem_iface) == MM_MODEM_STATE_FAILED) { + nm_log_warn (LOGD_MB, "(%s): unusable modem detected", + mm_modem_get_primary_port (modem_iface)); + return NULL; + } + + return (NMModem *) g_object_new (NM_TYPE_MODEM_BROADBAND, + NM_MODEM_PATH, mm_object_get_path (modem_object), + 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_BROADBAND_MODEM, modem_object, + NULL); +} + +static void +nm_modem_broadband_init (NMModemBroadband *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + NM_TYPE_MODEM_BROADBAND, + NMModemBroadbandPrivate); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (object); + + switch (prop_id) { + case PROP_MODEM: + /* construct-only */ + self->priv->modem_object = g_value_dup_object (value); + self->priv->modem_iface = mm_object_get_modem (self->priv->modem_object); + g_assert (self->priv->modem_iface != NULL); + g_signal_connect (self->priv->modem_iface, + "state-changed", + G_CALLBACK (modem_state_changed), + self); + + g_object_set (object, + NM_MODEM_ENABLED, (mm_modem_get_state (self->priv->modem_iface) >= MM_MODEM_STATE_ENABLED), + NM_MODEM_CONNECTED, (mm_modem_get_state (self->priv->modem_iface) >= MM_MODEM_STATE_CONNECTED), + NULL); + + /* Note: don't grab the Simple iface here; the Modem interface is the + * only one assumed to be always valid and available */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (object); + + switch (prop_id) { + case PROP_MODEM: + g_value_set_object (value, self->priv->modem_object); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (object); + + g_clear_object (&self->priv->ipv4_config); + g_clear_object (&self->priv->ipv6_config); + g_clear_object (&self->priv->bearer); + g_clear_object (&self->priv->modem_iface); + g_clear_object (&self->priv->simple_iface); + g_clear_object (&self->priv->modem_object); + + G_OBJECT_CLASS (nm_modem_broadband_parent_class)->dispose (object); +} + +static void +nm_modem_broadband_class_init (NMModemBroadbandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMModemClass *modem_class = NM_MODEM_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMModemBroadbandPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + 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; + modem_class->get_user_pass = get_user_pass; + modem_class->get_setting_name = get_setting_name; + modem_class->get_best_auto_connection = get_best_auto_connection; + modem_class->check_connection_compatible = check_connection_compatible; + modem_class->complete_connection = complete_connection; + modem_class->act_stage1_prepare = act_stage1_prepare; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_MODEM, + g_param_spec_object (NM_MODEM_BROADBAND_MODEM, + "Modem", + "Broadband modem object", + MM_GDBUS_TYPE_OBJECT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} diff --git a/src/modem-manager/nm-modem-broadband.h b/src/modem-manager/nm-modem-broadband.h new file mode 100644 index 00000000..005c3853 --- /dev/null +++ b/src/modem-manager/nm-modem-broadband.h @@ -0,0 +1,69 @@ +/* -*- 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) 2012 - Aleksander Morgado <aleksander@gnu.org> + */ + +#ifndef NM_MODEM_BROADBAND_H +#define NM_MODEM_BROADBAND_H + +#include <dbus/dbus-glib.h> +#include <glib-object.h> +#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)) +#define NM_IS_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_BROADBAND)) +#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; + +typedef enum { + NM_MODEM_BROADBAND_ERROR_CONNECTION_NOT_GSM, /*< nick=ConnectionNotGsm >*/ + NM_MODEM_BROADBAND_ERROR_CONNECTION_NOT_CDMA, /*< nick=ConnectionNotCdma >*/ + NM_MODEM_BROADBAND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_MODEM_BROADBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMModemBroadbandError; + +struct _NMModemBroadband { + NMModem parent; + NMModemBroadbandPrivate *priv; +}; + +struct _NMModemBroadbandClass { + NMModemClass parent; +}; + +GType nm_modem_broadband_get_type (void); + +NMModem *nm_modem_broadband_new (GObject *object); + +void nm_modem_broadband_get_capabilities (NMModemBroadband *self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps); + +G_END_DECLS + +#endif /* NM_MODEM_BROADBAND_H */ diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c index fa19a342..73c87c28 100644 --- a/src/modem-manager/nm-modem-cdma.c +++ b/src/modem-manager/nm-modem-cdma.c @@ -37,7 +37,7 @@ #include "NetworkManagerUtils.h" #include "nm-logging.h" -G_DEFINE_TYPE (NMModemCdma, nm_modem_cdma, NM_TYPE_MODEM) +G_DEFINE_TYPE (NMModemCdma, nm_modem_cdma, NM_TYPE_MODEM_GENERIC) #define NM_MODEM_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_CDMA, NMModemCdmaPrivate)) @@ -62,19 +62,20 @@ nm_cdma_error_quark (void) NMModem * nm_modem_cdma_new (const char *path, - const char *device, const char *data_device, - guint32 ip_method) + guint32 ip_method, + NMModemState state) { g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (data_device != NULL, NULL); return (NMModem *) g_object_new (NM_TYPE_MODEM_CDMA, NM_MODEM_PATH, path, - NM_MODEM_DEVICE, device, - NM_MODEM_IFACE, data_device, + NM_MODEM_UID, data_device, + NM_MODEM_CONTROL_PORT, NULL, + NM_MODEM_DATA_PORT, data_device, NM_MODEM_IP_METHOD, ip_method, + NM_MODEM_CONNECTED, (state == NM_MODEM_STATE_CONNECTED), NULL); } @@ -109,7 +110,7 @@ do_connect (NMModemCdma *self) NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (self); DBusGProxy *proxy; - proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_SIMPLE); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); priv->call = dbus_g_proxy_begin_call_with_timeout (proxy, "Connect", stage1_prepare_done, self, NULL, 120000, @@ -152,11 +153,11 @@ create_connect_properties (NMConnection *connection) } static NMActStageReturn -real_act_stage1_prepare (NMModem *modem, - NMActRequest *req, - GPtrArray **out_hints, - const char **out_setting_name, - NMDeviceStateReason *reason) +act_stage1_prepare (NMModem *modem, + NMActRequest *req, + GPtrArray **out_hints, + const char **out_setting_name, + NMDeviceStateReason *reason) { NMModemCdma *self = NM_MODEM_CDMA (modem); NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (self); @@ -177,7 +178,7 @@ real_act_stage1_prepare (NMModem *modem, if (enabled) do_connect (self); else { - proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_OLD_DBUS_INTERFACE_MODEM); dbus_g_proxy_begin_call_with_timeout (proxy, "Enable", stage1_enable_done, modem, NULL, 20000, @@ -192,9 +193,9 @@ real_act_stage1_prepare (NMModem *modem, } static NMConnection * -real_get_best_auto_connection (NMModem *modem, - GSList *connections, - char **specific_object) +get_best_auto_connection (NMModem *modem, + GSList *connections, + char **specific_object) { GSList *iter; @@ -217,9 +218,9 @@ real_get_best_auto_connection (NMModem *modem, } static gboolean -real_check_connection_compatible (NMModem *modem, - NMConnection *connection, - GError **error) +check_connection_compatible (NMModem *modem, + NMConnection *connection, + GError **error) { NMSettingConnection *s_con; NMSettingCdma *s_cdma; @@ -246,10 +247,10 @@ real_check_connection_compatible (NMModem *modem, } static gboolean -real_complete_connection (NMModem *modem, - NMConnection *connection, - const GSList *existing_connections, - GError **error) +complete_connection (NMModem *modem, + NMConnection *connection, + const GSList *existing_connections, + GError **error) { NMSettingCdma *s_cdma; NMSettingPPP *s_ppp; @@ -284,10 +285,10 @@ real_complete_connection (NMModem *modem, } static gboolean -real_get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) +get_user_pass (NMModem *modem, + NMConnection *connection, + const char **user, + const char **pass) { NMSettingCdma *s_cdma; @@ -304,25 +305,25 @@ real_get_user_pass (NMModem *modem, } static const char * -real_get_setting_name (NMModem *modem) +get_setting_name (NMModem *modem) { return NM_SETTING_CDMA_SETTING_NAME; } static void -real_deactivate (NMModem *modem, NMDevice *device) +deactivate (NMModem *modem, NMDevice *device) { NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (modem); if (priv->call) { DBusGProxy *proxy; - proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); dbus_g_proxy_cancel_call (proxy, priv->call); priv->call = NULL; } - NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate (modem, device); + NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate (modem, device); } /*****************************************************************************/ @@ -354,13 +355,13 @@ nm_modem_cdma_class_init (NMModemCdmaClass *klass) /* Virtual methods */ object_class->dispose = dispose; - modem_class->get_user_pass = real_get_user_pass; - modem_class->get_setting_name = real_get_setting_name; - modem_class->get_best_auto_connection = real_get_best_auto_connection; - modem_class->check_connection_compatible = real_check_connection_compatible; - modem_class->complete_connection = real_complete_connection; - modem_class->act_stage1_prepare = real_act_stage1_prepare; - modem_class->deactivate = real_deactivate; + modem_class->get_user_pass = get_user_pass; + modem_class->get_setting_name = get_setting_name; + modem_class->get_best_auto_connection = get_best_auto_connection; + modem_class->check_connection_compatible = check_connection_compatible; + modem_class->complete_connection = complete_connection; + modem_class->act_stage1_prepare = act_stage1_prepare; + modem_class->deactivate = deactivate; dbus_g_error_domain_register (NM_CDMA_ERROR, NULL, NM_TYPE_CDMA_ERROR); } diff --git a/src/modem-manager/nm-modem-cdma.h b/src/modem-manager/nm-modem-cdma.h index 2229c183..ab1b4874 100644 --- a/src/modem-manager/nm-modem-cdma.h +++ b/src/modem-manager/nm-modem-cdma.h @@ -22,14 +22,14 @@ #ifndef NM_MODEM_CDMA_H #define NM_MODEM_CDMA_H -#include <nm-modem.h> +#include <nm-modem-generic.h> G_BEGIN_DECLS -#define NM_TYPE_MODEM_CDMA (nm_modem_cdma_get_type ()) -#define NM_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_CDMA, NMModemCdma)) -#define NM_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) -#define NM_IS_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_CDMA)) +#define NM_TYPE_MODEM_CDMA (nm_modem_cdma_get_type ()) +#define NM_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_CDMA, NMModemCdma)) +#define NM_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) +#define NM_IS_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_CDMA)) #define NM_IS_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_CDMA)) #define NM_MODEM_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) @@ -40,22 +40,19 @@ typedef enum { } NMCdmaError; typedef struct { - NMModem parent; + NMModemGeneric parent; } NMModemCdma; typedef struct { - NMModemClass parent; - - /* Signals */ - void (*signal_quality) (NMModemCdma *self, guint32 quality); + NMModemGenericClass parent; } NMModemCdmaClass; GType nm_modem_cdma_get_type (void); NMModem *nm_modem_cdma_new (const char *path, - const char *device, const char *data_device, - guint32 ip_method); + guint32 ip_method, + NMModemState state); G_END_DECLS diff --git a/src/modem-manager/nm-modem-generic.c b/src/modem-manager/nm-modem-generic.c new file mode 100644 index 00000000..f4e7a52f --- /dev/null +++ b/src/modem-manager/nm-modem-generic.c @@ -0,0 +1,445 @@ +/* -*- 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. + */ + +#include <string.h> +#include "nm-modem-generic.h" +#include "nm-system.h" +#include "nm-dbus-manager.h" +#include "nm-setting-connection.h" +#include "nm-marshal.h" +#include "nm-properties-changed-signal.h" +#include "nm-modem-types.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-dbus-glib-types.h" + +G_DEFINE_TYPE (NMModemGeneric, nm_modem_generic, NM_TYPE_MODEM) + +#define NM_MODEM_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GENERIC, NMModemGenericPrivate)) + +typedef struct { + NMDBusManager *dbus_mgr; + DBusGProxy *proxy; + DBusGProxy *props_proxy; + + DBusGProxyCall *call; + + NMModemState state; +} NMModemGenericPrivate; + +/*****************************************************************************/ + +DBusGProxy * +nm_modem_generic_get_proxy (NMModemGeneric *self, + const char *interface) +{ + + NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self); + const char *current_iface; + + g_return_val_if_fail (NM_IS_MODEM_GENERIC (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 +update_mm_enabled (NMModem *self, + gboolean new_enabled) +{ + if (nm_modem_get_mm_enabled (self) != new_enabled) { + g_object_set (self, + NM_MODEM_ENABLED, new_enabled, + NULL); + } +} + +static void +get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + GError *error = NULL; + GValue value = { 0, }; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_VALUE, &value, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + return; + } + + if (G_VALUE_HOLDS_BOOLEAN (&value)) { + update_mm_enabled (self, g_value_get_boolean (&value)); + } else + nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type"); + + g_value_unset (&value); +} + +static void +query_mm_enabled (NMModemGeneric *self) +{ + dbus_g_proxy_begin_call (NM_MODEM_GENERIC_GET_PRIVATE (self)->props_proxy, + "Get", get_mm_enabled_done, + self, NULL, + G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM, + G_TYPE_STRING, "Enabled", + G_TYPE_INVALID); +} + +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)"); + } + + /* Update enabled/disabled state again */ + query_mm_enabled (NM_MODEM_GENERIC (user_data)); +} + +static void +set_mm_enabled (NMModem *self, gboolean enabled) +{ + /* FIXME: For now this just toggles the ModemManager enabled state. In the + * future we want to tie this into rfkill state instead so that the user can + * toggle rfkill status of the WWAN modem. + */ + dbus_g_proxy_begin_call (nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), + MM_OLD_DBUS_INTERFACE_MODEM), + "Enable", set_mm_enabled_done, + self, NULL, + G_TYPE_BOOLEAN, enabled, + G_TYPE_INVALID); + /* If we are disabling the modem, stop saying that it's enabled. */ + if (!enabled) + update_mm_enabled (self, enabled); +} + +/*****************************************************************************/ +/* IP method static */ + +static char addr_to_string_buf[INET6_ADDRSTRLEN + 1]; + +static const char * +ip_address_to_string (guint32 numeric) +{ + struct in_addr temp_addr; + + memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf)); + temp_addr.s_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.s_addr)); + return NULL; + } +} + +static void +static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + NMModemGeneric *self = NM_MODEM_GENERIC (user_data); + NMModemGenericPrivate *priv = NM_MODEM_GENERIC_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)) { + NMIP4Address *addr; + int i; + + config = nm_ip4_config_new (); + + addr = nm_ip4_address_new (); + + nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", + nm_modem_get_uid (NM_MODEM (self))); + + /* IP address */ + nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0))); + nm_ip4_address_set_prefix (addr, 32); + nm_ip4_config_take_address (config, addr); + + nm_log_info (LOGD_MB, " address %s/%d", + ip_address_to_string (nm_ip4_address_get_address (addr)), + nm_ip4_address_get_prefix (addr)); + + /* 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) +{ + NMModemGenericPrivate *priv; + + 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); + + priv = NM_MODEM_GENERIC_GET_PRIVATE (self); + + priv->call = dbus_g_proxy_begin_call (nm_modem_generic_get_proxy (NM_MODEM_GENERIC (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_generic_get_proxy (NM_MODEM_GENERIC (self), + MM_OLD_DBUS_INTERFACE_MODEM), + "Disconnect", + disconnect_done, + GUINT_TO_POINTER (warn), + NULL, + G_TYPE_INVALID); +} + +/*****************************************************************************/ + +static void +deactivate (NMModem *self, NMDevice *device) +{ + NMModemGenericPrivate *priv; + + g_assert (NM_IS_MODEM_GENERIC (self)); + g_assert (NM_IS_DEVICE (device)); + + priv = NM_MODEM_GENERIC_GET_PRIVATE (self); + + if (priv->call) { + dbus_g_proxy_cancel_call (priv->proxy, priv->call); + priv->call = NULL; + } + + /* Chain up parent's */ + NM_MODEM_CLASS (nm_modem_generic_parent_class)->deactivate (self, device); +} + +/*****************************************************************************/ + +static void +modem_properties_changed (DBusGProxy *proxy, + const char *interface, + GHashTable *props, + gpointer user_data) +{ + NMModemGeneric *self = NM_MODEM_GENERIC (user_data); + NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self); + GValue *value; + NMModemState new_state; + + if (strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM)) + return; + + value = g_hash_table_lookup (props, "Enabled"); + if (value && G_VALUE_HOLDS_BOOLEAN (value)) { + g_object_set (self, + NM_MODEM_ENABLED, g_value_get_boolean (value), + NULL); + } + + 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, "State"); + if (value && G_VALUE_HOLDS_UINT (value)) { + new_state = g_value_get_uint (value); + if (new_state != priv->state) { + if (new_state == NM_MODEM_STATE_CONNECTED) + g_object_set (self, + NM_MODEM_CONNECTED, TRUE, + NULL); + else if (priv->state == NM_MODEM_STATE_CONNECTED) + g_object_set (self, + NM_MODEM_CONNECTED, FALSE, + NULL); + priv->state = new_state; + } + } +} + +/*****************************************************************************/ + +static void +nm_modem_generic_init (NMModemGeneric *self) +{ + NMModemGenericPrivate *priv = NM_MODEM_GENERIC_GET_PRIVATE (self); + + priv->dbus_mgr = nm_dbus_manager_get (); +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMModemGenericPrivate *priv; + DBusGConnection *bus; + + object = G_OBJECT_CLASS (nm_modem_generic_parent_class)->constructor (type, n_construct_params, construct_params); + if (!object) + return NULL; + + priv = NM_MODEM_GENERIC_GET_PRIVATE (object); + + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + 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 (_nm_marshal_VOID__STRING_BOXED, + 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); + + query_mm_enabled (NM_MODEM_GENERIC (object)); + + return object; +} + +static void +dispose (GObject *object) +{ + NMModemGenericPrivate *priv = NM_MODEM_GENERIC_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->dbus_mgr) { + g_object_unref (priv->dbus_mgr); + priv->dbus_mgr = NULL; + } + + G_OBJECT_CLASS (nm_modem_generic_parent_class)->dispose (object); +} + +static void +nm_modem_generic_class_init (NMModemGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMModemClass *modem_class = NM_MODEM_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMModemGenericPrivate)); + + /* Virtual methods */ + object_class->constructor = constructor; + object_class->dispose = dispose; + + 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/modem-manager/nm-modem-generic.h b/src/modem-manager/nm-modem-generic.h new file mode 100644 index 00000000..59866a1e --- /dev/null +++ b/src/modem-manager/nm-modem-generic.h @@ -0,0 +1,69 @@ +/* -*- 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_GENERIC_H +#define NM_MODEM_GENERIC_H + +#include <dbus/dbus-glib.h> +#include <glib-object.h> +#include "nm-modem.h" + +G_BEGIN_DECLS + +#define NM_TYPE_MODEM_GENERIC (nm_modem_generic_get_type ()) +#define NM_MODEM_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GENERIC, NMModemGeneric)) +#define NM_MODEM_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GENERIC, NMModemGenericClass)) +#define NM_IS_MODEM_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GENERIC)) +#define NM_IS_MODEM_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GENERIC)) +#define NM_MODEM_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GENERIC, NMModemGenericClass)) + +typedef enum { + NM_MODEM_STATE_UNKNOWN = 0, + NM_MODEM_STATE_DISABLED = 10, + NM_MODEM_STATE_DISABLING = 20, + NM_MODEM_STATE_ENABLING = 30, + NM_MODEM_STATE_ENABLED = 40, + NM_MODEM_STATE_SEARCHING = 50, + NM_MODEM_STATE_REGISTERED = 60, + NM_MODEM_STATE_DISCONNECTING = 70, + NM_MODEM_STATE_CONNECTING = 80, + NM_MODEM_STATE_CONNECTED = 90, + + NM_MODEM_STATE_LAST = NM_MODEM_STATE_CONNECTED +} NMModemState; + +typedef struct { + NMModem parent; +} NMModemGeneric; + +typedef struct { + NMModemClass parent; +} NMModemGenericClass; + +GType nm_modem_generic_get_type (void); + +/* Protected */ +DBusGProxy *nm_modem_generic_get_proxy (NMModemGeneric *modem, + const gchar *interface); + +G_END_DECLS + +#endif /* NM_MODEM_GENERIC_H */ diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index 183b4780..b6d3c857 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -58,8 +58,10 @@ typedef enum { 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_3G_ONLY + MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY } MMModemGsmAllowedMode; typedef enum { @@ -75,7 +77,7 @@ typedef enum { MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP } MMModemGsmAllowedAuth; -G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM) +G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM_GENERIC) #define NM_MODEM_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GSM, NMModemGsmPrivate)) @@ -102,19 +104,20 @@ nm_gsm_error_quark (void) NMModem * nm_modem_gsm_new (const char *path, - const char *device, const char *data_device, - guint32 ip_method) + guint32 ip_method, + NMModemState state) { g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (data_device != NULL, NULL); return (NMModem *) g_object_new (NM_TYPE_MODEM_GSM, NM_MODEM_PATH, path, - NM_MODEM_DEVICE, device, - NM_MODEM_IFACE, data_device, + NM_MODEM_UID, data_device, + NM_MODEM_CONTROL_PORT, NULL, + NM_MODEM_DATA_PORT, data_device, NM_MODEM_IP_METHOD, ip_method, + NM_MODEM_CONNECTED, (state == NM_MODEM_STATE_CONNECTED), NULL); } @@ -222,12 +225,12 @@ do_connect (NMModemGsm *self) NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self); DBusGProxy *proxy; - proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_SIMPLE); - 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); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (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); @@ -242,7 +245,7 @@ do_enable (NMModemGsm *self) g_return_val_if_fail (NM_IS_MODEM_GSM (self), FALSE); NM_MODEM_GSM_GET_PRIVATE (self)->enable_delay_id = 0; - proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_OLD_DBUS_INTERFACE_MODEM); dbus_g_proxy_begin_call_with_timeout (proxy, "Enable", stage1_enable_done, self, NULL, 20000, @@ -295,7 +298,7 @@ handle_enable_pin_required (NMModemGsm *self) /* If we do, send it */ if (pin) { - proxy = nm_modem_get_proxy (NM_MODEM (self), MM_DBUS_INTERFACE_MODEM_GSM_CARD); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (self), MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD); dbus_g_proxy_begin_call_with_timeout (proxy, "SendPin", stage1_pin_done, self, NULL, 10000, @@ -387,6 +390,14 @@ create_connect_properties (NMConnection *connection) 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); @@ -423,11 +434,11 @@ create_connect_properties (NMConnection *connection) } static NMActStageReturn -real_act_stage1_prepare (NMModem *modem, - NMActRequest *req, - GPtrArray **out_hints, - const char **out_setting_name, - NMDeviceStateReason *reason) +act_stage1_prepare (NMModem *modem, + NMActRequest *req, + GPtrArray **out_hints, + const char **out_setting_name, + NMDeviceStateReason *reason) { NMModemGsm *self = NM_MODEM_GSM (modem); NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (self); @@ -456,9 +467,9 @@ real_act_stage1_prepare (NMModem *modem, } static NMConnection * -real_get_best_auto_connection (NMModem *modem, - GSList *connections, - char **specific_object) +get_best_auto_connection (NMModem *modem, + GSList *connections, + char **specific_object) { GSList *iter; @@ -481,9 +492,9 @@ real_get_best_auto_connection (NMModem *modem, } static gboolean -real_check_connection_compatible (NMModem *modem, - NMConnection *connection, - GError **error) +check_connection_compatible (NMModem *modem, + NMConnection *connection, + GError **error) { NMSettingConnection *s_con; NMSettingGsm *s_gsm; @@ -510,10 +521,10 @@ real_check_connection_compatible (NMModem *modem, } static gboolean -real_complete_connection (NMModem *modem, - NMConnection *connection, - const GSList *existing_connections, - GError **error) +complete_connection (NMModem *modem, + NMConnection *connection, + const GSList *existing_connections, + GError **error) { NMSettingGsm *s_gsm; NMSettingPPP *s_ppp; @@ -552,10 +563,10 @@ real_complete_connection (NMModem *modem, } static gboolean -real_get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) +get_user_pass (NMModem *modem, + NMConnection *connection, + const char **user, + const char **pass) { NMSettingGsm *s_gsm; @@ -572,20 +583,20 @@ real_get_user_pass (NMModem *modem, } static const char * -real_get_setting_name (NMModem *modem) +get_setting_name (NMModem *modem) { return NM_SETTING_GSM_SETTING_NAME; } static void -real_deactivate (NMModem *modem, NMDevice *device) +deactivate (NMModem *modem, NMDevice *device) { NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (modem); if (priv->call) { DBusGProxy *proxy; - proxy = nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM_SIMPLE); + proxy = nm_modem_generic_get_proxy (NM_MODEM_GENERIC (modem), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); dbus_g_proxy_cancel_call (proxy, priv->call); priv->call = NULL; } @@ -630,13 +641,13 @@ nm_modem_gsm_class_init (NMModemGsmClass *klass) /* Virtual methods */ object_class->dispose = dispose; - modem_class->get_user_pass = real_get_user_pass; - modem_class->get_setting_name = real_get_setting_name; - modem_class->get_best_auto_connection = real_get_best_auto_connection; - modem_class->check_connection_compatible = real_check_connection_compatible; - modem_class->complete_connection = real_complete_connection; - modem_class->act_stage1_prepare = real_act_stage1_prepare; - modem_class->deactivate = real_deactivate; + modem_class->get_user_pass = get_user_pass; + modem_class->get_setting_name = get_setting_name; + modem_class->get_best_auto_connection = get_best_auto_connection; + modem_class->check_connection_compatible = check_connection_compatible; + modem_class->complete_connection = complete_connection; + modem_class->act_stage1_prepare = act_stage1_prepare; + modem_class->deactivate = deactivate; dbus_g_error_domain_register (NM_GSM_ERROR, NULL, NM_TYPE_GSM_ERROR); } diff --git a/src/modem-manager/nm-modem-gsm.h b/src/modem-manager/nm-modem-gsm.h index e1c94f04..b0f78b0a 100644 --- a/src/modem-manager/nm-modem-gsm.h +++ b/src/modem-manager/nm-modem-gsm.h @@ -22,16 +22,16 @@ #ifndef NM_MODEM_GSM_H #define NM_MODEM_GSM_H -#include <nm-modem.h> +#include <nm-modem-generic.h> G_BEGIN_DECLS -#define NM_TYPE_MODEM_GSM (nm_modem_gsm_get_type ()) -#define NM_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GSM, NMModemGsm)) -#define NM_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GSM, NMModemGsmClass)) -#define NM_IS_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GSM)) +#define NM_TYPE_MODEM_GSM (nm_modem_gsm_get_type ()) +#define NM_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GSM, NMModemGsm)) +#define NM_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GSM, NMModemGsmClass)) +#define NM_IS_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GSM)) #define NM_IS_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GSM)) -#define NM_MODEM_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM, NMModemGsmClass)) +#define NM_MODEM_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM, NMModemGsmClass)) typedef enum { NM_GSM_ERROR_CONNECTION_NOT_GSM = 0, /*< nick=ConnectionNotGsm >*/ @@ -40,22 +40,19 @@ typedef enum { } NMGsmError; typedef struct { - NMModem parent; + NMModemGeneric parent; } NMModemGsm; typedef struct { - NMModemClass parent; - - /* Signals */ - void (*signal_quality) (NMModemGsm *self, guint32 quality); + NMModemGenericClass parent; } NMModemGsmClass; GType nm_modem_gsm_get_type (void); NMModem *nm_modem_gsm_new (const char *path, - const char *device, const char *data_device, - guint32 ip_method); + guint32 ip_method, + NMModemState state); G_END_DECLS diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c index 051940f5..d896b468 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/modem-manager/nm-modem-manager.c @@ -21,6 +21,7 @@ */ #include <string.h> +#include "config.h" #include "nm-modem-manager.h" #include "nm-logging.h" #include "nm-modem.h" @@ -31,19 +32,33 @@ #include "nm-marshal.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) -#define NM_MODEM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_MANAGER, NMModemManagerPrivate)) - -typedef struct { +struct _NMModemManagerPrivate { + /* ModemManager < 0.7 */ NMDBusManager *dbus_mgr; DBusGProxy *proxy; - GHashTable *modems; - gboolean disposed; guint poke_id; -} NMModemManagerPrivate; + +#if WITH_MODEM_MANAGER_1 + /* ModemManager >= 0.7 */ + GDBusConnection *dbus_connection; + MMManager *modem_manager_1; + guint modem_manager_1_poke_id; + gboolean old_modem_manager_found; + gboolean new_modem_manager_found; +#endif + + /* Common */ + GHashTable *modems; +}; enum { MODEM_ADDED, @@ -69,6 +84,28 @@ nm_modem_manager_get (void) return singleton; } +/************************************************************************/ +/* 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; + } + + if (self->priv->dbus_mgr) { + g_object_unref (self->priv->dbus_mgr); + self->priv->dbus_mgr = NULL; + } +} + static gboolean get_modem_properties (DBusGConnection *connection, const char *path, @@ -77,7 +114,8 @@ get_modem_properties (DBusGConnection *connection, char **driver, guint32 *type, guint32 *ip_method, - guint32 *ip_timeout) + guint32 *ip_timeout, + NMModemState *state) { DBusGProxy *proxy; GError *err = NULL; @@ -87,12 +125,12 @@ get_modem_properties (DBusGConnection *connection, GValue *value; proxy = dbus_g_proxy_new_for_name (connection, - MM_DBUS_SERVICE, + MM_OLD_DBUS_SERVICE, path, "org.freedesktop.DBus.Properties"); if (!dbus_g_proxy_call_with_timeout (proxy, "GetAll", 15000, &err, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, + G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM, G_TYPE_INVALID, DBUS_TYPE_G_MAP_OF_VARIANT, &props, G_TYPE_INVALID)) { @@ -122,6 +160,8 @@ get_modem_properties (DBusGConnection *connection, *driver = g_value_dup_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); } g_hash_table_unref (props); @@ -132,23 +172,23 @@ get_modem_properties (DBusGConnection *connection, } static void -create_modem (NMModemManager *manager, const char *path) +create_modem (NMModemManager *self, const char *path) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (manager); NMModem *modem = NULL; char *data_device = NULL, *driver = NULL, *master_device = NULL; uint modem_type = MM_MODEM_TYPE_UNKNOWN; uint ip_method = MM_MODEM_IP_METHOD_PPP; uint ip_timeout = 0; + NMModemState state = NM_MODEM_STATE_UNKNOWN; - if (g_hash_table_lookup (priv->modems, path)) { + if (g_hash_table_lookup (self->priv->modems, path)) { nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); return; } - if (!get_modem_properties (nm_dbus_manager_get_connection (priv->dbus_mgr), + if (!get_modem_properties (nm_dbus_manager_get_connection (self->priv->dbus_mgr), path, &master_device, &data_device, &driver, - &modem_type, &ip_method, &ip_timeout)) + &modem_type, &ip_method, &ip_timeout, &state)) return; if (modem_type == MM_MODEM_TYPE_UNKNOWN) { @@ -172,9 +212,9 @@ create_modem (NMModemManager *manager, const char *path) } if (modem_type == MM_MODEM_TYPE_GSM) - modem = nm_modem_gsm_new (path, master_device, data_device, ip_method); + modem = nm_modem_gsm_new (path, data_device, ip_method, state); else if (modem_type == MM_MODEM_TYPE_CDMA) - modem = nm_modem_cdma_new (path, master_device, data_device, ip_method); + modem = nm_modem_cdma_new (path, data_device, ip_method, state); else nm_log_warn (LOGD_MB, "unknown modem type '%d'", modem_type); @@ -182,8 +222,8 @@ create_modem (NMModemManager *manager, const char *path) if (modem) { g_object_set (G_OBJECT (modem), NM_MODEM_IP_TIMEOUT, ip_timeout, NULL); - g_hash_table_insert (priv->modems, g_strdup (path), modem); - g_signal_emit (manager, signals[MODEM_ADDED], 0, modem, driver); + g_hash_table_insert (self->priv->modems, g_strdup (path), modem); + g_signal_emit (self, signals[MODEM_ADDED], 0, modem, driver); } g_free (driver); @@ -198,13 +238,13 @@ modem_added (DBusGProxy *proxy, const char *path, gpointer user_data) static void modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (user_data); + NMModemManager *self = NM_MODEM_MANAGER (user_data); NMModem *modem; - modem = (NMModem *) g_hash_table_lookup (priv->modems, path); + modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); if (modem) { - g_signal_emit (user_data, signals[MODEM_REMOVED], 0, modem); - g_hash_table_remove (priv->modems, path); + g_signal_emit (self, signals[MODEM_REMOVED], 0, modem); + g_hash_table_remove (self->priv->modems, path); } } @@ -229,16 +269,17 @@ static gboolean poke_modem_cb (gpointer user_data) { NMModemManager *self = NM_MODEM_MANAGER (user_data); - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); DBusGConnection *g_connection; DBusGProxy *proxy; DBusGProxyCall *call; - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + g_connection = nm_dbus_manager_get_connection (self->priv->dbus_mgr); proxy = dbus_g_proxy_new_for_name (g_connection, - MM_DBUS_SERVICE, - MM_DBUS_PATH, - MM_DBUS_INTERFACE); + MM_OLD_DBUS_SERVICE, + MM_OLD_DBUS_PATH, + MM_OLD_DBUS_INTERFACE); + + nm_log_dbg (LOGD_MB, "Requesting to (re)launch modem-manager..."); call = dbus_g_proxy_begin_call_with_timeout (proxy, "EnumerateDevices", @@ -276,33 +317,43 @@ enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer dat } } +#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) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - - if (priv->poke_id) { - g_source_remove (priv->poke_id); - priv->poke_id = 0; + 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"); - priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), - MM_DBUS_SERVICE, MM_DBUS_PATH, MM_DBUS_INTERFACE); +#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 (priv->proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded", + 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 (priv->proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved", + 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 (priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); + dbus_g_proxy_begin_call (self->priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); } static gboolean @@ -316,19 +367,17 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) static void modem_manager_disappeared (NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - - g_hash_table_foreach_remove (priv->modems, remove_one_modem, self); + g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, self); - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; + if (self->priv->proxy) { + g_object_unref (self->priv->proxy); + self->priv->proxy = NULL; } /* Try to activate the modem-manager */ - nm_log_info (LOGD_MB, "trying to start the modem manager..."); + nm_log_dbg (LOGD_MB, "trying to start the modem manager..."); poke_modem_cb (self); - priv->poke_id = g_timeout_add_seconds (MODEM_POKE_INTERVAL, poke_modem_cb, self); + self->priv->poke_id = g_timeout_add_seconds (MODEM_POKE_INTERVAL, poke_modem_cb, self); } static void @@ -342,7 +391,7 @@ nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, gboolean new_owner_good; /* Can't handle the signal if its not from the modem service */ - if (strcmp (MM_DBUS_SERVICE, name) != 0) + if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0) return; old_owner_good = (old_owner && strlen (old_owner)); @@ -356,52 +405,306 @@ nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, } } -/*******************************************************/ +/************************************************************************/ +/* Support for ModemManager >= 0.7 */ + +#if WITH_MODEM_MANAGER_1 static void -nm_modem_manager_init (NMModemManager *self) +clear_modem_manager_1_support (NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + if (self->priv->modem_manager_1_poke_id) { + g_source_remove (self->priv->modem_manager_1_poke_id); + self->priv->modem_manager_1_poke_id = 0; + } - priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - priv->dbus_mgr = nm_dbus_manager_get (); + g_clear_object (&self->priv->modem_manager_1); + g_clear_object (&self->priv->dbus_connection); +} - g_signal_connect (priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (nm_modem_manager_name_owner_changed), - self); +static void +modem_object_added (MMManager *modem_manager, + MMObject *modem_object, + NMModemManager *self) +{ + const gchar *path; + gchar *drivers; + MMModem *modem_iface; + NMModem *modem; - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE)) - modem_manager_appeared (self, TRUE); + /* Ensure we don't have the same modem already */ + path = mm_object_get_path (modem_object); + if (g_hash_table_lookup (self->priv->modems, path)) { + nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); + return; + } + + /* Ensure we have the 'Modem' interface at least */ + modem_iface = mm_object_peek_modem (modem_object); + if (!modem_iface) { + nm_log_warn (LOGD_MB, "modem with path %s doesn't have the Modem interface, ignoring", path); + return; + } + + /* Ensure we have a primary port reported */ + if (!mm_modem_get_primary_port (modem_iface)) { + nm_log_warn (LOGD_MB, "modem with path %s has unknown primary port, ignoring", path); + return; + } + + /* Create a new modem object */ + modem = nm_modem_broadband_new (G_OBJECT (modem_object)); + if (!modem) + return; + + /* Build a single string with all drivers listed */ + drivers = g_strjoinv (", ", (gchar **)mm_modem_get_drivers (modem_iface)); + + /* Keep track of the new modem and notify about it */ + g_hash_table_insert (self->priv->modems, g_strdup (path), modem); + g_signal_emit (self, signals[MODEM_ADDED], 0, modem, drivers); + g_free (drivers); +} + +static void +modem_object_removed (MMManager *manager, + MMObject *modem_object, + NMModemManager *self) +{ + NMModem *modem; + const gchar *path; + + path = mm_object_get_path (modem_object); + modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); + if (!modem) + return; + + g_signal_emit (self, signals[MODEM_REMOVED], 0, modem); + g_hash_table_remove (self->priv->modems, path); +} + +static void +modem_manager_1_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 - modem_manager_disappeared (self); + 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); } +static void schedule_modem_manager_1_relaunch (NMModemManager *self, + guint n_seconds); + static void -dispose (GObject *object) +modem_manager_1_name_owner_changed (MMManager *modem_manager_1, + GParamSpec *pspec, + NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (object); + /* Quit poking, if any */ + if (self->priv->modem_manager_1_poke_id) { + g_source_remove (self->priv->modem_manager_1_poke_id); + self->priv->modem_manager_1_poke_id = 0; + } - if (priv->disposed) + if (!g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager_1))) { + nm_log_info (LOGD_MB, "ModemManager disappeared from bus"); + schedule_modem_manager_1_relaunch (self, 0); return; + } + + /* Available! */ + modem_manager_1_available (self); +} + +static void +manager_new_ready (GObject *source, + GAsyncResult *res, + NMModemManager *self) +{ + /* Note we always get an extra reference to self here */ - priv->disposed = TRUE; + GError *error = NULL; - if (priv->poke_id) { - g_source_remove (priv->poke_id); - priv->poke_id = 0; + g_assert (!self->priv->modem_manager_1); + self->priv->modem_manager_1 = mm_manager_new_finish (res, &error); + if (!self->priv->modem_manager_1) { + 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_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); + } else { + gchar *name_owner; + + g_signal_connect (self->priv->modem_manager_1, + "notify::name-owner", + G_CALLBACK (modem_manager_1_name_owner_changed), + self); + g_signal_connect (self->priv->modem_manager_1, + "object-added", + G_CALLBACK (modem_object_added), + self); + g_signal_connect (self->priv->modem_manager_1, + "object-removed", + G_CALLBACK (modem_object_removed), + self); + + /* If there is no current owner right away, ensure we poke until we get + * one */ + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager_1)); + if (!name_owner) { + /* Setup timeout to wait for an owner */ + schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); + } else { + /* Available! */ + modem_manager_1_available (self); + g_free (name_owner); + } } - g_hash_table_foreach_remove (priv->modems, remove_one_modem, object); - g_hash_table_destroy (priv->modems); + /* Balance refcount */ + g_object_unref (self); +} + +static void +recreate_client (NMModemManager *self) +{ + g_assert (self->priv->dbus_connection); + + /* Re-create the GDBusObjectManagerClient so that we request again the owner + * for the well-known name. + * Note that we pass an extra reference always */ + g_clear_object (&self->priv->modem_manager_1); + mm_manager_new (self->priv->dbus_connection, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + NULL, + (GAsyncReadyCallback)manager_new_ready, + g_object_ref (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; - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = 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_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); + } else { + /* Got the bus, create new ModemManager client. */ + recreate_client (self); } - if (priv->dbus_mgr) { - g_object_unref (priv->dbus_mgr); - priv->dbus_mgr = NULL; + /* Balance refcount */ + g_object_unref (self); +} + +static gboolean +ensure_bus (NMModemManager *self) +{ + nm_log_dbg (LOGD_MB, "Requesting to (re)launch ModemManager..."); + + /* Clear poke ID */ + self->priv->modem_manager_1_poke_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, launch client re-creation */ + recreate_client (self); + + return FALSE; +} + +static void +schedule_modem_manager_1_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_poke_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + else + self->priv->modem_manager_1_poke_id = g_idle_add ((GSourceFunc)ensure_bus, self); +} + +#endif /* WITH_MODEM_MANAGER_1 */ + +/************************************************************************/ + +static void +nm_modem_manager_init (NMModemManager *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_MODEM_MANAGER, NMModemManagerPrivate); + + 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 +} + +static void +dispose (GObject *object) +{ + NMModemManager *self = NM_MODEM_MANAGER (object); + + /* ModemManager < 0.7 */ + clear_modem_manager_support (self); + +#if WITH_MODEM_MANAGER_1 + /* ModemManager >= 0.7 */ + clear_modem_manager_1_support (self); +#endif + + if (self->priv->modems) { + g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, object); + g_hash_table_destroy (self->priv->modems); } /* Chain up to the parent class */ diff --git a/src/modem-manager/nm-modem-manager.h b/src/modem-manager/nm-modem-manager.h index 56427baf..0c2b243b 100644 --- a/src/modem-manager/nm-modem-manager.h +++ b/src/modem-manager/nm-modem-manager.h @@ -33,18 +33,23 @@ #define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_MANAGER)) #define NM_MODEM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) -typedef struct { +typedef struct _NMModemManager NMModemManager; +typedef struct _NMModemManagerClass NMModemManagerClass; +typedef struct _NMModemManagerPrivate NMModemManagerPrivate; + +struct _NMModemManager { GObject parent; -} NMModemManager; + NMModemManagerPrivate *priv; +}; -typedef struct { +struct _NMModemManagerClass { GObjectClass parent; /* Signals */ void (*modem_added) (NMModemManager *manager, NMModem *modem, const char *driver); void (*modem_removed) (NMModemManager *manager, NMModem *modem); -} NMModemManagerClass; +}; GType nm_modem_manager_get_type (void); diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h index e805cb21..9fc8deed 100644 --- a/src/modem-manager/nm-modem-types.h +++ b/src/modem-manager/nm-modem-types.h @@ -21,37 +21,32 @@ #ifndef NM_MODEM_TYPES_H #define NM_MODEM_TYPES_H -#define MM_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_DBUS_PATH "/org/freedesktop/ModemManager" -#define MM_DBUS_INTERFACE "org.freedesktop.ModemManager" -#define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" -#define MM_DBUS_INTERFACE_MODEM_SIMPLE "org.freedesktop.ModemManager.Modem.Simple" -#define MM_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma" - -#define MM_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" -#define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" +#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_MODEM_TYPE_UNKNOWN 0 #define MM_MODEM_TYPE_GSM 1 #define MM_MODEM_TYPE_CDMA 2 -#define MM_MODEM_IP_METHOD_PPP 0 -#define MM_MODEM_IP_METHOD_STATIC 1 -#define MM_MODEM_IP_METHOD_DHCP 2 - /* Errors */ -#define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed" -#define MM_SERIAL_SEND_FAILED MM_DBUS_INTERFACE_MODEM ".SerialSendFailed" -#define MM_SERIAL_RESPONSE_TIMEOUT MM_DBUS_INTERFACE_MODEM ".SerialResponseTimeout" +#define MM_SERIAL_OPEN_FAILED MM_OLD_DBUS_INTERFACE_MODEM ".SerialOpenFailed" +#define MM_SERIAL_SEND_FAILED MM_OLD_DBUS_INTERFACE_MODEM ".SerialSendFailed" +#define MM_SERIAL_RESPONSE_TIMEOUT MM_OLD_DBUS_INTERFACE_MODEM ".SerialResponseTimeout" -#define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".General" -#define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_DBUS_INTERFACE_MODEM ".OperationNotSupported" +#define MM_MODEM_ERROR_GENERAL MM_OLD_DBUS_INTERFACE_MODEM ".General" +#define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_OLD_DBUS_INTERFACE_MODEM ".OperationNotSupported" -#define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_DBUS_INTERFACE_MODEM ".NoCarrier" -#define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_DBUS_INTERFACE_MODEM ".NoDialtone" -#define MM_MODEM_CONNECT_ERROR_BUSY MM_DBUS_INTERFACE_MODEM ".Busy" -#define MM_MODEM_CONNECT_ERROR_NO_ANSWER MM_DBUS_INTERFACE_MODEM ".NoAnswer" +#define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_OLD_DBUS_INTERFACE_MODEM ".NoCarrier" +#define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_OLD_DBUS_INTERFACE_MODEM ".NoDialtone" +#define MM_MODEM_CONNECT_ERROR_BUSY MM_OLD_DBUS_INTERFACE_MODEM ".Busy" +#define MM_MODEM_CONNECT_ERROR_NO_ANSWER MM_OLD_DBUS_INTERFACE_MODEM ".NoAnswer" #define MM_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index c43e5e16..2d24a3ea 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -38,35 +38,34 @@ G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT) enum { PROP_0, - PROP_DEVICE, - PROP_IFACE, + PROP_CONTROL_PORT, + PROP_DATA_PORT, PROP_PATH, + PROP_UID, PROP_IP_METHOD, PROP_IP_TIMEOUT, PROP_ENABLED, + PROP_CONNECTED, LAST_PROP }; typedef struct { - NMDBusManager *dbus_mgr; - DBusGProxy *proxy; - DBusGProxy *props_proxy; - + char *uid; char *path; - NMPPPManager *ppp_manager; + char *control_port; + char *data_port; guint32 ip_method; - char *device; - char *iface; + + NMPPPManager *ppp_manager; NMActRequest *act_request; guint32 secrets_tries; guint32 secrets_id; - DBusGProxyCall *call; - gboolean mm_enabled; guint32 mm_ip_timeout; + gboolean mm_connected; /* PPP stats */ guint32 in_bytes; @@ -86,47 +85,31 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static void -update_mm_enabled (NMModem *self, gboolean new_enabled) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - - if (priv->mm_enabled != new_enabled) { - priv->mm_enabled = new_enabled; - g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED); - } -} +/*****************************************************************************/ +/* Get/Set enabled/connected */ gboolean nm_modem_get_mm_enabled (NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), TRUE); - return NM_MODEM_GET_PRIVATE (self)->mm_enabled; } -DBusGProxy * -nm_modem_get_proxy (NMModem *self, - const char *interface) +void +nm_modem_set_mm_enabled (NMModem *self, + gboolean enabled) { + NMModemPrivate *priv; - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - const char *current_iface; - - g_return_val_if_fail (NM_IS_MODEM (self), NULL); - - /* Default to the default interface. */ - if (interface == NULL) - interface = MM_DBUS_INTERFACE_MODEM; - - if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES)) - return priv->props_proxy; + priv = NM_MODEM_GET_PRIVATE (self); - current_iface = dbus_g_proxy_get_interface (priv->proxy); - if (!current_iface || strcmp (current_iface, interface)) - dbus_g_proxy_set_interface (priv->proxy, interface); + if (priv->mm_enabled != enabled) + NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); +} - return priv->proxy; +gboolean +nm_modem_get_mm_connected (NMModem *self) +{ + return NM_MODEM_GET_PRIVATE (self)->mm_connected; } /*****************************************************************************/ @@ -154,6 +137,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, 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 */ @@ -161,6 +145,11 @@ ppp_ip4_config (NMPPPManager *ppp_manager, guint32 good_dns2 = htonl (0x04020202); /* GTE nameserver */ gboolean dns_workaround = FALSE; + /* Notify about the new data port to use */ + g_free (priv->data_port); + priv->data_port = g_strdup (iface); + g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + /* 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. * Apparently fixed in ppp-2.4.5 but we've had some reports that this is @@ -197,7 +186,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, nm_ip4_config_add_nameserver (config, good_dns2); } - g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, iface, config, NULL); + g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, config, NULL); } static void @@ -250,17 +239,17 @@ ppp_stage3_ip4_config_start (NMModem *self, ip_timeout = priv->mm_ip_timeout; } - priv->ppp_manager = nm_ppp_manager_new (priv->iface); + priv->ppp_manager = nm_ppp_manager_new (priv->data_port); if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) { g_signal_connect (priv->ppp_manager, "state-changed", - G_CALLBACK (ppp_state_changed), - self); + G_CALLBACK (ppp_state_changed), + self); g_signal_connect (priv->ppp_manager, "ip4-config", - G_CALLBACK (ppp_ip4_config), - self); + G_CALLBACK (ppp_ip4_config), + self); g_signal_connect (priv->ppp_manager, "stats", - G_CALLBACK (ppp_stats), - self); + G_CALLBACK (ppp_stats), + self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { @@ -280,103 +269,6 @@ ppp_stage3_ip4_config_start (NMModem *self, } /*****************************************************************************/ -/* IP method static */ - -static char addr_to_string_buf[INET6_ADDRSTRLEN + 1]; - -static const char * -ip_address_to_string (guint32 numeric) -{ - struct in_addr temp_addr; - - memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf)); - temp_addr.s_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.s_addr)); - return NULL; - } -} - -static void -static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_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)) { - NMIP4Address *addr; - int i; - - config = nm_ip4_config_new (); - - addr = nm_ip4_address_new (); - - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", priv->iface); - - /* IP address */ - nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0))); - nm_ip4_address_set_prefix (addr, 32); - nm_ip4_config_take_address (config, addr); - - nm_log_info (LOGD_MB, " address %s/%d", - ip_address_to_string (nm_ip4_address_get_address (addr)), - nm_ip4_address_get_prefix (addr)); - - /* 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 (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, error); - g_clear_error (&error); -} - -static NMActStageReturn -static_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) -{ - NMModemPrivate *priv; - - 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); - - priv = NM_MODEM_GET_PRIVATE (self); - - priv->call = dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM), - "GetIP4Config", static_stage3_done, - self, NULL, - G_TYPE_INVALID); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *self, @@ -405,7 +297,7 @@ nm_modem_stage3_ip4_config_start (NMModem *self, ret = ppp_stage3_ip4_config_start (self, req, reason); break; case MM_MODEM_IP_METHOD_STATIC: - ret = static_stage3_ip4_config_start (self, req, reason); + ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; case MM_MODEM_IP_METHOD_DHCP: ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); @@ -419,6 +311,29 @@ nm_modem_stage3_ip4_config_start (NMModem *self, return ret; } +void +nm_modem_ip4_pre_commit (NMModem *modem, + NMDevice *device, + NMIP4Config *config) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (modem); + + /* If the modem has an ethernet-type data interface (ie, not PPP and thus + * 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) { + NMIP4Address *addr = nm_ip4_config_get_address (config, 0); + + g_assert (addr); + if (nm_ip4_address_get_prefix (addr) == 32) + nm_system_iface_set_arp (nm_device_get_ip_ifindex (device), FALSE); + } +} + +/*****************************************************************************/ + NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, NMDevice *device, @@ -430,6 +345,8 @@ nm_modem_stage3_ip6_config_start (NMModem *self, return NM_ACT_STAGE_RETURN_POSTPONE; } +/*****************************************************************************/ + static void cancel_get_secrets (NMModem *self) { @@ -486,12 +403,14 @@ nm_modem_get_secrets (NMModem *self, return !!(priv->secrets_id); } +/*****************************************************************************/ + static NMActStageReturn -real_act_stage1_prepare (NMModem *modem, - NMActRequest *req, - GPtrArray **out_hints, - const char **out_setting_name, - NMDeviceStateReason *reason) +act_stage1_prepare (NMModem *modem, + NMActRequest *req, + GPtrArray **out_hints, + const char **out_setting_name, + NMDeviceStateReason *reason) { *reason = NM_DEVICE_STATE_REASON_UNKNOWN; return NM_ACT_STAGE_RETURN_FAILURE; @@ -541,6 +460,8 @@ nm_modem_act_stage1_prepare (NMModem *self, return ret; } +/*****************************************************************************/ + NMActStageReturn nm_modem_act_stage2_config (NMModem *self, NMActRequest *req, @@ -556,6 +477,8 @@ nm_modem_act_stage2_config (NMModem *self, return NM_ACT_STAGE_RETURN_SUCCESS; } +/*****************************************************************************/ + NMConnection * nm_modem_get_best_auto_connection (NMModem *self, GSList *connections, @@ -566,6 +489,8 @@ nm_modem_get_best_auto_connection (NMModem *self, return NULL; } +/*****************************************************************************/ + gboolean nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection, @@ -576,6 +501,8 @@ nm_modem_check_connection_compatible (NMModem *self, return FALSE; } +/*****************************************************************************/ + gboolean nm_modem_complete_connection (NMModem *self, NMConnection *connection, @@ -587,8 +514,10 @@ nm_modem_complete_connection (NMModem *self, return FALSE; } +/*****************************************************************************/ + static void -real_deactivate (NMModem *self, NMDevice *device) +deactivate (NMModem *self, NMDevice *device) { NMModemPrivate *priv; int ifindex; @@ -608,11 +537,6 @@ real_deactivate (NMModem *self, NMDevice *device) priv->act_request = NULL; } - if (priv->call) { - dbus_g_proxy_cancel_call (priv->proxy, priv->call); - priv->call = NULL; - } - priv->in_bytes = priv->out_bytes = 0; if (priv->ppp_manager) { @@ -639,24 +563,15 @@ real_deactivate (NMModem *self, NMDevice *device) } } +/*****************************************************************************/ + void nm_modem_deactivate (NMModem *self, NMDevice *device) { NM_MODEM_GET_CLASS (self)->deactivate (self, device); } -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)"); - } -} +/*****************************************************************************/ void nm_modem_device_state_changed (NMModem *self, @@ -697,12 +612,7 @@ nm_modem_device_state_changed (NMModem *self, /* Don't bother warning on FAILED since the modem is already gone */ if (new_state == NM_DEVICE_STATE_FAILED) warn = FALSE; - dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM), - "Disconnect", - disconnect_done, - GUINT_TO_POINTER (warn), - NULL, - G_TYPE_INVALID); + NM_MODEM_GET_CLASS (self)->disconnect (self, warn); } break; default: @@ -710,29 +620,15 @@ nm_modem_device_state_changed (NMModem *self, } } -gboolean -nm_modem_hw_is_up (NMModem *self, NMDevice *device) -{ - int ifindex = nm_device_get_ip_ifindex (device); - - return ifindex > 0 ? nm_system_iface_is_up (ifindex) : TRUE; -} - -gboolean -nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware) -{ - int ifindex = nm_device_get_ip_ifindex (device); - - return ifindex > 0 ? nm_system_iface_set_up (ifindex, TRUE, no_firmware) : TRUE; -} +/*****************************************************************************/ const char * -nm_modem_get_iface (NMModem *self) +nm_modem_get_uid (NMModem *self) { g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_MODEM (self), NULL); - return NM_MODEM_GET_PRIVATE (self)->iface; + return NM_MODEM_GET_PRIVATE (self)->uid; } const char * @@ -744,109 +640,22 @@ nm_modem_get_path (NMModem *self) return NM_MODEM_GET_PRIVATE (self)->path; } -static void -get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModem *self = NM_MODEM (user_data); - GError *error = NULL; - GValue value = { 0, }; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - return; - } - - if (G_VALUE_HOLDS_BOOLEAN (&value)) { - update_mm_enabled (self, g_value_get_boolean (&value)); - } else - nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type"); - - g_value_unset (&value); -} - -static void -query_mm_enabled (NMModem *self) -{ - dbus_g_proxy_begin_call (NM_MODEM_GET_PRIVATE (self)->props_proxy, - "Get", get_mm_enabled_done, - self, NULL, - G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, - G_TYPE_STRING, "Enabled", - G_TYPE_INVALID); -} - -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)"); - } - - /* Update enabled/disabled state again */ - query_mm_enabled (NM_MODEM (user_data)); -} - -void -nm_modem_set_mm_enabled (NMModem *self, gboolean enabled) +const char * +nm_modem_get_control_port (NMModem *self) { - NMModemPrivate *priv; - - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_MODEM (self)); - - priv = NM_MODEM_GET_PRIVATE (self); - - /* FIXME: For now this just toggles the ModemManager enabled state. In the - * future we want to tie this into rfkill state instead so that the user can - * toggle rfkill status of the WWAN modem. - */ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_MODEM (self), NULL); - if (priv->mm_enabled != enabled) { - DBusGProxy *proxy; - - proxy = nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM); - dbus_g_proxy_begin_call (proxy, - "Enable", set_mm_enabled_done, - self, NULL, - G_TYPE_BOOLEAN, enabled, - G_TYPE_INVALID); - /* If we are disabling the modem, stop saying that it's enabled. */ - if (!enabled) - update_mm_enabled (self, enabled); - } + return NM_MODEM_GET_PRIVATE (self)->control_port; } -static void -modem_properties_changed (DBusGProxy *proxy, - const char *interface, - GHashTable *props, - gpointer user_data) +const char * +nm_modem_get_data_port (NMModem *self) { - NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - GValue *value; - - if (strcmp (interface, MM_DBUS_INTERFACE_MODEM)) - return; - - value = g_hash_table_lookup (props, "Enabled"); - if (value && G_VALUE_HOLDS_BOOLEAN (value)) { - update_mm_enabled (self, g_value_get_boolean (value)); - } + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_MODEM (self), NULL); - value = g_hash_table_lookup (props, "IpMethod"); - if (value && G_VALUE_HOLDS_UINT (value)) { - priv->ip_method = g_value_get_uint (value); - g_object_notify (G_OBJECT (self), NM_MODEM_IP_METHOD); - } + return NM_MODEM_GET_PRIVATE (self)->data_port; } /*****************************************************************************/ @@ -854,9 +663,6 @@ modem_properties_changed (DBusGProxy *proxy, static void nm_modem_init (NMModem *self) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - - priv->dbus_mgr = nm_dbus_manager_get (); } static GObject* @@ -866,23 +672,17 @@ constructor (GType type, { GObject *object; NMModemPrivate *priv; - DBusGConnection *bus; object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type, - n_construct_params, - construct_params); + n_construct_params, + construct_params); if (!object) return NULL; priv = NM_MODEM_GET_PRIVATE (object); - if (!priv->device) { - nm_log_err (LOGD_HW, "modem parent device not provided"); - goto err; - } - - if (!priv->device) { - nm_log_err (LOGD_HW, "modem command interface not provided"); + if (!priv->data_port && !priv->control_port) { + nm_log_err (LOGD_HW, "neither modem command nor data interface provided"); goto err; } @@ -891,30 +691,6 @@ constructor (GType type, goto err; } - bus = nm_dbus_manager_get_connection (priv->dbus_mgr); - priv->proxy = dbus_g_proxy_new_for_name (bus, - MM_DBUS_SERVICE, - priv->path, - MM_DBUS_INTERFACE_MODEM); - - priv->props_proxy = dbus_g_proxy_new_for_name (bus, - MM_DBUS_SERVICE, - priv->path, - DBUS_INTERFACE_PROPERTIES); - dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED, - 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); - - query_mm_enabled (NM_MODEM (object)); - return object; err: @@ -924,7 +700,7 @@ constructor (GType type, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); @@ -932,11 +708,14 @@ get_property (GObject *object, guint prop_id, case PROP_PATH: g_value_set_string (value, priv->path); break; - case PROP_DEVICE: - g_value_set_string (value, priv->device); + case PROP_CONTROL_PORT: + g_value_set_string (value, priv->control_port); break; - case PROP_IFACE: - g_value_set_string (value, priv->iface); + case PROP_DATA_PORT: + g_value_set_string (value, priv->data_port); + break; + case PROP_UID: + g_value_set_string (value, priv->uid); break; case PROP_IP_METHOD: g_value_set_uint (value, priv->ip_method); @@ -947,16 +726,18 @@ get_property (GObject *object, guint prop_id, case PROP_ENABLED: g_value_set_boolean (value, priv->mm_enabled); break; + case PROP_CONNECTED: + g_value_set_boolean (value, priv->mm_connected); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } - } static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); @@ -965,22 +746,27 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->path = g_value_dup_string (value); break; - case PROP_DEVICE: - /* Construct only */ - priv->device = g_value_dup_string (value); + case PROP_CONTROL_PORT: + priv->control_port = g_value_dup_string (value); + break; + case PROP_DATA_PORT: + priv->data_port = g_value_dup_string (value); break; - case PROP_IFACE: + case PROP_UID: /* Construct only */ - priv->iface = g_value_dup_string (value); + priv->uid = g_value_dup_string (value); break; case PROP_IP_METHOD: - /* Construct only */ priv->ip_method = g_value_get_uint (value); break; case PROP_IP_TIMEOUT: priv->mm_ip_timeout = g_value_get_uint (value); break; case PROP_ENABLED: + priv->mm_enabled = g_value_get_boolean (value); + break; + case PROP_CONNECTED: + priv->mm_connected = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -989,24 +775,27 @@ set_property (GObject *object, guint prop_id, } static void -finalize (GObject *object) +dispose (GObject *object) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); - if (priv->act_request) + if (priv->act_request) { g_object_unref (priv->act_request); + priv->act_request = NULL; + } - if (priv->proxy) - g_object_unref (priv->proxy); - - if (priv->props_proxy) - g_object_unref (priv->props_proxy); + G_OBJECT_CLASS (nm_modem_parent_class)->dispose (object); +} - g_object_unref (priv->dbus_mgr); +static void +finalize (GObject *object) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); - g_free (priv->iface); + g_free (priv->uid); g_free (priv->path); - g_free (priv->device); + g_free (priv->control_port); + g_free (priv->data_port); G_OBJECT_CLASS (nm_modem_parent_class)->finalize (object); } @@ -1022,45 +811,55 @@ nm_modem_class_init (NMModemClass *klass) object_class->constructor = constructor; object_class->set_property = set_property; object_class->get_property = get_property; + object_class->dispose = dispose; object_class->finalize = finalize; - klass->act_stage1_prepare = real_act_stage1_prepare; - klass->deactivate = real_deactivate; + klass->act_stage1_prepare = act_stage1_prepare; + klass->deactivate = deactivate; /* Properties */ + + g_object_class_install_property + (object_class, PROP_UID, + g_param_spec_string (NM_MODEM_UID, + "UID", + "Modem unique ID", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_PATH, g_param_spec_string (NM_MODEM_PATH, - "DBus path", - "DBus path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + "DBus path", + "DBus path", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property - (object_class, PROP_DEVICE, - g_param_spec_string (NM_MODEM_DEVICE, - "Device", - "Master modem parent device", + (object_class, PROP_CONTROL_PORT, + g_param_spec_string (NM_MODEM_CONTROL_PORT, + "Control port", + "The port controlling the modem", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property - (object_class, PROP_IFACE, - g_param_spec_string (NM_MODEM_IFACE, - "Interface", - "Modem command interface", + (object_class, PROP_DATA_PORT, + g_param_spec_string (NM_MODEM_DATA_PORT, + "Data port", + "The port to connect to", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); 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 | G_PARAM_CONSTRUCT_ONLY)); + "IP method", + "IP method", + MM_MODEM_IP_METHOD_PPP, + MM_MODEM_IP_METHOD_DHCP, + MM_MODEM_IP_METHOD_PPP, + G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_IP_TIMEOUT, @@ -1068,7 +867,7 @@ nm_modem_class_init (NMModemClass *klass) "IP timeout", "IP timeout", 0, 360, 20, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_ENABLED, @@ -1076,62 +875,70 @@ nm_modem_class_init (NMModemClass *klass) "Enabled", "Enabled", TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_CONNECTED, + g_param_spec_boolean (NM_MODEM_CONNECTED, + "Connected", + "Connected", + TRUE, + G_PARAM_READWRITE)); /* Signals */ + signals[PPP_STATS] = g_signal_new ("ppp-stats", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, ppp_stats), - NULL, NULL, - _nm_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ppp_stats), + NULL, NULL, + _nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); signals[PPP_FAILED] = g_signal_new ("ppp-failed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, ppp_failed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ppp_failed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals[IP4_CONFIG_RESULT] = g_signal_new (NM_MODEM_IP4_CONFIG_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, ip4_config_result), - NULL, NULL, - _nm_marshal_VOID__STRING_OBJECT_POINTER, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_OBJECT, G_TYPE_POINTER); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ip4_config_result), + NULL, NULL, + _nm_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); signals[PREPARE_RESULT] = g_signal_new (NM_MODEM_PREPARE_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, prepare_result), - NULL, NULL, - _nm_marshal_VOID__BOOLEAN_UINT, - G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, prepare_result), + NULL, NULL, + _nm_marshal_VOID__BOOLEAN_UINT, + G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT); signals[AUTH_REQUESTED] = g_signal_new (NM_MODEM_AUTH_REQUESTED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, auth_requested), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, auth_requested), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); signals[AUTH_RESULT] = g_signal_new (NM_MODEM_AUTH_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, auth_result), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, auth_result), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); } - diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h index 8fe52bc0..d01aaf2c 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/modem-manager/nm-modem.h @@ -29,19 +29,21 @@ 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)) -#define NM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM)) -#define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM)) -#define NM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM, NMModemClass)) - -#define NM_MODEM_PATH "path" -#define NM_MODEM_DEVICE "device" -#define NM_MODEM_IFACE "iface" -#define NM_MODEM_IP_METHOD "ip-method" -#define NM_MODEM_IP_TIMEOUT "ip-timeout" -#define NM_MODEM_ENABLED "enabled" +#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)) +#define NM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM)) +#define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM)) +#define NM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM, NMModemClass)) + +#define NM_MODEM_UID "uid" +#define NM_MODEM_PATH "path" +#define NM_MODEM_CONTROL_PORT "control-port" +#define NM_MODEM_DATA_PORT "data-port" +#define NM_MODEM_IP_METHOD "ip-method" +#define NM_MODEM_IP_TIMEOUT "ip-timeout" +#define NM_MODEM_ENABLED "enabled" +#define NM_MODEM_CONNECTED "connected" #define NM_MODEM_PPP_STATS "ppp-stats" #define NM_MODEM_PPP_FAILED "ppp-failed" @@ -50,6 +52,10 @@ G_BEGIN_DECLS #define NM_MODEM_AUTH_REQUESTED "auth-requested" #define NM_MODEM_AUTH_RESULT "auth-result" +#define MM_MODEM_IP_METHOD_PPP 0 +#define MM_MODEM_IP_METHOD_STATIC 1 +#define MM_MODEM_IP_METHOD_DHCP 2 + typedef struct { GObject parent; } NMModem; @@ -83,6 +89,14 @@ typedef struct { const char **out_setting_name, NMDeviceStateReason *reason); + NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self, + NMActRequest *req, + NMDeviceStateReason *reason); + + void (*set_mm_enabled) (NMModem *self, gboolean enabled); + + void (*disconnect) (NMModem *self, gboolean warn); + void (*deactivate) (NMModem *self, NMDevice *device); /* Signals */ @@ -90,7 +104,7 @@ typedef struct { void (*ppp_failed) (NMModem *self, NMDeviceStateReason reason); void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason); - void (*ip4_config_result) (NMModem *self, const char *iface, NMIP4Config *config, GError *error); + void (*ip4_config_result) (NMModem *self, NMIP4Config *config, GError *error); void (*auth_requested) (NMModem *self); void (*auth_result) (NMModem *self, GError *error); @@ -98,11 +112,10 @@ typedef struct { GType nm_modem_get_type (void); -/* Protected */ - -DBusGProxy * nm_modem_get_proxy (NMModem *modem, const char *interface); -const char * nm_modem_get_iface (NMModem *modem); -const char * nm_modem_get_path (NMModem *modem); +const char *nm_modem_get_path (NMModem *modem); +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); NMConnection *nm_modem_get_best_auto_connection (NMModem *self, GSList *connections, @@ -135,6 +148,8 @@ NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, NMDeviceClass *device_class, NMDeviceStateReason *reason); +void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config); + gboolean nm_modem_get_secrets (NMModem *modem, const char *setting_name, gboolean request_new, @@ -147,14 +162,12 @@ void nm_modem_device_state_changed (NMModem *modem, NMDeviceState old_state, NMDeviceStateReason reason); -gboolean nm_modem_hw_is_up (NMModem *modem, NMDevice *device); - -gboolean nm_modem_hw_bring_up (NMModem *modem, NMDevice *device, gboolean *no_firmware); - gboolean nm_modem_get_mm_enabled (NMModem *self); void nm_modem_set_mm_enabled (NMModem *self, gboolean enabled); +gboolean nm_modem_get_mm_connected (NMModem *self); + G_END_DECLS #endif /* NM_MODEM_H */ |