Arman Uguray <armansito@chromium.org>
Vinicius Costa Gomes <vcgomes@gmail.com>
Marcus Folkesson <marcus.folkesson@gmail.com>
+ Michael Olbrich <m.olbrich@pengutronix.de>
+ Harish Jenny K N <harish_kandiga@mentor.com>
+ Jaakko Hannikainen <jaakko.hannikainen@intel.com>
+ Adam Moore <adam.moore@savantsystems.com>
+ Marko Sulejic <marko.sulejic@hale.at>
+ Marcin Niestrój <m.niestroj@grinn-global.com>
+ Frank Stevers <f.stevers@ultimaker.com>
+ Laurent Vaudoit <laurent.vaudoit@gmail.com>
+ Abtin Keshavarzian <abtink@nestlabs.com>
+ Naveen Singh <naveensingh0977@gmail.com>
+ Mylène Josserand <josserand.mylene@gmail.com>
+ John Ernberg <john.ernberg@actia.se>
+ Niraj Kumar Goit <niraj.g@samsung.com>
+ Wu Zheng <wu.zheng@intel.com>
+ Milind Ramesh Murhekar <m.murhekar@samsung.com>
+ Nishant Chaprana <n.chaprana@samsung.com>
+ Hendrik Donner <hendrik@rennod.org>
+ Ravi Prasad RK <ravi.rk@samsung.com>
+ Krisztian Litkey <kli@iki.fi>
+ Jose Blanquicet <blanquicet@gmail.com>
+ Frédéric Dalleau <frederic.dalleau@collabora.co.uk>
+ Yusuke Nakamura <yusuke1653381@gmail.com>
+ Maxime Chevallier <maxime.chevallier@smile.fr>
+ Sam Nazarko <email@samnazarko.co.uk>
+ Kristian Klausen <klausenbusk@hotmail.com>
+ Måns Rullgård <mans@mansr.com>
+ Michele Dionisio <michele.dionisio@gmail.com>
+ Alexander Kochetkov <al.kochet@gmail.com>
+ Ioan-Adrian Ratiu <adrian.ratiu@ni.com>
+ Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+ Bernhard Lichtinger <bernhard.lichtinger@lrz.de>
+ Andreas Smas <andreas@lonelycoder.com>
+ Ingo Albrecht <randomice@quantentunnel.de>
+ Scott Valentine <svalentine@ikayzo.com>
+ Craig McQueen <craig.mcqueen@innerrange.com>
+ Tobias Klauser <tklauser@distanz.ch>
+ Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+ Bjoern Thorwirth <external.bjoern.thorwirth@de.bosch.com>
+ Maxin B. John <maxin.john@intel.com>
+ Heghedus Razvan <razvan.heghedus@ni.com>
+ Guillaume Deroire <guillaume.deroire@hach.com>
include/dbus.h include/option.h \
include/provider.h include/vpn-dbus.h \
include/utsname.h include/timeserver.h include/proxy.h \
- include/technology.h include/setting.h \
- include/backtrace.h
+ include/technology.h include/setting.h
local_headers = $(foreach file,$(include_HEADERS) $(nodist_include_HEADERS) \
$(noinst_HEADERS), include/connman/$(notdir $(file)))
gweb_sources += gweb/giognutls.h gweb/gionotls.c
endif
-if BACKTRACE
-backtrace_sources = src/backtrace.c
-endif
-
shared_sources = src/shared/util.h src/shared/util.c \
src/shared/netlink.h src/shared/netlink.c
dbusconf_DATA += vpn/connman-vpn-dbus.conf
dbusservicedir = @DBUS_DATADIR@
dbusservice_DATA = vpn/net.connman.vpn.service
-endif
if SYSTEMD
systemdunitdir = @SYSTEMD_UNITDIR@
-systemdunit_DATA = src/connman.service src/connman-wait-online.service
+systemdunit_DATA = src/connman.service vpn/connman-vpn.service
-tmpfilesdir = @SYSTEMD_TMPFILESDIR@
-nodist_tmpfiles_DATA = scripts/connman_resolvconf.conf
-
-if VPN
-systemdunit_DATA += vpn/connman-vpn.service
-endif
-endif
endif
service_files_sources = src/connman.service.in src/net.connman.service.in \
- vpn/connman-vpn.service.in \
- vpn/net.connman.vpn.service.in \
- src/connman-wait-online.service.in
+ vpn/net.connman.vpn.service.in vpn/connman-vpn.service.in
service_files = src/connman.service src/net.connman.service \
- vpn/connman-vpn.service \
- vpn/net.connman.vpn.service \
- src/connman-wait-online.service
+ vpn/net.connman.vpn.service vpn/connman-vpn.service
+
+else
+
+if SYSTEMD
+systemdunitdir = @SYSTEMD_UNITDIR@
+systemdunit_DATA = src/connman.service
+
+endif
+
+service_files_sources = src/connman.service.in src/net.connman.service.in
+service_files = src/connman.service src/net.connman.service
+endif
+endif
plugin_LTLIBRARIES =
builtin_cflags =
noinst_PROGRAMS =
+if TIZEN_EXT
+bin_PROGRAMS = src/connmand
+else
bin_PROGRAMS =
+endif
unit_objects =
MANUAL_PAGES =
- sbin_PROGRAMS = src/connmand
+if TIZEN_EXT
+sbin_PROGRAMS =
+else
+ sbin_PROGRAMS = src/connmand src/connmand-wait-online
+endif
-src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) $(backtrace_sources) \
+src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) \
$(builtin_sources) $(shared_sources) src/connman.ver \
src/main.c src/connman.h src/log.c \
src/error.c src/plugin.c src/task.c \
src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/ntp.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
- src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
+ src/stats.c src/dnsproxy.c src/6to4.c \
src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
- src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \
+ src/inotify.c src/ipv6pd.c src/peer.c \
src/peer_service.c src/machine.c src/util.c
src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
- @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ @LIBSYSTEMD_LIBS@ \
- @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
++ @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ @LIBSYSTEMD_LIBS@ \
-lresolv -ldl -lrt
-src_connmand_LDFLAGS = -Wl,--export-dynamic \
+src_connmand_LDFLAGS = -Wl,--export-dynamic -pie \
-Wl,--version-script=$(srcdir)/src/connman.ver
+ src_connmand_wait_online_SOURCES = src/connmand-wait-online.c
+
+ src_connmand_wait_online_LDADD = gdbus/libgdbus-internal.la \
+ @GLIB_LIBS@ @DBUS_LIBS@
+
+ if XTABLES
+ src_connmand_SOURCES += src/iptables.c src/firewall-iptables.c
+ src_connmand_LDADD += @XTABLES_LIBS@
+ endif
+
+ if NFTABLES
+ src_connmand_SOURCES += src/firewall-nftables.c
+ src_connmand_LDADD += @NFTABLES_LIBS@
+ endif
+
if VPN
vpn_plugin_LTLIBRARIES =
builtin_vpn_libadd =
builtin_vpn_cflags =
+if TIZEN_EXT
+bin_PROGRAMS += vpn/connman-vpnd
+else
sbin_PROGRAMS += vpn/connman-vpnd
+endif
-vpn_connman_vpnd_SOURCES = $(builtin_vpn_sources) $(backtrace_sources) \
+vpn_connman_vpnd_SOURCES = $(gdhcp_sources) $(builtin_vpn_sources) \
$(gweb_sources) vpn/vpn.ver vpn/main.c vpn/vpn.h \
- src/log.c src/error.c src/plugin.c src/task.c \
vpn/vpn-manager.c vpn/vpn-provider.c \
vpn/vpn-provider.h vpn/vpn-rtnl.h \
vpn/vpn-ipconfig.c src/inet.c vpn/vpn-rtnl.c \
- src/dbus.c src/storage.c src/ipaddress.c src/agent.c \
- vpn/vpn-agent.c vpn/vpn-agent.h src/inotify.c \
+ src/log.c src/error.c src/plugin.c src/task.c \
+ src/device.c src/network.c src/connection.c \
+ src/manager.c src/service.c \
+ src/clock.c src/timezone.c src/agent-connman.c \
+ src/agent.c src/notifier.c src/provider.c \
+ src/resolver.c src/ipconfig.c src/detect.c \
+ src/dhcp.c src/dhcpv6.c src/rtnl.c src/proxy.c \
+ src/utsname.c src/timeserver.c src/rfkill.c \
+ src/storage.c src/dbus.c src/config.c \
+ src/technology.c src/counter.c src/ntp.c \
+ src/session.c src/tethering.c src/wpad.c src/wispr.c \
+ src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
+ src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
- src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \
++ src/inotify.c src/firewall-iptables.c src/ipv6pd.c src/peer.c \
+ src/peer_service.c src/machine.c src/util.c \
+ vpn/vpn-agent.c vpn/vpn-agent.h \
vpn/vpn-config.c
vpn_connman_vpnd_LDADD = gdbus/libgdbus-internal.la $(builtin_vpn_libadd) \
- @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
+ @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ \
+ @LIBSYSTEMD_LIBS@ \
-lresolv -ldl
vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \
-Wl,--version-script=$(srcdir)/vpn/vpn.ver
endif
-BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) \
- scripts/connman scripts/connman_resolvconf.conf
+BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) scripts/connman
if VPN
BUILT_SOURCES += vpn/builtin.h
CLEANFILES = src/connman.conf $(BUILT_SOURCES) $(service_files)
- statedir = $(localstatedir)/run/connman
- vpn_statedir = $(localstatedir)/run/connman-vpn
+ statedir = $(runstatedir)/connman
+ vpn_statedir = $(runstatedir)/connman-vpn
if VPN
vpn_plugindir = $(libdir)/connman/plugins-vpn
endif
endif
- AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ @LIBSYSTEMD_CFLAGS@\
-AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
++AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @LIBSYSTEMD_CFLAGS@\
@GNUTLS_CFLAGS@ $(builtin_cflags) \
-DCONNMAN_PLUGIN_BUILTIN \
-DSTATEDIR=\""$(statedir)"\" \
-DSCRIPTDIR=\""$(build_scriptdir)"\" \
-DSTORAGEDIR=\""$(storagedir)\"" \
-DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \
- -DCONFIGDIR=\""$(configdir)\""
+ -DCONFIGDIR=\""$(configdir)\"" \
+ -fPIE
if VPN
AM_CPPFLAGS = -I$(builddir)/include -I$(srcdir)/gdbus
AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
endif
- src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
+ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
@GNUTLS_CFLAGS@ $(builtin_cflags) \
-DCONNMAN_PLUGIN_BUILTIN \
-DSTATEDIR=\""$(statedir)"\" \
$(service_files_sources) scripts/connman.in
if VPN
-vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
+vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
$(builtin_vpn_cflags) \
-DCONNMAN_PLUGIN_BUILTIN \
-DVPN_STATEDIR=\""$(vpn_statedir)"\" \
endif
+ if XTABLES
+ AM_CFLAGS += @XTABLES_CFLAGS@
+ src_connmand_CFLAGS += @XTABLES_CFLAGS@
+ endif
+
+ if NFTABLES
+ AM_CFLAGS += @NFTABLES_CFLAGS@
+ src_connmand_CFLAGS += @NFTABLES_CFLAGS@
+ endif
+
EXTRA_DIST += vpn/vpn-dbus.conf vpn/vpn-polkit.conf
script_DATA =
if CLIENT
bin_PROGRAMS += client/connmanctl
- #MANUAL_PAGES = doc/connmanctl.1
-
client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \
client/services.h client/services.c \
client/commands.h client/commands.c \
client/main.c
client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ \
- -lreadline -ldl
+ -lreadline -ldl -lncurses
endif
noinst_PROGRAMS += unit/test-ippool
-unit_test_ippool_SOURCES = $(backtrace_sources) src/log.c src/dbus.c \
- src/error.c src/ippool.c unit/test-ippool.c
+unit_test_ippool_SOURCES = src/log.c src/dbus.c src/error.c \
+ src/ippool.c unit/test-ippool.c
unit_test_ippool_LDADD = gdbus/libgdbus-internal.la \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
tools/dhcp-test tools/dhcp-server-test \
tools/addr-test tools/web-test tools/resolv-test \
tools/dbus-test tools/polkit-test \
- tools/iptables-test tools/tap-test tools/wpad-test \
+ tools/tap-test tools/wpad-test \
tools/stats-tool tools/private-network-test \
- tools/session-test tools/iptables-unit \
+ tools/session-test \
tools/dnsproxy-test tools/netlink-test
tools_supplicant_test_SOURCES = tools/supplicant-test.c \
tools_polkit_test_LDADD = @DBUS_LIBS@
- tools_iptables_test_SOURCES = src/log.c src/iptables.c tools/iptables-test.c
- tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
-
tools_private_network_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
-tools_session_test_SOURCES = $(backtrace_sources) src/log.c src/dbus.c src/error.c \
+tools_session_test_SOURCES = src/log.c src/dbus.c src/error.c \
tools/session-test.c tools/session-utils.c tools/manager-api.c \
tools/session-api.c tools/session-test.h
tools_session_test_LDADD = gdbus/libgdbus-internal.la \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
+ if XTABLES
+ noinst_PROGRAMS += tools/iptables-test tools/iptables-unit
+
+ tools_iptables_test_SOURCES = $(backtrace_sources) src/log.c src/iptables.c \
+ tools/iptables-test.c
+ tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
+
tools_iptables_unit_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
-DIPTABLES_SAVE=\""${IPTABLES_SAVE}"\"
-tools_iptables_unit_SOURCES = $(backtrace_sources) src/log.c \
+tools_iptables_unit_SOURCES = src/log.c \
- src/iptables.c src/firewall.c src/nat.c tools/iptables-unit.c
+ src/iptables.c src/firewall-iptables.c src/nat.c \
+ tools/iptables-unit.c
tools_iptables_unit_LDADD = gdbus/libgdbus-internal.la \
@GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ -ldl
+ endif
tools_dnsproxy_test_SOURCES = tools/dnsproxy-test.c
tools_dnsproxy_test_LDADD = @GLIB_LIBS@
- tools_netlink_test_SOURCES =$(shared_sources) tools/netlink-test.c
+ tools_netlink_test_SOURCES = $(shared_sources) tools/netlink-test.c
tools_netlink_test_LDADD = @GLIB_LIBS@
endif
doc/vpn-config-format.txt \
doc/vpn-connection-api.txt \
doc/vpn-manager-api.txt doc/vpn-overview.txt \
- doc/session-policy-format.txt
+ doc/session-policy-format.txt \
+ doc/connmanctl.1.in doc/connman.conf.5.in \
+ doc/connman-service.config.5.in \
+ doc/connman-vpn.conf.5.in \
+ doc/connman-vpn-provider.config.5.in \
+ doc/connman.8.in doc/connman-vpn.8.in
EXTRA_DIST += src/main.conf \
- src/eduroam.config \
- scripts/connman_resolvconf.conf.in
+ src/eduroam.config
- #MANUAL_PAGES += doc/connman.8 doc/connman.conf.5
-MANUAL_PAGES += doc/connmanctl.1 doc/connman.conf.5 \
- doc/connman-service.config.5 doc/connman-vpn.conf.5 \
- doc/connman-vpn-provider.config.5 \
- doc/connman.8 doc/connman-vpn.8
++#MANUAL_PAGES += doc/connmanctl.1 doc/connman.conf.5 \
++# doc/connman-service.config.5 doc/connman-vpn.conf.5 \
++# doc/connman-vpn-provider.config.5 \
++# doc/connman.8 doc/connman-vpn.8
- dist_man_MANS = $(MANUAL_PAGES)
+ nodist_man_MANS = $(MANUAL_PAGES)
pkgconfigdir = $(libdir)/pkgconfig
--enable-hh2serial-gps \
--enable-openconnect \
--enable-openvpn \
+ --enable-ipsec \
--enable-vpnc \
--enable-session-policy-local \
--enable-nmcompat \
src/builtin.h: src/genbuiltin $(builtin_sources)
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
vpn/builtin.h: src/genbuiltin $(builtin_vpn_sources)
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_vpn_modules) > $@
src/connman.conf: src/connman-dbus.conf src/connman-polkit.conf
else
$(AM_V_GEN)cp $(srcdir)/vpn/vpn-dbus.conf $@
endif
+ CLEANFILES += vpn/connman-vpn-dbus.conf
endif
if SELINUX
do_subst = $(AM_V_GEN)$(SED) \
-e 's,[@]prefix[@],$(prefix),g' \
-e 's,[@]sbindir[@],$(sbindir),g' \
- -e 's,[@]sysconfdir[@],$(sysconfdir),g'
+ -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
+ -e 's,[@]storagedir[@],$(storagedir),g' \
+ -e 's,[@]vpn_storagedir[@],$(vpn_storagedir),g' \
- -e 's,[@]localstatedir[@],$(localstatedir),g' \
- -e 's,[@]runstatedir[@],$(runstatedir),g'
++ -e 's,[@]localstatedir[@],$(localstatedir),g'
+
+ %.1 : %.1.in
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(do_subst) < $< > $@
+
+ %.5 : %.5.in
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(do_subst) < $< > $@
+
+ %.8 : %.8.in
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(do_subst) < $< > $@
%.service: %.service.in Makefile
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
$(do_subst) < $< > $@
scripts/connman: scripts/connman.in Makefile
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
$(do_subst) < $< > $@
-scripts/connman_resolvconf.conf: scripts/connman_resolvconf.conf.in
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(do_subst) < $< > $@
-
include/connman/version.h: include/version.h
$(AM_V_at)$(MKDIR_P) include/connman
$(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@
$(AM_V_GEN)$(LN_S) $< $@
clean-local:
- @$(RM) -rf include/connman
+ @$(RM) -rf include/connman $(MANUAL_PAGES)
builtin_sources += plugins/wifi.c $(gsupplicant_sources)
endif
+ if IWD
+ builtin_modules += iwd
+ builtin_sources += plugins/iwd.c
+ endif
+
if BLUETOOTH
- builtin_modules += bluetooth_legacy
- builtin_sources += plugins/bluetooth_legacy.c
builtin_modules += bluetooth
builtin_sources += plugins/bluetooth.c
endif
builtin_sources += plugins/dundee.c
endif
+if TELEPHONY
+if TELEPHONY_BUILTIN
+builtin_modules += telephony
+builtin_sources += plugins/telephony.c
+else
+plugin_LTLIBRARIES += plugins/telephony.la
+plugin_objects += $(plugins_telephony_la_OBJECTS)
+plugins_telephony_la_CFLAGS = $(plugin_cflags)
+plugins_telephony_la_LDFLAGS = $(plugin_ldflags)
+endif
+endif
+
if VPN
builtin_modules += vpn
builtin_sources += plugins/vpn.c
endif
endif
+if IPSEC
+if IPSEC_BUILTIN
+builtin_vpn_modules += ipsec
+builtin_vpn_sources += vpn/plugins/ipsec.h vpn/plugins/ipsec.c
+builtin_vpn_sources += vpn/plugins/vici-client.h vpn/plugins/vici-client.c
+builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h
+builtin_vpn_cflags += -DIPSEC=\"@IPSEC@\"
+else
+vpn_plugin_LTLIBRARIES += vpn/plugins/ipsec.la
+vpn_plugin_objects += $(plugins_ipsec_la_OBJECTS)
+vpn_plugins_ipsec_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \
+ vpn/plugins/ipsec.c vpn/plugins/vici-client.c
+vpn_plugins_ipsec_la_CFLAGS = $(plugin_cflags) -DIPSEC=\"@IPSEC@\" \
+ -DVPN_STATEDIR=\""$(vpn_statedir)"\" \
+ -DSCRIPTDIR=\""$(build_scriptdir)"\" @GIO_CFLAGS@
+vpn_plugins_ipsec_la_LDFLAGS = $(plugin_ldflags) @GIO_LIBS@
+endif
+endif
+
if VPNC
if VPNC_BUILTIN
builtin_vpn_modules += vpnc
scripts_openvpn_script_LDADD = @DBUS_LIBS@
endif
+if IPSEC
+script_PROGRAMS += scripts/ipsec-script
+
+scripts_ipsec_script_LDADD = @DBUS_LIBS@
+endif
+
if NMCOMPAT
builtin_modules += nmcompat
builtin_sources += plugins/nmcompat.c
detected and only a runtime dependency. It is not needed to
build ConnMan.
+ --enable-iwd
+
+ Enable support for Wireless daemon for Linux
+
+ The IWD project does not have initial release so far,
+ therefore by default IWD support is not enabled.
+
+ It is safe to enable this option along WiFi support.
+
--disable-pacrunner
Disable support for PACrunner proxy handling
uplink.
+ GnuTLS
+ ======
+
+ When using GnuTLS be aware that depending on the configuration of
+ GnuTLS does either an lazy or eager initialization of an internal
+ entropy pool using /dev/urandom. On eager initialization the loading
+ of ConnMan will be delayed by the link loader until the entropy pool
+ is filled. On smaller system this can easily delay the startup of
+ ConnMan by several seconds (we had reports of 25 seconds and more
+ delay).
+
+ GnuTLS allows to switch back to lazy evaluation when the environment
+ variable GNUTLS_NO_EXPLICIT_INIT. For more details please read
+ the man page to gnutls_global_init(3).
+
+
Online check
============
(for IPv6 connectivity). The used URL looks like this
http://ipv{4|6}.connman.net/online/status.html
+ See connman.conf(5) for the EnableOnlineCheck option, if you need to
+ disable the feature.
+
During the online check procedure, ConnMan will temporarily install
a host route to both the ipv4.connman.net and ipv6.connman.net so that
the online check query can be directed via the correct network
interface which the connected service is using. This host route is
- automatically removed when the online check is done.
+ automatically removed when the online check is done. Note that the server
+ expressly does not log any connection information, including IPv4/6
+ addresses of connecting clients. The server runtime logs cycle in RAM
+ memory depending on amount of connections processed.
ConnMan sends this very minimal information in http header when doing
the online check request (example):
utilize the information already provided by netlink in src/device.c.
- - Simplify gateway selection code
-
- Priority: Low
- Complexity: C4
-
- The service list is always sorted according to preference with the
- first service always owning the default route. See if update_order and
- find_default_gateway in src/connection.c can be modified to use the
- sorted service list instead of walking through the gateway_hash.
-
-
- Support D-Bus ObjectManager
Priority: Medium
ObjectManager common to Linux desktops can be implemented.
+ Tethering
+ =========
+
+ - Verify if bridge has been correctly created and configured
+
+ Priority: Low
+ Complexity: C1
+
+ When enabling tethering check if there was any error while creating and
+ configuring the bridge before continue. It has been done only for WiFi
+ technology, for other tethering technologies it should be evaluated
+ and implemented in case it is advantageous.
+
+
WiFi
====
wifi's technology set_regdom implementation. Removing autoscan fallback.
(Note: should be done around the end 2012)
+
Bluetooth
=========
- - Remove Bluez 4.x support
-
- Priority: Low
- Complexity: C1
-
- Remove plugins/bluetooth-legacy.c support in about 6 month (July 2013) or
- when Bluez 4.x usage becomes minimal.
Cellular
========
Tools
=====
- - Add Clock API and MoveBefore/MoveAfter support to connmanctl
+ - Add Clock API support to connmanctl
Priority: Low
Complexity: C2
- The connmanctl command line tool should support Clock API and Service API
- MoveBefore/MoveAfter.
-
-
- User Interface
- ==============
-
- - GNOME3 UI
-
- Priority: Low
- Complexity: C4
-
- A GNOME3 shell user interface would make it easier for mainstream distros
- users to use ConnMan. Continue/restart the work at
- https://github.com/connectivity/gnome-extension-connman
+ The connmanctl command line tool should support Clock API.
static DBusConnection *connection;
static GHashTable *service_hash;
+ static GHashTable *vpnconnection_hash;
static GHashTable *peer_hash;
static GHashTable *technology_hash;
static char *session_notify_path;
state_print, NULL, NULL, NULL);
}
+ static int clock_print(DBusMessageIter *iter, const char *error,
+ void *user_data)
+ {
+ DBusMessageIter entry;
+
+ if (error) {
+ fprintf(stderr, "Error: %s", error);
+ return 0;
+ }
+
+ dbus_message_iter_recurse(iter, &entry);
+ __connmanctl_dbus_print(&entry, " ", " = ", "\n");
+ fprintf(stdout, "\n");
+
+ return 0;
+ }
+
+ static int cmd_clock(char *args[], int num, struct connman_option *options)
+ {
+ if (num > 1)
+ return -E2BIG;
+
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ CONNMAN_PATH, "net.connman.Clock", "GetProperties",
+ clock_print, NULL, NULL, NULL);
+ }
+
static int services_list(DBusMessageIter *iter, const char *error,
void *user_data)
{
static int tether_update(struct tether_properties *tether)
{
- if (tether->ssid_result == 0 && tether->passphrase_result == 0)
- return tether_set("wifi", tether->set_tethering);
+ int ret;
+
+ if (tether->ssid_result == 0 && tether->passphrase_result == 0) {
+ ret = tether_set("wifi", tether->set_tethering);
+ g_free(tether);
+ return ret;
+ }
if (tether->ssid_result != -EINPROGRESS &&
tether->passphrase_result != -EINPROGRESS) {
disconnect_return, path, NULL, NULL);
}
+ struct move_service {
+ char *service;
+ char *target;
+ };
+
+ static int move_before_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+ {
+ struct move_service *services = user_data;
+ char *service;
+ char *target;
+
+ if (!error) {
+ service = strrchr(services->service, '/');
+ service++;
+ target = strrchr(services->target, '/');
+ target++;
+ fprintf(stdout, "Moved %s before %s\n", service, target);
+ } else
+ fprintf(stderr, "Error %s: %s\n", services->service, error);
+
+ g_free(services->service);
+ g_free(services->target);
+ g_free(user_data);
+
+ return 0;
+ }
+
+ static void move_before_append_args(DBusMessageIter *iter, void *user_data)
+ {
+ char *path = user_data;
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_OBJECT_PATH, &path);
+
+ return;
+ }
+
+ static int cmd_service_move_before(char *args[], int num,
+ struct connman_option *options)
+ {
+ const char *iface = "net.connman.Service";
+ struct move_service *services;
+
+ if (num > 3)
+ return -E2BIG;
+
+ if (num < 3)
+ return -EINVAL;
+
+ if (check_dbus_name(args[1]) == false)
+ return -EINVAL;
+
+ services = g_new(struct move_service, 1);
+
+ services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
+ services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
+
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ services->service, iface, "MoveBefore",
+ move_before_return, services,
+ move_before_append_args,
+ services->target);
+ }
+
+ static int move_after_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+ {
+ struct move_service *services = user_data;
+ char *service;
+ char *target;
+
+ if (!error) {
+ service = strrchr(services->service, '/');
+ service++;
+ target = strrchr(services->target, '/');
+ target++;
+ fprintf(stdout, "Moved %s after %s\n", service, target);
+ } else
+ fprintf(stderr, "Error %s: %s\n", services->service, error);
+
+ g_free(services->service);
+ g_free(services->target);
+ g_free(user_data);
+
+ return 0;
+ }
+
+ static void move_after_append_args(DBusMessageIter *iter, void *user_data)
+ {
+ char *path = user_data;
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_OBJECT_PATH, &path);
+
+ return;
+ }
+
+ static int cmd_service_move_after(char *args[], int num,
+ struct connman_option *options)
+ {
+ const char *iface = "net.connman.Service";
+ struct move_service *services;
+
+ if (num > 3)
+ return -E2BIG;
+
+ if (num < 3)
+ return -EINVAL;
+
+ if (check_dbus_name(args[1]) == false)
+ return -EINVAL;
+
+ services = g_new(struct move_service, 1);
+
+ services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
+ services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
+
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ services->service, iface, "MoveAfter",
+ move_after_return, services,
+ move_after_append_args,
+ services->target);
+ }
+
static int config_return(DBusMessageIter *iter, const char *error,
void *user_data)
{
int index = 0, res = 0;
struct config_append append;
char c;
+ char *ifname;
+ dbus_bool_t source_ip_rule;
while (index < num && args[index]) {
append.opts = &args[index];
DBUS_TYPE_STRING, &args[index + 1]);
append.values = 2;
break;
+ case 'i':
+ if (index + 1 < num)
+ ifname = args[index + 1];
+ else
+ ifname = "";
+
+ res = __connmanctl_dbus_session_change(connection,
+ session_path, session_config_return,
+ "AllowedInterface", "AllowedInterface",
+ DBUS_TYPE_STRING, &ifname);
+ append.values = 2;
+ break;
+ case 's':
+ if (!args[index + 1]) {
+ res = -EINVAL;
+ break;
+ }
+ switch (parse_boolean(args[index + 1])) {
+ case 1:
+ source_ip_rule = TRUE;
+ break;
+ case 0:
+ source_ip_rule = FALSE;
+ break;
+ default:
+ res = -EINVAL;
+ break;
+ }
+
+ res = __connmanctl_dbus_session_change(connection,
+ session_path, session_config_return,
+ "SourceIPRule", "SourceIPRule",
+ DBUS_TYPE_BOOLEAN, &source_ip_rule);
+ append.values = 2;
+ break;
default:
res = -EINVAL;
return 1;
}
- static char *lookup_service(const char *text, int state)
+ static char *lookup_key_from_table(GHashTable *hash, const char *text,
+ int state)
{
static int len = 0;
static GHashTableIter iter;
gpointer key, value;
if (state == 0) {
- g_hash_table_iter_init(&iter, service_hash);
+ g_hash_table_iter_init(&iter, hash);
len = strlen(text);
}
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- const char *service = key;
- if (strncmp(text, service, len) == 0)
- return strdup(service);
- }
+ while (g_hash_table_iter_next(&iter, &key, &value))
+ if (strncmp(text, key, len) == 0)
+ return strdup(key);
return NULL;
}
return NULL;
}
- return lookup_service(text, state);
+ return lookup_key_from_table(service_hash, text, state);
}
static char *lookup_peer(const char *text, int state)
return lookup_on_off(text, state);
}
+ static char *lookup_vpnconnection_arg(const char *text, int state)
+ {
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ return lookup_key_from_table(vpnconnection_hash, text, state);
+ }
+
static struct connman_option service_options[] = {
{"properties", 'p', "[<service>] (obsolete)"},
{ NULL, }
static struct connman_option session_options[] = {
{"bearers", 'b', "<technology1> [<technology2> [...]]"},
{"type", 't', "local|internet|any"},
+ {"ifname", 'i', "[<interface_name>]"},
+ {"srciprule", 's', "yes|no"},
{ NULL, }
};
static char *lookup_config(const char *text, int state)
{
if (__connmanctl_input_calc_level() < 2)
- return lookup_service(text, state);
+ return lookup_key_from_table(service_hash, text, state);
return lookup_options(config_options, text, state);
}
service = dbus_malloc0(sizeof(*service));
+#if defined TIZEN_EXT
+ if (!service)
+ return NULL;
+#endif
+
if (bjr_query_len && bjr_response_len) {
service->bjr_query = dbus_malloc0(bjr_query_len);
+#if defined TIZEN_EXT
+ if(!service->bjr_query) {
+ dbus_free(service);
+ return NULL;
+ }
+#endif
memcpy(service->bjr_query, bjr_query, bjr_query_len);
service->bjr_query_len = bjr_query_len;
service->bjr_response = dbus_malloc0(bjr_response_len);
+#if defined TIZEN_EXT
+ if(!service->bjr_response) {
+ dbus_free(service->bjr_query);
+ dbus_free(service);
+ return NULL;
+ }
+#endif
memcpy(service->bjr_response, bjr_response, bjr_response_len);
service->bjr_response_len = bjr_response_len;
} else if (upnp_service && version) {
service->version = version;
} else if (wfd_ies && wfd_ies_len) {
service->wfd_ies = dbus_malloc0(wfd_ies_len);
+#if defined TIZEN_EXT
+ if (!service->wfd_ies) {
+ dbus_free(service);
+ return NULL;
+ }
+#endif
memcpy(service->wfd_ies, wfd_ies, wfd_ies_len);
service->wfd_ies_len = wfd_ies_len;
} else {
"Shows if the system is online or offline", NULL },
{ "technologies", NULL, NULL, cmd_technologies,
"Display technologies", NULL },
+ { "clock", NULL, NULL, cmd_clock,
+ "Get System Clock Properties", NULL },
{ "enable", "<technology>|offline", NULL, cmd_enable,
"Enables given technology or offline mode",
lookup_technology_offline },
"Connect a given service or peer", lookup_service_arg },
{ "disconnect", "<service/peer>", NULL, cmd_disconnect,
"Disconnect a given service or peer", lookup_service_arg },
+ { "move-before", "<service> <target service> ", NULL,
+ cmd_service_move_before, "Move <service> before <target service>",
+ lookup_service_arg },
+ { "move-after", "<service> <target service> ", NULL,
+ cmd_service_move_after, "Move <service> after <target service>",
+ lookup_service_arg },
{ "config", "<service>", config_options, cmd_config,
"Set service configuration options", lookup_config },
{ "monitor", "[off]", monitor_options, cmd_monitor,
"Monitor signals from interfaces", lookup_monitor },
{ "agent", "on|off", NULL, cmd_agent,
"Agent mode", lookup_agent },
- {"vpnconnections", "[<connection>]", NULL, cmd_vpnconnections,
- "Display VPN connections", NULL },
+ { "vpnconnections", "[<connection>]", NULL, cmd_vpnconnections,
+ "Display VPN connections", lookup_vpnconnection_arg },
{ "vpnagent", "on|off", NULL, cmd_vpnagent,
"VPN Agent mode", lookup_agent },
{ "session", "on|off|connect|disconnect|config", session_options,
return 0;
}
+ static void add_vpnconnection_id(const char *path)
+ {
+ g_hash_table_replace(vpnconnection_hash, g_strdup(path),
+ GINT_TO_POINTER(TRUE));
+ }
+
+ static void remove_vpnconnection_id(const char *path)
+ {
+ g_hash_table_remove(vpnconnection_hash, path);
+ }
+
+ static void vpnconnection_added(DBusMessageIter *iter)
+ {
+ char *path = NULL;
+
+ dbus_message_iter_get_basic(iter, &path);
+ add_vpnconnection_id(get_path(path));
+ }
+
+ static void vpnconnection_removed(DBusMessageIter *iter)
+ {
+ char *path = NULL;
+
+ dbus_message_iter_get_basic(iter, &path);
+ remove_vpnconnection_id(get_path(path));
+ }
+
+ static void add_vpnconnections(DBusMessageIter *iter)
+ {
+ DBusMessageIter array;
+ char *path = NULL;
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array) !=
+ DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(&array, &path);
+ add_vpnconnection_id(get_path(path));
+
+ dbus_message_iter_next(iter);
+ }
+ }
+
+ static int populate_vpnconnection_hash(DBusMessageIter *iter, const char *error,
+ void *user_data)
+ {
+ DBusMessageIter array;
+
+ if (error) {
+ fprintf(stderr, "Error getting VPN connections: %s", error);
+ return 0;
+ }
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return 0;
+
+ dbus_message_iter_recurse(iter, &array);
+
+ add_vpnconnections(&array);
+
+ return 0;
+ }
+
static void add_peer_id(const char *path)
{
g_hash_table_replace(peer_hash, g_strdup(path), GINT_TO_POINTER(TRUE));
return handled;
}
+ if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
+ "ConnectionAdded")) {
+ dbus_message_iter_init(message, &iter);
+ vpnconnection_added(&iter);
+ return handled;
+ }
+
+ if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
+ "ConnectionRemoved")) {
+ dbus_message_iter_init(message, &iter);
+ vpnconnection_removed(&iter);
+ return handled;
+ }
+
if (dbus_message_is_signal(message, "net.connman.Manager",
"PeersChanged")) {
dbus_message_iter_init(message, &iter);
if (!dbus_conn) {
g_hash_table_destroy(service_hash);
+ g_hash_table_destroy(vpnconnection_hash);
g_hash_table_destroy(technology_hash);
dbus_bus_remove_match(connection,
"type='signal',interface='net.connman.Manager'", NULL);
+ dbus_bus_remove_match(connection,
+ "type='signal',interface='net.connman.vpn.Manager'",
+ NULL);
dbus_connection_remove_filter(connection,
monitor_completions_changed,
manager_enabled);
service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
+ vpnconnection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
peer_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
populate_service_hash, NULL, NULL, NULL);
__connmanctl_dbus_method_call(connection,
+ VPN_SERVICE, CONNMAN_PATH,
+ "net.connman.vpn.Manager", "GetConnections",
+ populate_vpnconnection_hash, NULL, NULL, NULL);
+
+ __connmanctl_dbus_method_call(connection,
CONNMAN_SERVICE, CONNMAN_PATH,
"net.connman.Manager", "GetPeers",
populate_peer_hash, NULL, NULL, NULL);
dbus_bus_add_match(connection,
"type='signal',interface='net.connman.Manager'", &err);
+ if (dbus_error_is_set(&err)) {
+ fprintf(stderr, "Error: %s\n", err.message);
+ return;
+ }
+
+ dbus_bus_add_match(connection,
+ "type='signal',interface='net.connman.vpn.Manager'",
+ &err);
+
if (dbus_error_is_set(&err))
fprintf(stderr, "Error: %s\n", err.message);
}
#include <stdio.h>
#include <errno.h>
+ #include <inttypes.h>
#include <glib.h>
#include "input.h"
dbus_uint16_t u16;
dbus_uint32_t u;
dbus_int32_t i;
+ dbus_uint64_t u64;
double d;
char *str;
fprintf(stdout, "%d", i);
break;
+ case DBUS_TYPE_UINT64:
+ dbus_message_iter_get_basic(iter, &u64);
+ fprintf(stdout, "%"PRIu64, u64);
+ break;
+
case DBUS_TYPE_DOUBLE:
dbus_message_iter_get_basic(iter, &d);
fprintf(stdout, "%f", d);
__connmanctl_save_rl();
reply = dbus_pending_call_steal_reply(call);
+ dbus_pending_call_unref(call);
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
DBusError err;
}
if (len > 0) {
-
- add_history(input);
+ HIST_ENTRY *previous = history_get(where_history());
+ if(!previous || strcmp(previous->line, input))
+ add_history(input);
err = __connmanctl_commands(connection, trim_args, len);
g_strfreev(args);
g_free(trim_args);
+ free(input);
}
static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
__connmanctl_monitor_completions(NULL);
rl_callback_handler_remove();
+#if !defined TIZEN_EXT
rl_message("");
+#endif
}
dbus_connection_unref(connection);
AC_PREREQ(2.60)
- AC_INIT(connman, 1.29)
+ AC_INIT(connman, 1.35)
+
+ AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
AC_CONFIG_HEADERS([config.h])
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
+ gl_CONFIGMAKE_PREP
+
AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization],
[disable code optimization through compiler]), [
if (test "${enableval}" = "no"); then
AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no")
AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin")
+AC_ARG_ENABLE(telephony,
+ AC_HELP_STRING([--enable-telephony], [enable Telephony support]),
+ [enable_telephony=${enableval}], [enable_telephony="yes"])
+AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
+AM_CONDITIONAL(TELEPHONY_BUILTIN, test "${enable_telephony}" = "builtin")
+
+AC_ARG_ENABLE(tizen-ext,
+ AC_HELP_STRING([--enable-tizen-ext], [enable TIZEN extensions]),
+ [if (test "${enableval}" = "yes"); then
+ CFLAGS="$CFLAGS -DTIZEN_EXT"
+ LIBS="$LIBS -lsmack"
+ fi])
+AM_CONDITIONAL(TIZEN_EXT, test "${enable-tizen-ext}" != "no")
+
AC_ARG_WITH(openconnect, AC_HELP_STRING([--with-openconnect=PROGRAM],
[specify location of openconnect binary]), [path_openconnect=${withval}])
[enable_openconnect=${enableval}], [enable_openconnect="no"])
if (test "${enable_openconnect}" != "no"); then
if (test -z "${path_openconnect}"); then
- AC_PATH_PROG(OPENCONNECT, [openconnect], [], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(OPENCONNECT, [openconnect], [], $PATH:/bin:/usr/bin)
if (test -z "${OPENCONNECT}"); then
AC_MSG_ERROR(openconnect binary not found)
fi
[enable_openvpn=${enableval}], [enable_openvpn="no"])
if (test "${enable_openvpn}" != "no"); then
if (test -z "${path_openvpn}"); then
- AC_PATH_PROG(OPENVPN, [openvpn], [], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(OPENVPN, [openvpn], [/usr/bin/openvpn], $PATH:/bin:/usr/bin)
if (test -z "${OPENVPN}"); then
AC_MSG_ERROR(openvpn binary not found)
fi
AM_CONDITIONAL(OPENVPN, test "${enable_openvpn}" != "no")
AM_CONDITIONAL(OPENVPN_BUILTIN, test "${enable_openvpn}" = "builtin")
+AC_ARG_WITH(ipsec, AC_HELP_STRING([--with-ipsec=PROGRAM],
+ [specify location of ipsec binary]), [path_ipsec=${withval}])
+
+AC_ARG_ENABLE(ipsec,
+ AC_HELP_STRING([--enable-ipsec], [enable ipsec support]),
+ [enable_ipsec=${enableval}], [enable_ipsec="no"])
+if (test "${enable_ipsec}" != "no"); then
+ PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.28, dummy=yes,
+ AC_MSG_ERROR(GIO >= 2.28 is required))
+ AC_SUBST(GIO_CFLAGS)
+ AC_SUBST(GIO_LIBS)
+ if (test -z "${path_ipsec}"); then
+ AC_PATH_PROG(IPSEC, [charon], [/usr/bin/charon], $PATH:/usr/bin)
+ if (test -z "${IPSEC}"); then
+ AC_MSG_ERROR(ipsec binary not found)
+ fi
+ else
+ IPSEC="${path_ipsec}"
+ AC_SUBST(IPSEC)
+ fi
+fi
+AM_CONDITIONAL(IPSEC, test "${enable_ipsec}" != "no")
+AM_CONDITIONAL(IPSEC_BUILTIN, test "${enable_ipsec}" = "builtin")
+
AC_ARG_WITH(vpnc, AC_HELP_STRING([--with-vpnc=PROGRAM],
[specify location of vpnc binary]), [path_vpnc=${withval}])
[enable_vpnc=${enableval}], [enable_vpnc="no"])
if (test "${enable_vpnc}" != "no"); then
if (test -z "${path_vpnc}"); then
- AC_PATH_PROG(VPNC, [vpnc], [], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(VPNC, [vpnc], [], $PATH:/bin:/usr/bin)
if (test -z "${VPNC}"); then
AC_MSG_ERROR(vpnc binary not found)
fi
[enable_l2tp=${enableval}], [enable_l2tp="no"])
if (test "${enable_l2tp}" != "no"); then
if (test -z "${path_pppd}"); then
- AC_PATH_PROG(PPPD, [pppd], [/usr/sbin/pppd], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(PPPD, [pppd], [/usr/bin/pppd], $PATH:/bin:/usr/bin)
else
PPPD="${path_pppd}"
AC_SUBST(PPPD)
AC_CHECK_HEADERS(pppd/pppd.h, dummy=yes,
AC_MSG_ERROR(ppp header files are required))
if (test -z "${path_l2tp}"); then
- AC_PATH_PROG(L2TP, [xl2tpd], [/usr/sbin/xl2tpd], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(L2TP, [xl2tpd], [/usr/bin/xl2tpd], $PATH:/bin:/usr/bin)
else
L2TP="${path_l2tp}"
AC_SUBST(L2TP)
[enable_pptp=${enableval}], [enable_pptp="no"])
if (test "${enable_pptp}" != "no"); then
if (test -z "${path_pppd}"); then
- AC_PATH_PROG(PPPD, [pppd], [/usr/sbin/pppd], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(PPPD, [pppd], [/usr/bin/pppd], $PATH:/bin:/usr/bin)
else
PPPD="${path_pppd}"
AC_SUBST(PPPD)
AC_CHECK_HEADERS(pppd/pppd.h, dummy=yes,
AC_MSG_ERROR(ppp header files are required))
if (test -z "${path_pptp}"); then
- AC_PATH_PROG(PPTP, [pptp], [/usr/sbin/pptp], $PATH:/sbin:/usr/sbin)
+ AC_PATH_PROG(PPTP, [pptp], [/usr/bin/pptp], $PATH:/bin:/usr/bin)
else
PPTP="${path_pptp}"
AC_SUBST(PPTP)
AC_MSG_ERROR(resolver library support is required))
])
-AC_CHECK_HEADERS([execinfo.h])
-AM_CONDITIONAL([BACKTRACE], [test "${ac_cv_header_execinfo_h}" = "yes"])
-
AC_CHECK_FUNC(signalfd, dummy=yes,
AC_MSG_ERROR(signalfd support is required))
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
+PKG_CHECK_MODULES(LIBSYSTEMD, libsystemd-daemon, dummy=yes,
+ AC_MSG_ERROR(libsystemd-daemon library is required))
+AC_SUBST(LIBSYSTEMD_CFLAGS)
+AC_SUBST(LIBSYSTEMD_LIBS)
+
PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.4, dummy=yes,
AC_MSG_ERROR(D-Bus >= 1.4 is required))
AC_SUBST(DBUS_CFLAGS)
fi
AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}")
- PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, dummy=yes,
- AC_MSG_ERROR(Xtables library is required))
- AC_SUBST(XTABLES_CFLAGS)
- AC_SUBST(XTABLES_LIBS)
-AC_ARG_WITH([tmpfilesdir], AC_HELP_STRING([--with-tmpfilesdir=DIR],
- [path to systemd tmpfiles.d directory]), [path_tmpfiles=${withval}],
- [path_tmpfiles="`$PKG_CONFIG --variable=tmpfilesdir systemd`"])
-if (test -n "${path_tmpfiles}"); then
- SYSTEMD_TMPFILESDIR="${path_tmpfiles}"
- AC_SUBST(SYSTEMD_TMPFILESDIR)
-fi
-
+ AC_ARG_WITH(firewall, AC_HELP_STRING([--with-firewall=TYPE],
+ [specify which firewall type is used iptables or nftables [default=iptables]]),
+ [firewall_type=${withval}],
+ [firewall_type="iptables"])
+
+ if (test "${firewall_type}" != "iptables" -a \
+ "${firewall_type}" != "nftables"); then
+ AC_MSG_ERROR(neither nftables nor iptables support enabled)
+ fi
+
+ found_iptables="no"
+ if (test "${firewall_type}" = "iptables"); then
+ PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, [found_iptables="yes"],
+ AC_MSG_ERROR(Xtables library is required))
+ AC_SUBST(XTABLES_CFLAGS)
+ AC_SUBST(XTABLES_LIBS)
+ fi
+ AM_CONDITIONAL(XTABLES, test "${found_iptables}" != "no")
+
+ found_nftables="no"
+ if (test "${firewall_type}" = "nftables"); then
+ PKG_CHECK_MODULES(NFTABLES, [libnftnl >= 1.0.4 libmnl >= 1.0.0], [found_nftables="yes"],
+ AC_MSG_ERROR([libnftnl >= 1.0.4 or libmnl >= 1.0.0 not found]))
+ AC_SUBST(NFTABLES_CFLAGS)
+ AC_SUBST(NFTABLES_LIBS)
+ fi
+ AM_CONDITIONAL(NFTABLES, test "${found_nftables}" != "no")
AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
[enable test/example scripts]), [enable_test=${enableval}])
[enable_wifi=${enableval}])
AM_CONDITIONAL(WIFI, test "${enable_wifi}" != "no")
+ AC_ARG_ENABLE(iwd, AC_HELP_STRING([--enable-iwd],
+ [enable iwd support]),
+ [enable_iwd=${enableval}])
+ AM_CONDITIONAL(IWD, test "${enable_iwd}" = "yes")
+
AC_ARG_ENABLE(bluetooth, AC_HELP_STRING([--disable-bluetooth],
[disable Bluetooth support]),
[enable_bluetooth=${enableval}])
if (test "${enable_tools}" != "no"); then
AC_PATH_PROGS(IPTABLES_SAVE, [iptables-save], [],
- $PATH:/sbin:/usr/sbin)
+ $PATH:/bin:/usr/bin)
IPTABLES_SAVE=$ac_cv_path_IPTABLES_SAVE
else
IPTABLES_SAVE=""
if (test "${enable_wifi}" != "no"); then
AC_PATH_PROG(WPASUPPLICANT, [wpa_supplicant], [],
- $PATH:/sbin:/usr/sbin)
+ $PATH:/bin:/usr/bin)
fi
AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
AM_CONDITIONAL(VPN, test "${enable_openconnect}" != "no" -o \
"${enable_openvpn}" != "no" -o \
+ "${enable_ipsec}" != "no" -o \
"${enable_vpnc}" != "no" -o \
"${enable_l2tp}" != "no" -o \
"${enable_pptp}" != "no")
-AC_OUTPUT(Makefile include/version.h connman.pc)
+AC_OUTPUT(Makefile include/version.h connman.pc src/connman.service src/connman_tv.service vpn/connman-vpn.service)
string PreviousPassphrase
The previous passphrase successfully saved, i.e.
- which lead to a successfull connection. This field is
+ which led to a successfull connection. This field is
provided as an informational argument when connecting
with it does not work anymore, for instance when it
has been changed on the AP. Such argument appears when
would be the network name or SSID.
All "mandatory" fields must be returned, while the
- "optional" can be returned if available.
+ "optional" ones can be returned if available.
Nothing needs to be returned for "informational", as it
- is here only to provide an information so a value is
+ is here only to provide an information. A value is
attached to it.
array{string} Alternates
passphrase. The PrivateKeyPassphrase field is ignored when this field is set
to fsid.
- Identity: Identity string for EAP.
+ - AnonymousIdentity: Anonymous Identity string for EAP.
+ - SubjectMatch: Substring to be matched against the subject of the
+ authentication server certificate for EAP.
+ - AltSubjectMatch: Semicolon separated string of entries to be matched against
+ the alternative subject name of the authentication server certificate for EAP.
+ - DomainSuffixMatch: Constraint for server domain name. If set, this FQDN is
+ used as a suffix match requirement for the authentication server certificate
+ for EAP.
+ - DomainMatch: This FQDN is used as a full match requirement for the
+ authentication server certificate for EAP.
- Phase2: Phase2 (inner authentication with TLS tunnel) authentication method.
Prefix the value with "EAP-" to indicate the usage of an EAP-based inner
authentication method (should only be used with EAP = TTLS).
.\" connman.conf(5) manual page
.\"
- .\" Copyright (C) 2012 Intel Corporation
+ .\" Copyright (C) 2012,2015 Intel Corporation
.\"
- .TH "connman.conf" "5" "21 August 2012" ""
+ .TH "connman.conf" "5" "2015-10-15" ""
.SH NAME
main.conf \- ConnMan configuration file
.SH SYNOPSIS
- /etc/connman/main.conf
- .br
- or
- .br
- \fI<SYSCONFDIR>\fP/connman/main.conf
- .br
- where <SYSCONFDIR> depends on your distribution or build.
+ .B @sysconfdir@/connman/main.conf
.SH DESCRIPTION
.P
- .I main.conf
+ .B main.conf
is a configuration file for ConnMan. The configuration file is
optional but it can be used to set up various aspects of ConnMan's
behavior. The location of the file may be changed through use of
- the "\-\-config=" argument for \fBconnman\fP (8).
+ the \fB\-\-config= \fRargument for \fBconnman\fP(8).
.SH "FILE FORMAT"
.P
The configuration file format is key file format.
.SS [General]
This section is the only mandatory section of the configuration file.
.TP
- .B InputRequestTimeout=\fPsecs\fP
+ .BI InputRequestTimeout= secs
Set input request timeout. Default is 120 seconds
The request for inputs like passphrase will timeout
after certain amount of time. Use this setting to
increase the value in case of different user
interface designs.
.TP
- .B BrowserLaunchTimeout=\fPsecs\fP
+ .BI BrowserLaunchTimeout= secs
Set browser launch timeout. Default is 300 seconds
The request for launching a browser for portal pages
will timeout after certain amount of time. Use this
setting to increase the value in case of different
user interface designs.
.TP
- .B BackgroundScanning=\fPtrue|false\fP
+ .BI BackgroundScanning=true\ \fR|\fB\ false
Enable background scanning. Default is true.
Background scanning will start every 5 minutes unless
the scan list is empty. In that case, a simple backoff
mechanism starting from 10s up to 5 minutes will run.
.TP
- .B FallbackTimeservers=\fPserver1,server2,...\fP
+ .BI FallbackTimeservers= server\fR[,...]
List of Fallback timeservers separated by ",".
These timeservers are used for NTP sync when there are
no timeserver set by the user or by the service.
These can contain mixed combination of fully qualified
domain names, IPv4 and IPv6 addresses.
.TP
- .B FallbackNameservers=\fPserver1,server2,...\fP
+ .BI FallbackNameservers= server\fR[,...]
List of fallback nameservers separated by "," appended
to the list of nameservers given by the service. The
nameserver entries must be in numeric format, host
names are ignored.
.TP
- .B DefaultAutoConnectTechnologies=\fPtechnology1,technology2,...\fP
+ .BI DefaultAutoConnectTechnologies= technology\fR[,...]
List of technologies that are marked autoconnectable
by default, separated by commas ",". The default value
for this entry when empty is ethernet,wifi,cellular.
Services that are automatically connected must have been
set up and saved to storage beforehand.
.TP
- .B PreferredTechnologies=\fPtechnology1,technology2,...\fP
+ .BI AlwaysConnectedTechnologies= technology\fR[,...]
+ List of technoolgies which are always connected regardless
+ of PreferredTechnologies setting (AutoConnect = true). The
+ default value is empty and this feature is disabled unless
+ explicitely enabled in the config file.
+ .TP
+ .BI PreferredTechnologies= technology\fR[,...]
List of preferred technologies from the most preferred
one to the least preferred one separated by commas ",".
Services of the listed technology type will be tried one
the default route when compared to either a non-preferred
type or a preferred type further down in the list.
.TP
- .B NetworkInterfaceBlacklist=\fPinterface1,interface2,...\fP
+ .BI NetworkInterfaceBlacklist= interface\fR[,...]
List of blacklisted network interfaces separated by ",".
Found interfaces will be compared to the list and will
not be handled by connman, if their first characters
match any of the list entries. Default value is
vmnet,vboxnet,virbr,ifb.
.TP
- .B AllowHostnameUpdates=\fPtrue|false\fP
+ .BI AllowHostnameUpdates=true\ \fR|\fB\ false
Allow connman to change the system hostname. This can
happen for example if we receive DHCP hostname option.
Default value is true.
.TP
- .B SingleConnectedTechnology=\fPtrue|false\fP
+ .BI SingleConnectedTechnology=true\ \fR|\fB\ false
Keep only a single connected technology at any time. When a new
service is connected by the user or a better one is found according
to PreferredTechnologies, the new service is kept connected and all
setting enabled applications will notice more network breaks than
normal. Default value is false.
.TP
- .B TetheringTechnologies=\fPtechnology1,technology2,...\fP
+ .BI TetheringTechnologies= technology\fR[,...]
List of technologies that are allowed to enable tethering separated by ",".
The default value is wifi,bluetooth,gadget. Only those technologies listed
here are used for tethering. If one wants to tether ethernet,
tethered by default. Do not activate ethernet tethering unless you
really know what you are doing.
.TP
- .B PersistentTetheringMode=\fPtrue|false\fP
+ .BI PersistentTetheringMode=true\ \fR|\fB\ false
Restore earlier tethering status when returning from offline mode,
re-enabling a technology, and after restarts and reboots.
Default value is false.
.TP
- .B Enable6to4=\fPtrue|false\fP
+ .BI Enable6to4=true\ \fR|\fB\ false
Automatically enable Anycast 6to4 if possible. This is not recommended, as the
use of 6to4 will generally lead to a severe degradation of connection quality.
See RFC6343. Default value is false (as recommended by RFC6343 section 4.1).
-Enable or disable use of HTTP GET as an online status check.
+ .TP
+ .BI VendorClassID= string
+ Set DHCP option 60 (Vendor Class ID) to the given string. This option can
+ be used by DHCP servers to identify specific clients without having to
+ rely on MAC address ranges, etc
+ .TP
+ .BI EnableOnlineCheck=true\ \fR|\fB\ false
++Enable or disable use of HTTP GET as on online status check.
+ When a service is in a READY state, and is selected as default,
+ ConnMan will issue an HTTP GET request to verify that end-to-end
+ connectivity is successful. Only then the service will be
+ transitioned to ONLINE state.
+ If this setting is false, the default service will remain in READY state.
+ Default value is true.
+ .SH "EXAMPLE"
+ The following example configuration disables hostname updates and enables
+ ethernet tethering.
+ .PP
+ .nf
+ [General]
+ AllowHostnameUpdates = false
+ TetheringTechnologies = ethernet,wifi,bluetooth,gadget
+ .fi
.SH "SEE ALSO"
- .BR Connman (8)
+ .BR connman (8)
+---------------+
| idle |<-------------------------------+
- +---------------+ |
- | |
+ +---------------+ A |
+ | clear error | |
| +-------------+ |
+----------------------| failure | |
| service.Connect() +-------------+ |
| |
+------------------------------------------+
- The different states should no be used by the user interface to trigger
+ The different states should not be used by the user interface to trigger
advanced actions. The state transitions are provided for the sole purpose
to give the user feedback on what is currently going on. Especially in
cases where networks are flaky or DHCP servers take a long time these
A Technology in ConnMan is an abstract representation of the different
kinds of technologies it supports such as WiFi, Ethernet, Bluetooth and
- Celullar. The technologies support are added to ConnMan through plugins, such
+ Celullar. The technologies supported are added to ConnMan through plugins, such
as plugins/bluetooth.c for the Bluetooth Technology or plugins/wifi.c for the
WiFi Technology. Each new technology plugin needs to register itself as a
Technology with ConnMan. As an example we will take a look at the Bluetooth
connman_technology_driver_register(&tech_driver);
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
All plugins should check return values in driver registration functions.
After this call ConnMan becomes aware of the new Technology plugin and will
adapter is recognized. A Technology is only probed if there exists at least
one device of such technology plugged into the system.
- Complementary, the technology must be unregistered on the plugin exit function
+ Complementary, the technology must be unregistered by the plugin exit function
through 'connman_technology_driver_unregister()'.
Device infrastructure
'connman_device_driver_register()' is called during the plugin initialization
process, not necessarily at the plugin init function.
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
All plugins should check return values in driver registration functions.
Additionally code to handle the detection of new devices needs to be written
Network infrastructure
======================
- The Connection Manager provides a mean to plugins handle the specifics of
+ The Connection Manager provides a means to plugins to handle the specifics of
establishing/handling a connection for each type of Technology. For the
bluetooth plugin a connman_network_driver needs to be registered:
connman_network_driver_register(&network_driver);
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
All plugins should check return values in driver registration functions.
The next step would be the probe of a Network entity, for the bluetooth
plugin this would happen when a new device that supports the PAN NAP role is
- paired with the system. ConnMan then call connman_device_add_network() to
+ paired with the system. ConnMan then calls connman_device_add_network() to
associate the new Network with the existing Device entity (the local Bluetooth
Adapter).
void ClearProperty(string name)
- Clears the value of the specified property.
+ Clears the value of the specified property. Only
+ the readonly Error property can be cleared using
+ this method call. When cleared the service is reset
+ to the idle state.
- Properties cannot be cleared for hidden WiFi service
- entries or provisioned services.
-
- Possible Errors: [service].Error.InvalidArguments
- [service].Error.InvalidProperty
+ Possible Errors: [service].Error.InvalidProperty
void Connect()
to false, but that is currently not supported.
In the case a connection attempt failed and the
- service is in the State=failure, this method can
- also be used to reset the service.
+ service is in the state "failure", "idle" or
+ "disconnect", this method can also be used
+ to reset the service.
Calling this method on Ethernet devices, hidden WiFi
services or provisioned services will cause an error
Possible Errors: None
+ boolean GetUserFavorite() [experimental]
+
+ This function is used to check whether this service
+ is favorite to the current user.
+
+ Possible Errors: None
+
Signals PropertyChanged(string name, variant value)
This signal indicates a changed value of the given
and also "wps".
This property might be only present for WiFi
+ services.
+
+ string BSSID [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the BSSID of the service.
+
+ uint32 MaxRate [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the Maximum speed(bps) of the service.
+
+ uint16 Frequency [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the frequency band(MHz) of the service.
+
+ string EncryptionMode [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the key encryption mode.
+
+ Possible values are "none", "wep", "tkip", "aes"
+ and "mixed".
+
+ This property might be only present for WiFi
services.
uint8 Strength [readonly]
This value will be set to true if the service is
configured externally via a configuration file.
- The only valid operation are Connect() and of
- course Disconnect(). The Remove() method will
- result in an error.
+ The only valid operations are Connect(), Disconnect()
+ and changing the AutoConnect property. The Remove()
+ method will result in an error.
boolean AutoConnect [readwrite]
string Method [readonly]
- Possible values are "dhcp", "manual"
+ Possible values are "dhcp", "manual", "auto"
and "off".
+ It could be "auto" in case address was got
+ through IPv4LL after DHCP failed. In this
+ case also IPv4.Configuration will become
+ "auto" to allow user to ask for a DHCP
+ address at any time.
+
The value "fixed" indicates an IP address
that can not be modified. For example
cellular networks return fixed information.
(This setting will be removed when the unique process
identification problem is solved.)
+ string AllowedInterface [readwrite] [experimental]
+
+ This field is used to bind a session to a specific
+ network interface. If this field is empty, the first
+ interface from a list of available ones will be used.
+ Also "*" string matches any interface.
+
+ Only one interface may be specified.
+
+ If a specified network interface is not available
+ (e.g. because AllowedBearers filters it out), the
+ session will not go online.
+
+ boolean SourceIPRule [readwrite] [experimental]
+
+ If set to true the session will create source IP
+ address rule in the firewall, which redirects traffic
+ to that session's routing table.
+
+ Each session maintains a dedicated routing table, with
+ a default route. When the source IP rule is enabled,
+ an application can select which session/interface to
+ send traffic on, using bind-before-connect mechanism.
routing. Sessions are still useful in this setup, because the
notification of sessions is still available, e.g. the online/offline
notification.
+
+
+ Multiple per-session routing tables
+ ===================================
+
+ Sessions can be used in an environment with multiple network interfaces,
+ where an application needs to direct outside traffic through a selected
+ interface(s). ConnMan can maintain multiple sessions in a connected
+ stated, and the application can dynamically, on a per-socket basis,
+ select which session is used to route traffic.
+
+ Example use cases are:
+ - monitoring liveness of multiple connected interfaces, by sending
+ end-to-end heartbeat traffic on all of them in parallel.
+ - prioritising traffic - e.g. sensitive data can be transferred over a slow,
+ but secure connection, while big, public downloads use a second session
+
+ By default, ConnMan maintains only one online service. So it is impossible
+ to send external traffic (routed through a gateway) on multiple interfaces.
+ In order to enable this functionality, an application needs to issue the
+ following API calls:
+ - create multiple sessions, one for each interface to be used
+ - set each session's AllowedInterface config field to the required interface
+ name (eth0, eth1, wlan0, ppp0, etc.)
+ - set each session's SourceIPRule config field to true
+ - connect each session (or the service it is using)
+
+ That will instruct ConnMan to create multiple routing tables, with default
+ routes in them. After that, the application can issue a bind() call on each
+ socket, using required interface's source IP address. The bind() call must
+ be made before a connect() call on a socket.
This signal indicates a changed value of the given
property.
+ DhcpConnected(string aptype, string ipaddr,
+ string macaddr, string hostname)
+
+ This signal indicates a station information that
+ has connected to the AP(Access Point).
+
+ DhcpLeaseDeleted(string aptype, string ipaddr,
+ string macaddr, string hostname)
+
+ This signal indicates a station information that
+ has disconnected to the AP(Access Point).
+
Properties boolean Powered [readwrite]
Boolean representing the power state of the
Boolean representing if a technology is connected.
- This is just a convience property for allowing the
+ This is just a convenience property for allowing the
UI to easily show if this technology has an active
connection or not.
If this property is True it means that at least one
service of this technology is in ready state.
+ In case of P2P technology, this property indicates
+ if the peer is fully connected to another peer.
+
string Name [readonly]
Name of this technology.
This property is only valid for the WiFi technology,
and is then mapped to the WPA pre-shared key clients
will have to use in order to establish a connection.
+
+ boolean Hidden [readwrite]
+
+ This option allows to enable or disable the support
+ for the hidden Wi-Fi tethering.
--auth-user-pass value (O)
OpenVPN.TLSRemote --tls-remote Accept connections only from a host
with X509 name or common name equal
- to name parameter (O)
+ to name parameter (O). Deprecated in
+ OpenVPN 2.3+.
OpenVPN.TLSAuth sub-option of --tls-remote (O)
OpenVPN.TLSAuthDir sub-option of --tls-remote (O)
OpenVPN.Cipher --cipher Encrypt packets with cipher algorithm
OpenVPN.ConfigFile --config OpenVPN config file that can contain
extra options not supported by OpenVPN
plugin (O)
+ OpenVPN.DeviceType --dev-type Whether the VPN should use a tun (OSI
+ layer 3) or tap (OSI layer 2) device.
+ Value is "tun" (default) or "tap" (O)
VPNC VPN supports following options (see vpnc(8) for details):
Option name VPNC config value Description
VPNC.Xauth.Password Xauth password your password (cleartext) (O)
VPNC.IKE.Authmode IKE Authmode IKE Authentication mode (O)
VPNC.IKE.DHGroup IKE DH Group name of the IKE DH Group (O)
- VPNC.PFS Perfect Forward Secrecy Diffie-Hellman group to use for PFS (O)
+ VPNC.PFS Perfect Forward Secrecy Diffie-Hellman group to use for
+ PFS (O)
VPNC.Domain Domain Domain name for authentication (O)
VPNC.Vendor Vendor vendor of your IPSec gateway (O)
VPNC.LocalPort Local Port local ISAKMP port number to use
- VPNC.CiscoPort Cisco UDP Encapsulation Port Local UDP port number to use (O)
- VPNC.AppVersion Application Version Application Version to report (O)
+ VPNC.CiscoPort Cisco UDP Encapsulation Port Local UDP port number to
+ use (O)
+ VPNC.AppVersion Application version Application Version to report (O)
VPNC.NATTMode NAT Traversal Mode Which NAT-Traversal Method to use (O)
- VPNC.DPDTimeout DPD idle timeout (our side) Send DPD packet after timeout (O)
+ VPNC.DPDTimeout DPD idle timeout (our side) Send DPD packet after
+ timeout (O)
VPNC.SingleDES Enable Single DES enables single DES encryption (O)
- VPNC.NoEncryption Enable no encryption enables using no encryption for data traffic (O)
+ VPNC.NoEncryption Enable no encryption enables using no encryption for data
+ traffic (O)
+ VPNC.DeviceType Interface mode Whether the VPN should use a tun (OSI
+ layer 3) or tap (OSI layer 2) device.
+ Value is "tun" (default) or "tap" (O)
L2TP VPN supports following options (see xl2tpd.conf(5) and pppd(8) for details)
Option name xl2tpd config value Description
if not set here (O)
L2TP.Password - L2TP password, asked from the user
if not set here (O)
- L2TP.BPS bps Max bandwith to use (O)
- L2TP.TXBPS tx bps Max transmit bandwith to use (O)
- L2TP.RXBPS rx bps Max receive bandwith to use (O)
+ L2TP.BPS bps Max bandwidth to use (O)
+ L2TP.TXBPS tx bps Max transmit bandwidth to use (O)
+ L2TP.RXBPS rx bps Max receive bandwidth to use (O)
L2TP.LengthBit length bit Use length bit (O)
L2TP.Challenge challenge Use challenge authentication (O)
L2TP.DefaultRoute defaultroute Default route (O)
PPPD.RefuseMSCHAP2 refuse-mschapv2 Deny mschapv2 auth (O)
PPPD.NoBSDComp nobsdcomp Disables BSD compression (O)
PPPD.NoPcomp nopcomp Disable protocol compression (O)
- PPPD.UseAccomp accomp Disable address/control compression (O)
+ PPPD.UseAccomp noaccomp Disable address/control
+ compression (O)
PPPD.NoDeflate nodeflate Disable deflate compression (O)
PPPD.ReqMPPE require-mppe Require the use of MPPE (O)
PPPD.ReqMPPE40 require-mppe-40 Require the use of MPPE 40 bit (O)
PPPD.ReqMPPE128 require-mppe-128 Require the use of MPPE 128 bit (O)
PPPD.ReqMPPEStateful mppe-stateful Allow MPPE to use stateful mode (O)
- PPPD.NoVJ no-vj-comp No Van Jacobson compression (O)
+ PPPD.NoVJ novj No Van Jacobson compression (O)
PPTP VPN supports following options (see pptp(8) and pppd(8) for details)
PPPD.RequirMPPE40 require-mppe-40 Require the use of MPPE 40 bit (O)
PPPD.RequirMPPE128 require-mppe-128 Require the use of MPPE 128 bit (O)
PPPD.RequirMPPEStateful mppe-stateful Allow MPPE to use stateful mode (O)
- PPPD.NoVJ no-vj-comp No Van Jacobson compression (O)
+ PPPD.NoVJ novj No Van Jacobson compression (O)
+IPsec VPN supports following options (see swanctl.conf(5) for details):
+ Option name IPSec config value Description
+ IPsec.Version Version IKE major version to use for connection (M)
+ IPsec.LeftAddrs local_addrs Local address(es) to use for IKE communication (M)
+ IPsec.RightAddrs remote_addrs Remote address(es) to use for IKE communication (M)
+
+
+ IPsec.LocalAuth local.auth Authentication to perform locally (M)
+ IPsec.LocalCerts local.certs Certificate candidate to use for authentication (O)
+ IPsec.LocalID local.id IKE identity to use for authentication round (O)
+ IPsec.LocalXauthID local.xauth_id Client XAuth username used in the XAuth exchange (O)
+ IPsec.LocalXauthAuth local-xauth.auth Xauth round authentication to perform locally (O)
+ IPsec.LocalXauthXauthID local-xauth.xauth_id Xauth round client XAuth username used in the XAuth exchange (O)
+
+ IPsec.RemoteAuth remote.auth Authentication to expect from remote (M)
+ IPsec.RemoteCerts remote.certs Certificate candidate to use for authentication (O)
+ IPsec.RemoteID remote.id IKE identity to use for authentication round (O)
+ IPsec.RemoteXauthAuth remote-xauth.auth Xauth round authentication to expect from remote (O)
+ IPsec.ChildrenLocalTs children.local_ts local selectors to include in CHILD_SA (O)
+ IPsec.ChildrenRemoteTs children.remote_ts Remote selectors to include in CHILD_SA (O)
+
+ IPsec.IKEData secret.data IKE PSK raw shared key data
+ IPsec.IKEOwners secret.Owners list of shared key owner identities
+ IPsec.XauthData secret.data XAUTH raw shared key data
+ IPsec.XauthOwners secret.Owners list of shared key owner identities
+
+ IPsec.CertType cert.type certificate type, X509|X509_AC|X509_CRL
+ IPsec.CertFlag cert.flag X.509 certificate flag, NONE|CA|AA|OCSP
+ IPsec.CertData cert.data PEM or DER encoded certificate data
Example
=======
string Netmask
- The netmask of the route.
+ The netmask of the route. For IPv6 routes,
+ this is the prefix length.
string Gateway
string Netmask
- The netmask of the route.
+ The netmask of the route. For IPv6 routes,
+ this is the prefix length.
string Gateway
void *signal_data;
GDBusProxyFunction proxy_added;
GDBusProxyFunction proxy_removed;
+#if !defined TIZEN_EXT
GDBusClientFunction ready;
void *ready_data;
+#endif
GDBusPropertyFunction property_changed;
void *user_data;
GList *proxy_list;
return TRUE;
}
+#if !defined TIZEN_EXT
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
const char *name, int type, const void *value,
size_t size, GDBusResultFunction function,
return TRUE;
}
+#endif
struct method_call_data {
GDBusReturnFunction function;
if (client == NULL)
return FALSE;
- data = g_try_new0(struct method_call_data, 1);
- if (data == NULL)
- return FALSE;
-
- data->function = function;
- data->user_data = user_data;
- data->destroy = destroy;
-
msg = dbus_message_new_method_call(client->service_name,
proxy->obj_path, proxy->interface, method);
- if (msg == NULL) {
- g_free(data);
+ if (msg == NULL)
return FALSE;
- }
if (setup) {
DBusMessageIter iter;
dbus_message_iter_init_append(msg, &iter);
- setup(&iter, data->user_data);
+ setup(&iter, user_data);
}
+ if (!function)
+ return g_dbus_send_message(client->dbus_conn, msg);
+
+ data = g_try_new0(struct method_call_data, 1);
+ if (data == NULL)
+ return FALSE;
+
+ data->function = function;
+ data->user_data = user_data;
+ data->destroy = destroy;
+
+
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, METHOD_CALL_TIMEOUT) == FALSE) {
dbus_message_unref(msg);
dbus_message_iter_next(&dict);
}
- #if !defined TIZEN_EXT
- if (client->ready)
- client->ready(client, client->ready_data);
- #endif
}
static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
parse_managed_objects(client, reply);
done:
++#if !defined TIZEN_EXT
+ if (client->ready)
+ client->ready(client, client->ready_data);
++#endif
+
dbus_message_unref(reply);
dbus_pending_call_unref(client->get_objects_call);
return TRUE;
}
+#if !defined TIZEN_EXT
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
GDBusClientFunction ready, void *user_data)
{
return TRUE;
}
+#endif
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
GDBusProxyFunction proxy_added,
#include <dbus/dbus.h>
#include <glib.h>
- typedef enum GDBusMethodFlags GDBusMethodFlags;
- typedef enum GDBusSignalFlags GDBusSignalFlags;
- typedef enum GDBusPropertyFlags GDBusPropertyFlags;
- typedef enum GDBusSecurityFlags GDBusSecurityFlags;
-
typedef struct GDBusArgInfo GDBusArgInfo;
typedef struct GDBusMethodTable GDBusMethodTable;
typedef struct GDBusSignalTable GDBusSignalTable;
G_DBUS_SECURITY_FLAG_ALLOW_INTERACTION = (1 << 2),
};
+ enum GDbusPropertyChangedFlags {
+ G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH = (1 << 0),
+ };
+
+ typedef enum GDBusMethodFlags GDBusMethodFlags;
+ typedef enum GDBusSignalFlags GDBusSignalFlags;
+ typedef enum GDBusPropertyFlags GDBusPropertyFlags;
+ typedef enum GDBusSecurityFlags GDBusSecurityFlags;
+ typedef enum GDbusPropertyChangedFlags GDbusPropertyChangedFlags;
+
struct GDBusArgInfo {
const char *name;
const char *signature;
void g_dbus_emit_property_changed(DBusConnection *connection,
const char *path, const char *interface,
const char *name);
+ void g_dbus_emit_property_changed_full(DBusConnection *connection,
+ const char *path, const char *interface,
+ const char *name,
+ GDbusPropertyChangedFlags flags);
gboolean g_dbus_get_properties(DBusConnection *connection, const char *path,
const char *interface, DBusMessageIter *iter);
GDBusResultFunction function, void *user_data,
GDBusDestroyFunction destroy);
+#if !defined TIZEN_EXT
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
const char *name, int type, const void *value,
size_t size, GDBusResultFunction function,
void *user_data, GDBusDestroyFunction destroy);
+#endif
typedef void (* GDBusSetupFunction) (DBusMessageIter *iter, void *user_data);
typedef void (* GDBusReturnFunction) (DBusMessage *message, void *user_data);
GDBusReturnFunction function, void *user_data,
GDBusDestroyFunction destroy);
+#if !defined TIZEN_EXT
typedef void (* GDBusClientFunction) (GDBusClient *client, void *user_data);
+#endif
typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
DBusMessageIter *iter, void *user_data);
GDBusWatchFunction function, void *user_data);
gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
GDBusMessageFunction function, void *user_data);
+#if !defined TIZEN_EXT
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
GDBusClientFunction ready, void *user_data);
+#endif
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
GDBusProxyFunction proxy_added,
GDBusProxyFunction proxy_removed,
reply = method->function(connection, message, iface_user_data);
- if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY) {
+ if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY ||
+ dbus_message_get_no_reply(message)) {
if (reply != NULL)
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_HANDLED;
if (!dbus_connection_register_object_path(connection, path,
&generic_table, data)) {
+#if !defined TIZEN_EXT
dbus_connection_unref(data->conn);
g_free(data->path);
+#endif
g_free(data->introspect);
g_free(data);
return NULL;
}
}
- void g_dbus_emit_property_changed(DBusConnection *connection,
+ void g_dbus_emit_property_changed_full(DBusConnection *connection,
const char *path, const char *interface,
- const char *name)
+ const char *name,
+ GDbusPropertyChangedFlags flags)
{
const GDBusPropertyTable *property;
struct generic_data *data;
iface->pending_prop = g_slist_prepend(iface->pending_prop,
(void *) property);
- add_pending(data);
+ if (flags & G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH)
+ process_property_changes(data);
+ else
+ add_pending(data);
+ }
+
+ void g_dbus_emit_property_changed(DBusConnection *connection, const char *path,
+ const char *interface, const char *name)
+ {
+ g_dbus_emit_property_changed_full(connection, path, interface, name, 0);
}
gboolean g_dbus_get_properties(DBusConnection *connection, const char *path,
#define DISCOVER_TIMEOUT 5
#define DISCOVER_RETRIES 6
+#if defined TIZEN_EXT
+#define REQUEST_TIMEOUT 1
+#else
#define REQUEST_TIMEOUT 5
+#endif
#define REQUEST_RETRIES 3
+#if defined TIZEN_EXT
+#define DISCOVER_TIMEOUT_WIFI 1
+#define DISCOVER_RETRIES_WIFI 10
+static int dhcp_discover_timeout = DISCOVER_TIMEOUT_WIFI;
+static int dhcp_discover_max_retry = DISCOVER_RETRIES_WIFI;
+
+void set_dhcp_discover_timeout(int timeout_value)
+{
+ dhcp_discover_timeout = timeout_value;
+}
+
+void set_dhcp_discover_retry_count(int retry_count)
+{
+ dhcp_discover_max_retry = retry_count;
+}
+#endif
+
typedef enum _listen_mode {
L_NONE,
L2,
bool retransmit;
struct timeval start_time;
bool request_bcast;
+#if defined TIZEN_EXT
+ uint32_t dhcp_lease_seconds;
+ gboolean init_reboot;
+#endif
};
static inline void debug(GDHCPClient *client, const char *format, ...)
init_packet(dhcp_client, &packet, DHCPREQUEST);
packet.xid = dhcp_client->xid;
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot != TRUE)
+#endif
packet.secs = dhcp_attempt_secs(dhcp_client);
if (dhcp_client->state == REQUESTING || dhcp_client->state == REBOOTING)
.filter = (struct sock_filter *) filter_instr,
};
- fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
+ fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return -errno;
{
GDHCPClient *dhcp_client = user_data;
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot) {
+ debug(dhcp_client, "DHCPREQUEST of INIT-REBOOT has failed");
+
+ /* Start DHCPDISCOVERY when DHCPREQUEST of INIT-REBOOT has failed */
+ g_dhcp_client_set_address_known(dhcp_client, FALSE);
+
+ dhcp_client->retry_times = 0;
+ dhcp_client->requested_ip = 0;
+
+ g_dhcp_client_start(dhcp_client, dhcp_client->last_address);
+
+ return FALSE;
+ }
+#endif
debug(dhcp_client, "request timeout (retries %d)",
dhcp_client->retry_times);
return 3600;
lease_seconds = get_be32(option);
- /* paranoia: must not be prone to overflows */
- lease_seconds &= 0x0fffffff;
+
if (lease_seconds < 10)
lease_seconds = 10;
switch_listening_mode(dhcp_client, L2);
send_request(dhcp_client);
- if (dhcp_client->t2_timeout> 0)
+ if (dhcp_client->t2_timeout> 0) {
g_source_remove(dhcp_client->t2_timeout);
+ dhcp_client->t2_timeout = 0;
+ }
/*recalculate remaining rebind time*/
dhcp_client->T2 >>= 1;
return g_strdup(inet_ntoa(addr));
}
-/* get a rough idea of how long an option will be */
-static const uint8_t len_of_option_as_string[] = {
- [OPTION_IP] = sizeof("255.255.255.255 "),
- [OPTION_STRING] = 1,
- [OPTION_U8] = sizeof("255 "),
- [OPTION_U16] = sizeof("65535 "),
- [OPTION_U32] = sizeof("4294967295 "),
-};
-
-static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
-{
- return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
-}
-
-/* Create "opt_value1 option_value2 ..." string */
-static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
-{
- unsigned upper_length;
- int len, optlen;
- char *dest, *ret;
-
- len = option[OPT_LEN - OPT_DATA];
- type &= OPTION_TYPE_MASK;
- optlen = dhcp_option_lengths[type];
- if (optlen == 0)
- return NULL;
- upper_length = len_of_option_as_string[type] *
- ((unsigned)len / (unsigned)optlen);
- dest = ret = g_malloc(upper_length + 1);
- if (!ret)
- return NULL;
-
- while (len >= optlen) {
- switch (type) {
- case OPTION_IP:
- dest += sprint_nip(dest, "", option);
- break;
- case OPTION_U16: {
- uint16_t val_u16 = get_be16(option);
- dest += sprintf(dest, "%u", val_u16);
- break;
- }
- case OPTION_U32: {
- uint32_t val_u32 = get_be32(option);
- dest += sprintf(dest, "%u", val_u32);
- break;
- }
- case OPTION_STRING:
- memcpy(dest, option, len);
- dest[len] = '\0';
- return ret;
- default:
- break;
- }
- option += optlen;
- len -= optlen;
- if (len <= 0)
- break;
- *dest++ = ' ';
- *dest = '\0';
- }
-
- return ret;
-}
-
static GList *get_option_value_list(char *value, GDHCPOptionType type)
{
char *pos = value;
if (dhcp_client->type == G_DHCP_IPV6) {
re = dhcpv6_recv_l3_packet(&packet6, buf, sizeof(buf),
dhcp_client->listener_sockfd);
+ if (re < 0)
+ return TRUE;
pkt_len = re;
pkt = packet6;
xid = packet6->transaction_id[0] << 16 |
return TRUE;
}
- if (!message_type && !client_id)
- /* No message type / client id option, ignore package */
- return TRUE;
-
debug(dhcp_client, "received DHCP packet xid 0x%04x "
"(current state %d)", ntohl(xid), dhcp_client->state);
dhcp_client->lease_seconds = get_lease(&packet);
+#if defined TIZEN_EXT
+ dhcp_client->dhcp_lease_seconds = dhcp_client->lease_seconds;
+#endif
+
get_request(dhcp_client, &packet);
switch_listening_mode(dhcp_client, L_NONE);
remove_timeouts(dhcp_client);
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot) {
+ g_dhcp_client_set_address_known(dhcp_client, FALSE);
+ dhcp_client->timeout = g_idle_add_full(
+ G_PRIORITY_HIGH,
+ restart_dhcp_timeout,
+ dhcp_client,
+ NULL);
+
+ break;
+ }
+#endif
dhcp_client->timeout = g_timeout_add_seconds_full(
G_PRIORITY_HIGH, 3,
restart_dhcp_timeout,
GDHCPClient *dhcp_client = dhcp_data;
uint32_t ip;
+#if defined TIZEN_EXT
+ if (!dhcp_client)
+ return FALSE;
+#endif
+
debug(dhcp_client, "request timeout (retries %d)",
dhcp_client->retry_times);
uint32_t addr;
uint64_t rand;
+#if defined TIZEN_EXT
+ int discover_retry = 0;
+ int timeout = 0;
+#endif
+
remove_timeouts(dhcp_client);
if (dhcp_client->type == G_DHCP_IPV6) {
return 0;
}
+#if defined TIZEN_EXT
+ if (g_ascii_strncasecmp(dhcp_client->interface, "wlan", 4)
+ == 0) {
+ discover_retry = DISCOVER_RETRIES_WIFI;
+ timeout = DISCOVER_TIMEOUT_WIFI;
+ } else {
+ discover_retry = DISCOVER_RETRIES;
+ timeout = DISCOVER_TIMEOUT;
+ }
+
+ debug(dhcp_client, "[DHCPC] Discover retry/total : [%d]/[%d] timeout [%d]",
+ dhcp_client->retry_times, discover_retry, timeout);
+#endif
+
+
if (dhcp_client->type == G_DHCP_IPV4LL) {
dhcp_client->state = INIT_SELECTING;
ipv4ll_start(dhcp_client);
return 0;
}
- if (dhcp_client->retry_times == DISCOVER_RETRIES) {
+#if defined TIZEN_EXT
+ if (dhcp_client->retry_times == discover_retry) {
+#else
+ if (dhcp_client->retry_times == DISCOVER_RETRIES) {
+#endif
if (dhcp_client->no_lease_cb)
dhcp_client->no_lease_cb(dhcp_client,
dhcp_client->no_lease_data);
dhcp_client->timeout = g_timeout_add_seconds_full(
G_PRIORITY_HIGH,
+#if defined TIZEN_EXT
+ timeout,
+#else
REQUEST_TIMEOUT,
+#endif
reboot_timeout,
dhcp_client,
NULL);
send_discover(dhcp_client, addr);
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+#if defined TIZEN_EXT
+ timeout,
+#else
DISCOVER_TIMEOUT,
+#endif
discover_timeout,
dhcp_client,
NULL);
if (!dhcp_client)
return NULL;
+#if defined TIZEN_EXT
+ return get_ip(htonl(dhcp_client->server_ip));
+#else
return get_ip(dhcp_client->server_ip);
+#endif
+}
+
+#if defined TIZEN_EXT
+int g_dhcp_client_get_dhcp_lease_duration(GDHCPClient *dhcp_client)
+{
+ return dhcp_client->dhcp_lease_seconds;
}
+#endif
char *g_dhcp_client_get_address(GDHCPClient *dhcp_client)
{
return G_DHCP_CLIENT_ERROR_NONE;
}
- /* Now only support send hostname */
+ /* Now only support send hostname and vendor class ID */
GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client,
unsigned char option_code, const char *option_value)
{
uint8_t *binary_option;
- if (option_code == G_DHCP_HOST_NAME && option_value) {
+ if ((option_code == G_DHCP_HOST_NAME ||
+ option_code == G_DHCP_VENDOR_CLASS_ID) && option_value) {
binary_option = alloc_dhcp_string_option(option_code,
option_value);
if (!binary_option)
g_hash_table_destroy(dhcp_client->send_value_hash);
g_free(dhcp_client);
+#if defined TIZEN_EXT
+ dhcp_client = NULL;
+#endif
}
void g_dhcp_client_set_debug(GDHCPClient *dhcp_client,
return copy;
}
+
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *dhcp_client, gboolean known)
+{
+ /* DHCPREQUEST during INIT-REBOOT state (rfc2131)
+ * 4.4.3 Initialization with known network address
+ * 4.3.2 DHCPREQUEST generated during INIT-REBOOT state
+ */
+ debug(dhcp_client, "known network address (%d)", known);
+
+ if (dhcp_client->init_reboot == known)
+ return;
+
+ dhcp_client->init_reboot = known;
+}
+#endif
{ OPTION_IP | OPTION_LIST, 0x06 }, /* domain-name-servers */
{ OPTION_STRING, 0x0c }, /* hostname */
{ OPTION_STRING, 0x0f }, /* domain-name */
+ { OPTION_U16, 0x1a }, /* mtu */
{ OPTION_IP | OPTION_LIST, 0x2a }, /* ntp-servers */
{ OPTION_U32, 0x33 }, /* dhcp-lease-time */
/* Options below will not be exposed to user */
return i;
}
+/* get a rough idea of how long an option will be */
+static const uint8_t len_of_option_as_string[] = {
+ [OPTION_IP] = sizeof("255.255.255.255 "),
+ [OPTION_STRING] = 1,
+ [OPTION_U8] = sizeof("255 "),
+ [OPTION_U16] = sizeof("65535 "),
+ [OPTION_U32] = sizeof("4294967295 "),
+};
+
+static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
+{
+ return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
+}
+
+/* Create "opt_value1 option_value2 ..." string */
+char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
+{
+ unsigned upper_length;
+ int len, optlen;
+ char *dest, *ret;
+
+ len = option[OPT_LEN - OPT_DATA];
+ type &= OPTION_TYPE_MASK;
+ optlen = dhcp_option_lengths[type];
+ if (optlen == 0)
+ return NULL;
+ upper_length = len_of_option_as_string[type] *
+ ((unsigned)len / (unsigned)optlen);
+ dest = ret = g_malloc(upper_length + 1);
+ if (ret == NULL)
+ return NULL;
+
+ while (len >= optlen) {
+ switch (type) {
+ case OPTION_IP:
+ dest += sprint_nip(dest, "", option);
+ break;
+ case OPTION_U16: {
+ uint16_t val_u16 = get_be16(option);
+ dest += sprintf(dest, "%u", val_u16);
+ break;
+ }
+ case OPTION_U32: {
+ uint32_t val_u32 = get_be32(option);
+ dest += sprintf(dest, "%u", val_u32);
+ break;
+ }
+ case OPTION_STRING:
+ memcpy(dest, option, len);
+ dest[len] = '\0';
+ return ret;
+ default:
+ break;
+ }
+ option += optlen;
+ len -= optlen;
+ if (len <= 0)
+ break;
+ *dest++ = ' ';
+ *dest = '\0';
+ }
+
+ return ret;
+}
+
uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
int code, uint16_t *option_len, int *option_count)
{
if (fd < 0)
return -errno;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+ int err = errno;
+ close(fd);
+ return -err;
+ }
memset(&src, 0, sizeof(src));
src.sin6_family = AF_INET6;
src.sin6_port = htons(DHCPV6_CLIENT_PORT);
if (bind(fd, (struct sockaddr *) &src, sizeof(src)) <0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
memset(&dst, 0, sizeof(dst));
offsetof(struct ip_udp_dhcp_packet, udp),
};
- fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
+ fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return -errno;
dest.sll_halen = 6;
memcpy(dest.sll_addr, dest_arp, 6);
if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
packet.ip.protocol = IPPROTO_UDP;
*/
n = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0,
(struct sockaddr *) &dest, sizeof(dest));
- close(fd);
+ if (n < 0) {
+ int err = errno;
+ close(fd);
+ return -err;
+ }
- if (n < 0)
- return -errno;
+ close(fd);
return n;
}
if (fd < 0)
return -errno;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+ int err = errno;
+ close(fd);
+ return -err;
+ }
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(source_port);
client.sin_addr.s_addr = htonl(source_ip);
if (bind(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
memset(&client, 0, sizeof(client));
client.sin_port = htons(dest_port);
client.sin_addr.s_addr = htonl(dest_ip);
if (connect(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
n = write(fd, dhcp_pkt, DHCP_SIZE);
+ if (n < 0) {
+ int err = errno;
+ close(fd);
+ return -err;
+ }
close(fd);
- if (n < 0)
- return -errno;
-
return n;
}
if (fd < 0)
return -errno;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+ int err = errno;
+ close(fd);
+ return -err;
+ }
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
interface, strlen(interface) + 1) < 0) {
+ int err = errno;
close(fd);
- return -1;
+ return -err;
}
if (family == AF_INET) {
#define G_DHCP_DNS_SERVER 0x06
#define G_DHCP_DOMAIN_NAME 0x0f
#define G_DHCP_HOST_NAME 0x0c
+ #define G_DHCP_MTU 0x1a
#define G_DHCP_NTP_SERVER 0x2a
+ #define G_DHCP_VENDOR_CLASS_ID 0x3c
#define G_DHCP_CLIENT_ID 0x3d
#define G_DHCPV6_CLIENTID 1
const char *option_value);
char *g_dhcp_client_get_server_address(GDHCPClient *client);
+
+#if defined TIZEN_EXT
+int g_dhcp_client_get_dhcp_lease_duration(GDHCPClient *client);
+#endif
+
char *g_dhcp_client_get_address(GDHCPClient *client);
char *g_dhcp_client_get_netmask(GDHCPClient *client);
GList *g_dhcp_client_get_option(GDHCPClient *client,
typedef struct _GDHCPServer GDHCPServer;
+typedef void (*GDHCPSaveACKLeaseFunc) (char *hostname,
+ unsigned char *mac, unsigned int nip);
+
GDHCPServer *g_dhcp_server_new(GDHCPType type,
int ifindex, GDHCPServerError *error);
int g_dhcp_server_start(GDHCPServer *server);
GDHCPSaveLeaseFunc func, gpointer user_data);
void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server,
GDHCPLeaseAddedCb cb);
+void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
+ GDHCPSaveACKLeaseFunc func, gpointer user_data);
int dhcp_get_random(uint64_t *val);
void dhcp_cleanup_random(void);
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *client, gboolean known);
+#endif
+
#ifdef __cplusplus
}
#endif
uint32_t ip_target;
int fd, n;
- fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ARP));
+ fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return -errno;
dest.sll_halen = ETH_ALEN;
memset(dest.sll_addr, 0xFF, ETH_ALEN);
if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
ip_source = htonl(source_ip);
int fd;
struct sockaddr_ll sock;
- fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ARP));
+ fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return fd;
sock.sll_ifindex = ifindex;
if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) {
+ int err = errno;
close(fd);
- return -errno;
+ return -err;
}
return fd;
GHashTable *option_hash; /* Options send to client */
GDHCPSaveLeaseFunc save_lease_func;
GDHCPLeaseAddedCb lease_added_cb;
+ GDHCPSaveACKLeaseFunc save_ack_lease_func;
GDHCPDebugFunc debug_func;
gpointer debug_data;
};
g_hash_table_insert(dhcp_server->nip_lease_hash,
GINT_TO_POINTER((int) lease->lease_nip), lease);
- if (dhcp_server->lease_added_cb)
- dhcp_server->lease_added_cb(lease->lease_mac, yiaddr);
-
return lease;
}
dhcp_server->listener_watch = -1;
dhcp_server->listener_channel = NULL;
dhcp_server->save_lease_func = NULL;
+ dhcp_server->save_ack_lease_func = NULL;
dhcp_server->debug_func = NULL;
dhcp_server->debug_data = NULL;
send_packet_to_client(dhcp_server, &packet);
add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);
+
+ if (dhcp_server->lease_added_cb)
+ dhcp_server->lease_added_cb(packet.chaddr, packet.yiaddr);
}
static void send_NAK(GDHCPServer *dhcp_server,
struct dhcp_packet packet;
struct dhcp_lease *lease;
uint32_t requested_nip = 0;
- uint8_t type, *server_id_option, *request_ip_option;
+ uint8_t type, *server_id_option, *request_ip_option, *host_name;
int re;
+ GDHCPOptionType option_type;
+ char *option_value;
+
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
dhcp_server->listener_watch = 0;
return FALSE;
if (lease && requested_nip == lease->lease_nip) {
debug(dhcp_server, "Sending ACK");
+
+ host_name = dhcp_get_option(&packet, DHCP_HOST_NAME);
+ option_type = dhcp_get_code_type(DHCP_HOST_NAME);
+ option_value = malloc_option_value_string(host_name,
+ option_type);
send_ACK(dhcp_server, &packet,
lease->lease_nip);
+
+ if (dhcp_server->save_ack_lease_func)
+ dhcp_server->save_ack_lease_func(
+ option_value,
+ lease->lease_mac,
+ lease->lease_nip);
+ g_free(option_value);
+
break;
}
dhcp_server->lease_added_cb = cb;
}
+void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
+ GDHCPSaveACKLeaseFunc func, gpointer user_data)
+{
+ if (dhcp_server == NULL)
+ return;
+
+ dhcp_server->save_ack_lease_func = func;
+}
+
GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server)
{
if (!dhcp_server)
#define G_SUPPLICANT_KEYMGMT_WPA_NONE (1 << 2)
#define G_SUPPLICANT_KEYMGMT_WPA_PSK (1 << 3)
#define G_SUPPLICANT_KEYMGMT_WPA_PSK_256 (1 << 4)
+#if defined TIZEN_EXT
+#define G_SUPPLICANT_KEYMGMT_WPA_FT_EAP (1 << 5)
+#define G_SUPPLICANT_KEYMGMT_WPA_FT_PSK (1 << 6)
+#else
#define G_SUPPLICANT_KEYMGMT_WPA_FT_PSK (1 << 5)
#define G_SUPPLICANT_KEYMGMT_WPA_FT_EAP (1 << 6)
+#endif
#define G_SUPPLICANT_KEYMGMT_WPA_EAP (1 << 7)
#define G_SUPPLICANT_KEYMGMT_WPA_EAP_256 (1 << 8)
#define G_SUPPLICANT_KEYMGMT_WPS (1 << 9)
G_SUPPLICANT_SECURITY_WEP,
G_SUPPLICANT_SECURITY_PSK,
G_SUPPLICANT_SECURITY_IEEE8021X,
+#if defined TIZEN_EXT
+ G_SUPPLICANT_SECURITY_FT_PSK,
+ G_SUPPLICANT_SECURITY_FT_IEEE8021X,
+#endif
} GSupplicantSecurity;
typedef enum {
G_SUPPLICANT_PEER_GROUP_FAILED,
} GSupplicantPeerState;
+enum GSupplicantAPHiddenSSID {
+ G_SUPPLICANT_AP_NO_SSID_HIDING,
+ G_SUPPLICANT_AP_HIDDEN_SSID_ZERO_LEN,
+ G_SUPPLICANT_AP_HIDDEN_SSID_ZERO_CONTENTS,
+};
+
struct _GSupplicantSSID {
const void *ssid;
unsigned int ssid_len;
const char *eap;
const char *passphrase;
const char *identity;
+ const char *anonymous_identity;
const char *ca_cert_path;
+ const char *subject_match;
+ const char *altsubject_match;
+ const char *domain_suffix_match;
+ const char *domain_match;
const char *client_cert_path;
const char *private_key_path;
const char *private_key_passphrase;
dbus_bool_t use_wps;
const char *pin_wps;
const char *bgscan;
+ int ignore_broadcast_ssid;
+#if defined TIZEN_EXT
+ unsigned char *bssid;
+#endif
};
typedef struct _GSupplicantSSID GSupplicantSSID;
+/*
+ * Max number of SSIDs that can be scanned.
+ * In wpa_s 0.7x the limit is 4.
+ * In wps_s 0.8 or later it is 16.
+ * The value is only used if wpa_supplicant does not return any max limit
+ * for number of scannable SSIDs.
+ */
+#define WPAS_MAX_SCAN_SSIDS 4
+
struct scan_ssid {
unsigned char ssid[32];
uint8_t ssid_len;
GSupplicantInterfaceCallback callback,
void *user_data);
+#if defined TIZEN_EXT
+int g_supplicant_interface_remove_network(GSupplicantInterface *interface);
+#endif
int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
unsigned int ap_scan);
bool g_supplicant_peer_is_client(GSupplicantPeer *peer);
bool g_supplicant_peer_has_requested_connection(GSupplicantPeer *peer);
- void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network);
+#if defined TIZEN_EXT
+/*
+* Description: Network client requires additional wifi specific info
+*/
+const unsigned char *g_supplicant_network_get_bssid(
+ GSupplicantNetwork *network);
+unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network);
+const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network);
+bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network);
+bool g_supplicant_network_is_hs20AP(GSupplicantNetwork *network);
+const char *g_supplicant_network_get_eap(GSupplicantNetwork *network);
+const char *g_supplicant_network_get_identity(GSupplicantNetwork *network);
+const char *g_supplicant_network_get_phase2(GSupplicantNetwork *network);
+unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network);
++const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
++ unsigned int *wifi_vsie_len);
+#endif
+
struct _GSupplicantCallbacks {
void (*system_ready) (void);
void (*system_killed) (void);
void (*p2p_support) (GSupplicantInterface *interface);
void (*scan_started) (GSupplicantInterface *interface);
void (*scan_finished) (GSupplicantInterface *interface);
+ void (*ap_create_fail) (GSupplicantInterface *interface);
void (*network_added) (GSupplicantNetwork *network);
void (*network_removed) (GSupplicantNetwork *network);
+#if defined TIZEN_EXT
+ void (*network_merged) (GSupplicantNetwork *network);
+#endif
void (*network_changed) (GSupplicantNetwork *network,
const char *property);
+ void (*network_associated) (GSupplicantNetwork *network);
+#if defined TIZEN_EXT
+ void (*system_power_off) (void);
+ void (*assoc_failed) (void *user_data);
+#endif
+ void (*add_station) (const char *mac);
+ void (*remove_station) (const char *mac);
void (*peer_found) (GSupplicantPeer *peer);
void (*peer_lost) (GSupplicantPeer *peer);
void (*peer_changed) (GSupplicantPeer *peer,
void (*peer_request) (GSupplicantPeer *peer);
void (*debug) (const char *str);
void (*disconnect_reasoncode)(GSupplicantInterface *interface,
- int reasoncode);
+ int reasoncode);
void (*assoc_status_code)(GSupplicantInterface *interface,
int reasoncode);
};
static GHashTable *peer_mapping;
static GHashTable *group_mapping;
static GHashTable *pending_peer_connection;
+ static GHashTable *config_file_table;
struct _GSupplicantWpsCredentials {
unsigned char ssid[32];
char *key;
};
+ struct added_network_information {
+ char * ssid;
+ GSupplicantSecurity security;
+ char * passphrase;
+ char * private_passphrase;
+ };
+
struct _GSupplicantInterface {
char *path;
char *network_path;
unsigned int max_scan_ssids;
bool p2p_support;
bool p2p_finding;
+ bool ap_create_in_progress;
dbus_bool_t ready;
GSupplicantState state;
dbus_bool_t scanning;
GHashTable *network_table;
GHashTable *peer_table;
GHashTable *group_table;
- GHashTable *net_mapping;
GHashTable *bss_mapping;
void *data;
const char *pending_peer_path;
+ GSupplicantNetwork *current_network;
+ struct added_network_information network_info;
+#if defined TIZEN_EXT
+ int disconnect_reason;
+#endif
};
struct g_supplicant_bss {
dbus_bool_t privacy;
dbus_bool_t psk;
dbus_bool_t ieee8021x;
- GSList *vsie_list;
+#if defined TIZEN_EXT
+ dbus_bool_t ft_psk;
+ dbus_bool_t ft_ieee8021x;
++ char *wifi_vsie;
++ unsigned int wifi_vsie_len;
+ dbus_bool_t hs20;
+#endif
unsigned int wps_capabilities;
};
unsigned int wps_capabilities;
GHashTable *bss_table;
GHashTable *config_table;
- GSList *vsie_list;
+#if defined TIZEN_EXT
+ bool isHS20AP;
+ char *eap;
+ char *identity;
+ char *phase2;
+ unsigned int keymgmt;
++ char *wifi_vsie;
++ unsigned int wifi_vsie_len;
+#endif
};
struct _GSupplicantPeer {
GSList *members;
};
+ struct interface_data {
+ GSupplicantInterface *interface;
+ char *path; /* Interface path cannot be taken from interface (above) as
+ * it might have been freed already.
+ */
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+ bool network_remove_in_progress;
+ GSupplicantSSID *ssid;
+ };
+
+ struct interface_create_data {
+ char *ifname;
+ char *driver;
+ char *bridge;
+ GSupplicantInterface *interface;
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+ };
+
+ struct interface_connect_data {
+ GSupplicantInterface *interface;
+ char *path;
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+ union {
+ GSupplicantSSID *ssid;
+ GSupplicantPeerParams *peer;
+ };
+ };
+
+ struct interface_scan_data {
+ GSupplicantInterface *interface;
+ char *path;
+ GSupplicantInterfaceCallback callback;
+ GSupplicantScanParams *scan_params;
+ void *user_data;
+ };
+
+ static int network_remove(struct interface_data *data);
+
static inline void debug(const char *format, ...)
{
char str[256];
va_list ap;
- if (!callbacks_pointer->debug)
+ if (!callbacks_pointer || !callbacks_pointer->debug)
return;
va_start(ap, format);
return "psk";
case G_SUPPLICANT_SECURITY_IEEE8021X:
return "ieee8021x";
+#if defined TIZEN_EXT
+ case G_SUPPLICANT_SECURITY_FT_PSK:
+ return "ft_psk";
+ case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
+ return "ft_ieee8021x";
+#endif
}
return NULL;
return G_SUPPLICANT_STATE_UNKNOWN;
}
+ static bool compare_network_parameters(GSupplicantInterface *interface,
+ GSupplicantSSID *ssid)
+ {
+ if (memcmp(interface->network_info.ssid, ssid->ssid, ssid->ssid_len))
+ return FALSE;
+
+ if (interface->network_info.security != ssid->security)
+ return FALSE;
+
+ if (interface->network_info.passphrase &&
+ g_strcmp0(interface->network_info.passphrase,
+ ssid->passphrase) != 0) {
+ return FALSE;
+ }
+
+ if (interface->network_info.private_passphrase &&
+ g_strcmp0(interface->network_info.private_passphrase,
+ ssid->private_key_passphrase) != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ static void remove_network_information(GSupplicantInterface * interface)
+ {
+ g_free(interface->network_info.ssid);
+ g_free(interface->network_info.passphrase);
+ g_free(interface->network_info.private_passphrase);
+ interface->network_info.ssid = NULL;
+ interface->network_info.passphrase = NULL;
+ interface->network_info.private_passphrase = NULL;
+ }
+
+ static int store_network_information(GSupplicantInterface * interface,
+ GSupplicantSSID *ssid)
+ {
+ interface->network_info.ssid = g_malloc(ssid->ssid_len + 1);
+ if (interface->network_info.ssid != NULL) {
+ memcpy(interface->network_info.ssid, ssid->ssid,
+ ssid->ssid_len);
+ interface->network_info.ssid[ssid->ssid_len] = '\0';
+ } else {
+ return -ENOMEM;
+ }
+
+ interface->network_info.security = ssid->security;
+
+ if ((ssid->security == G_SUPPLICANT_SECURITY_WEP ||
+ ssid->security == G_SUPPLICANT_SECURITY_PSK ||
+ ssid->security == G_SUPPLICANT_SECURITY_NONE) &&
+ ssid->passphrase) {
+ interface->network_info.passphrase = g_strdup(ssid->passphrase);
+ }
+
+ if (ssid->security == G_SUPPLICANT_SECURITY_IEEE8021X &&
+ ssid->private_key_passphrase) {
+ interface->network_info.private_passphrase =
+ g_strdup(ssid->private_key_passphrase);
+ }
+
+ return 0;
+ }
+
static void callback_system_ready(void)
{
if (system_ready)
callbacks_pointer->interface_removed(interface);
}
+#if !defined TIZEN_EXT
static void callback_p2p_support(GSupplicantInterface *interface)
{
SUPPLICANT_DBG("");
if (callbacks_pointer && callbacks_pointer->p2p_support)
callbacks_pointer->p2p_support(interface);
}
+#endif
static void callback_scan_started(GSupplicantInterface *interface)
{
callbacks_pointer->scan_started(interface);
}
+ static void callback_ap_create_fail(GSupplicantInterface *interface)
+ {
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->ap_create_fail)
+ return;
+
+ callbacks_pointer->ap_create_fail(interface);
+ }
+
static void callback_scan_finished(GSupplicantInterface *interface)
{
if (!callbacks_pointer)
callbacks_pointer->network_removed(network);
}
+#if defined TIZEN_EXT
+static void callback_network_merged(GSupplicantNetwork *network)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->network_merged)
+ return;
+
+ callbacks_pointer->network_merged(network);
+}
+
+static void callback_assoc_failed(void *user_data)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->assoc_failed)
+ return;
+
+ callbacks_pointer->assoc_failed(user_data);
+}
+#endif
+
static void callback_network_changed(GSupplicantNetwork *network,
const char *property)
{
callbacks_pointer->network_changed(network, property);
}
+ static void callback_network_associated(GSupplicantNetwork *network)
+ {
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->network_associated)
+ return;
+
+ callbacks_pointer->network_associated(network);
+ }
+
static void callback_peer_found(GSupplicantPeer *peer)
{
if (!callbacks_pointer)
GSupplicantInterface *interface = data;
g_hash_table_destroy(interface->bss_mapping);
- g_hash_table_destroy(interface->net_mapping);
g_hash_table_destroy(interface->network_table);
g_hash_table_destroy(interface->peer_table);
g_hash_table_destroy(interface->group_table);
g_free(interface->wps_cred.key);
g_free(interface->path);
g_free(interface->network_path);
+#if defined TIZEN_EXT
+ interface->network_path = NULL;
+#endif
g_free(interface->ifname);
g_free(interface->driver);
g_free(interface->bridge);
+ remove_network_information(interface);
g_free(interface);
}
g_free(network->path);
g_free(network->group);
g_free(network->name);
- g_slist_free_full(network->vsie_list, g_free);
+#if defined TIZEN_EXT
+ g_free(network->eap);
+ g_free(network->identity);
+ g_free(network->phase2);
+#endif
+#if defined TIZEN_EXT
++ g_free(network->wifi_vsie);
+#endif
+
g_free(network);
}
struct g_supplicant_bss *bss = data;
g_free(bss->path);
- g_slist_free_full(bss->vsie_list, g_free);
+#if defined TIZEN_EXT
++ g_free(bss->wifi_vsie);
+#endif
g_free(bss);
}
g_free(peer->path);
g_free(peer->name);
g_free(peer->identifier);
+ g_free(peer->widi_ies);
g_free(peer);
}
key, dbus_message_iter_get_arg_type(iter));
}
+ struct set_apscan_data
+ {
+ unsigned int ap_scan;
+ GSupplicantInterface *interface;
+ };
+
static void set_apscan(DBusMessageIter *iter, void *user_data)
{
- unsigned int ap_scan = *(unsigned int *)user_data;
+ struct set_apscan_data *data = user_data;
+ unsigned int ap_scan = data->ap_scan;
dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &ap_scan);
}
+ static void set_apscan_complete(const char *error,
+ DBusMessageIter *iter, void *user_data)
+ {
+ struct set_apscan_data *data = user_data;
+ GSupplicantInterface *interface = data->interface;
+
+ if (error) {
+ interface->ap_create_in_progress = false;
+ SUPPLICANT_DBG("Set AP scan error %s", error);
+ goto error;
+ }
+
+ interface->ap_create_in_progress = true;
+ error:
+ dbus_free(data);
+ }
+
int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
unsigned int ap_scan)
{
- return supplicant_dbus_property_set(interface->path,
+ struct set_apscan_data *data;
+ int ret;
+
+ data = dbus_malloc0(sizeof(*data));
+
+ if (!data)
+ return -ENOMEM;
+
+ data->ap_scan = ap_scan;
+ data->interface = interface;
+
+ ret = supplicant_dbus_property_set(interface->path,
SUPPLICANT_INTERFACE ".Interface",
- "ApScan", DBUS_TYPE_UINT32_AS_STRING,
- set_apscan, NULL, &ap_scan, NULL);
+ "ApScan", DBUS_TYPE_UINT32_AS_STRING,
+ set_apscan, set_apscan_complete, data, NULL);
+ if (ret < 0)
+ dbus_free(data);
+
+ return ret;
}
void g_supplicant_interface_set_data(GSupplicantInterface *interface,
if (!interface)
return 0;
+ if (interface->max_scan_ssids == 0)
+ return WPAS_MAX_SCAN_SSIDS;
+
return interface->max_scan_ssids;
}
return peer->name;
}
+#if defined TIZEN_EXT
+bool g_supplicant_network_is_hs20AP(GSupplicantNetwork *network)
+{
+ if (!network)
+ return 0;
+
+ return network->isHS20AP;
+}
+
+const char *g_supplicant_network_get_eap(GSupplicantNetwork *network)
+{
+ if (!network || !network->eap)
+ return NULL;
+
+ return network->eap;
+}
+
+const char *g_supplicant_network_get_identity(GSupplicantNetwork *network)
+{
+ if (!network || !network->identity)
+ return NULL;
+
+ return network->identity;
+}
+
+const char *g_supplicant_network_get_phase2(GSupplicantNetwork *network)
+{
+ if (!network || !network->phase2)
+ return NULL;
+
+ return network->phase2;
+}
+
+unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return 0;
+
+ return network->keymgmt;
+}
+#endif
+
const unsigned char *g_supplicant_peer_get_widi_ies(GSupplicantPeer *peer,
int *length)
{
return peer->connection_requested;
}
- void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+const unsigned char *g_supplicant_network_get_bssid(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
+
+ return (const unsigned char *)network->best_bss->bssid;
+}
+
+unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return 0;
+
+ return network->best_bss->maxrate;
+}
+
+const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
+
+ if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
+ unsigned int pairwise;
+
+ pairwise = network->best_bss->rsn_pairwise |
+ network->best_bss->wpa_pairwise;
+
+ if ((pairwise & G_SUPPLICANT_PAIRWISE_CCMP) &&
+ (pairwise & G_SUPPLICANT_PAIRWISE_TKIP))
+ return "mixed";
+ else if (pairwise & G_SUPPLICANT_PAIRWISE_CCMP)
+ return "aes";
+ else if (pairwise & G_SUPPLICANT_PAIRWISE_TKIP)
+ return "tkip";
+
+ } else if (network->best_bss->security == G_SUPPLICANT_SECURITY_WEP)
+ return "wep";
+ else if (network->best_bss->security == G_SUPPLICANT_SECURITY_NONE)
+ return "none";
+
+ return NULL;
+}
+
+bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return 0;
+
+ if (network->best_bss->rsn_selected) {
+ const char *mode = g_supplicant_network_get_enc_mode(network);
+ if (g_strcmp0(mode, "aes") == 0 ||
+ g_strcmp0(mode, "mixed") == 0)
+ return true;
+ else
+ return false;
+ } else
+ return false;
+}
+
- GSList *vsie_list = NULL;
-
- if (!network)
++const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
++ unsigned int *wifi_vsie_len)
+{
-
- if (g_slist_length(network->vsie_list) > 0) {
- GSList *list = NULL;
- unsigned char *vsie = NULL;
- for (list = network->vsie_list; list; list = list->next) {
- unsigned char *ie = (unsigned char *)list->data;
- vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
-
- if (vsie) {
- memcpy(vsie, ie, ie[1]+2);
- vsie_list = g_slist_append(vsie_list, vsie);
- } else
- SUPPLICANT_DBG("Failed to allocate memory");
- }
++ if (!network) {
++ *wifi_vsie_len = 0;
+ return NULL;
- return vsie_list;
+ }
+
++ *wifi_vsie_len = network->wifi_vsie_len;
++ return network->wifi_vsie;
+}
+#endif
+
static void merge_network(GSupplicantNetwork *network)
{
GString *str;
const char *ssid, *mode, *key_mgmt;
+#if defined TIZEN_EXT
+ GSupplicantInterface *interface;
+ const char *isHS20AP;
+ const char *eap, *identity, *phase2;
+#endif
unsigned int i, ssid_len;
char *group;
ssid = g_hash_table_lookup(network->config_table, "ssid");
mode = g_hash_table_lookup(network->config_table, "mode");
key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
+#if defined TIZEN_EXT
+ isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
+ eap = g_hash_table_lookup(network->config_table, "eap");
+ identity = g_hash_table_lookup(network->config_table, "identity");
+ phase2 = g_hash_table_lookup(network->config_table, "phase2");
+ interface = network->interface;
+#endif
SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
return;
for (i = 0; i < ssid_len; i++)
+#if defined TIZEN_EXT
+ {
+ if (ssid[i] != '"')
+#endif
g_string_append_printf(str, "%02x", ssid[i]);
+#if defined TIZEN_EXT
+ }
+#endif
if (g_strcmp0(mode, "0") == 0)
g_string_append_printf(str, "_managed");
if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
g_string_append_printf(str, "_psk");
+#if defined TIZEN_EXT
+ else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
+ g_string_append_printf(str, "_ieee8021x");
+ else
+ g_string_append_printf(str, "_none");
+#endif
group = g_string_free(str, FALSE);
SUPPLICANT_DBG("%s", group);
+#if defined TIZEN_EXT
+ if (g_strcmp0(isHS20AP, "1") == 0) {
+ network->isHS20AP = 1;
+ if (network->eap)
+ g_free(network->eap);
+ network->eap = g_strdup(eap);
+
+ if (network->identity)
+ g_free(network->identity);
+ network->identity = g_strdup(identity);
+
+ if (network->phase2)
+ g_free(network->phase2);
+ network->phase2 = g_strdup(phase2);
+ } else
+ network->isHS20AP = 0;
+
+ if (interface)
+ interface->network_path = g_strdup(network->path);
+
+ network->group = g_strdup(group);
+ callback_network_merged(network);
+#endif
+
g_free(group);
g_hash_table_destroy(network->config_table);
if (g_strcmp0(path, "/") == 0)
return;
- network = g_hash_table_lookup(interface->net_mapping, path);
- if (network)
- return;
-
network = g_try_new0(GSupplicantNetwork, 1);
if (!network)
return;
static void interface_network_removed(DBusMessageIter *iter, void *user_data)
{
- GSupplicantInterface *interface = user_data;
- GSupplicantNetwork *network;
- const char *path = NULL;
-
- dbus_message_iter_get_basic(iter, &path);
- if (!path)
- return;
-
- network = g_hash_table_lookup(interface->net_mapping, path);
- if (!network)
- return;
-
- g_hash_table_remove(interface->net_mapping, path);
+ SUPPLICANT_DBG("");
+ return;
}
static char *create_name(unsigned char *ssid, int ssid_len)
return g_string_free(str, FALSE);
}
- static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
+ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
{
GSupplicantInterface *interface = bss->interface;
GSupplicantNetwork *network;
SUPPLICANT_DBG("New group created: %s", group);
if (!group)
- return;
+ return -ENOMEM;
network = g_hash_table_lookup(interface->network_table, group);
if (network) {
network = g_try_new0(GSupplicantNetwork, 1);
if (!network) {
g_free(group);
- return;
+ return -ENOMEM;
}
network->interface = interface;
network->frequency = bss->frequency;
network->best_bss = bss;
- if (g_slist_length(bss->vsie_list) > 0) {
- GSList *list = NULL;
- unsigned char *vsie = NULL;
- for (list = bss->vsie_list; list; list = list->next) {
- unsigned char *ie = (unsigned char *)list->data;
- vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
-
- if (vsie) {
- memcpy(vsie, ie, ie[1]+2);
- network->vsie_list = g_slist_append(network->vsie_list, vsie);
- } else
- SUPPLICANT_DBG("Failed to allocate memory.");
+#if defined TIZEN_EXT
+ network->keymgmt = bss->keymgmt;
+
++ if (bss->wifi_vsie_len > 0) {
++ SUPPLICANT_DBG("vsie len: %d", bss->wifi_vsie_len);
++ network->wifi_vsie = (char *)g_try_malloc0(bss->wifi_vsie_len);
++ if(network->wifi_vsie) {
++ network->wifi_vsie_len = bss->wifi_vsie_len;
++ memcpy(network->wifi_vsie, bss->wifi_vsie, network->wifi_vsie_len);
++ } else {
++ SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
+ }
+ }
+
+ network->isHS20AP = bss->hs20;
+#endif
+
SUPPLICANT_DBG("New network %s created", network->name);
network->bss_table = g_hash_table_new_full(g_str_hash, g_str_equal,
network->wps_capabilities |= bss->wps_capabilities;
}
- if (bss->signal > network->signal) {
+ /*
+ * Do not change best BSS if we are connected. It will be done through
+ * CurrentBSS property in case of misalignment with wpa_s or roaming.
+ */
+ if (network != interface->current_network &&
+ bss->signal > network->signal) {
network->signal = bss->signal;
network->best_bss = bss;
callback_network_changed(network, "Signal");
g_hash_table_replace(network->bss_table, bss->path, bss);
g_hash_table_replace(bss_mapping, bss->path, interface);
+
+ return 0;
}
static void bss_rates(DBusMessageIter *iter, void *user_data)
{
struct g_supplicant_bss *bss = user_data;
const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
++#if defined TIZEN_EXT
++ const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
++#endif
unsigned char *ie, *ie_end;
DBusMessageIter array;
unsigned int value;
#define WPS_PBC 0x04
#define WPS_PIN 0x00
#define WPS_CONFIGURED 0x02
+#if defined TIZEN_EXT
+#define VENDOR_SPECIFIC_INFO 0xDD
+#endif
dbus_message_iter_recurse(iter, &array);
dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
ie += ie[1] + 2) {
-
+#if defined TIZEN_EXT
- unsigned char *vsie;
- int vsie_len = 0;
- if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
- SUPPLICANT_DBG("IE: match vendor specific data");
-
- vsie_len = ie[1]+2; // tag number size(1), tag length size(1)
- vsie = (unsigned char *)g_try_malloc0(vsie_len);
-
- if (vsie) {
- memcpy(vsie, ie, vsie_len);
- bss->vsie_list = g_slist_append(bss->vsie_list, vsie);
- } else
- SUPPLICANT_DBG("Failed to allocate memory");
- continue;
++ if((ie[0] == VENDOR_SPECIFIC_INFO) && (memcmp(ie+2, WIFI_OUI, sizeof(WIFI_OUI)) == 0)) {
++ SUPPLICANT_DBG("IE: match WIFI_OUI");
++ bss->wifi_vsie = (char *)g_try_malloc0(ie[1] + 2); // tag number size(1), tag length size(1)
++ if (bss->wifi_vsie) {
++ bss->wifi_vsie_len = ie[1] + 2;
++ memcpy(bss->wifi_vsie, ie, bss->wifi_vsie_len);
++ } else {
++ SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
++ }
++ continue;
+ }
+#endif
if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
continue;
bss->ieee8021x = FALSE;
bss->psk = FALSE;
+#if defined TIZEN_EXT
+ bss->ft_ieee8021x = FALSE;
+ bss->ft_psk = FALSE;
+#endif
+#if defined TIZEN_EXT
+ if (bss->keymgmt &
+ (G_SUPPLICANT_KEYMGMT_WPA_EAP |
+ G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
+ bss->ieee8021x = TRUE;
+ else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_EAP)
+ bss->ft_ieee8021x = TRUE;
+#else
if (bss->keymgmt &
(G_SUPPLICANT_KEYMGMT_WPA_EAP |
G_SUPPLICANT_KEYMGMT_WPA_FT_EAP |
G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
bss->ieee8021x = TRUE;
+#endif
+#if defined TIZEN_EXT
+ if (bss->keymgmt &
+ (G_SUPPLICANT_KEYMGMT_WPA_PSK |
+ G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
+ bss->psk = TRUE;
+ else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
+ bss->ft_psk = TRUE;
+#else
if (bss->keymgmt &
(G_SUPPLICANT_KEYMGMT_WPA_PSK |
G_SUPPLICANT_KEYMGMT_WPA_FT_PSK |
G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
bss->psk = TRUE;
+#endif
if (bss->ieee8021x)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
else if (bss->psk)
bss->security = G_SUPPLICANT_SECURITY_PSK;
+#if defined TIZEN_EXT
+ else if (bss->ft_psk)
+ bss->security = G_SUPPLICANT_SECURITY_FT_PSK;
+ else if (bss->ft_ieee8021x == TRUE)
+ bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
+#endif
else if (bss->privacy)
bss->security = G_SUPPLICANT_SECURITY_WEP;
else
bss->rsn_selected = FALSE;
supplicant_dbus_property_foreach(iter, bss_wpa, bss);
+#if defined TIZEN_EXT
+ } else if (g_strcmp0(key, "HS20") == 0) {
+ dbus_bool_t hs20 = FALSE;
+ dbus_message_iter_get_basic(iter, &hs20);
+ bss->hs20 = hs20;
+#endif
} else if (g_strcmp0(key, "IEs") == 0)
bss_process_ies(iter, bss);
else
supplicant_dbus_property_foreach(iter, bss_property, bss);
bss_compute_security(bss);
- add_or_replace_bss_to_network(bss);
+ if (add_or_replace_bss_to_network(bss) < 0)
+ SUPPLICANT_DBG("add_or_replace_bss_to_network failed");
}
static void interface_bss_added_without_keys(DBusMessageIter *iter,
bss_property, bss, NULL);
bss_compute_security(bss);
- add_or_replace_bss_to_network(bss);
+ if (add_or_replace_bss_to_network(bss) < 0)
+ SUPPLICANT_DBG("add_or_replace_bss_to_network failed");
}
static void update_signal(gpointer key, gpointer value,
SUPPLICANT_DBG("New network signal %d", network->signal);
}
+ static void interface_current_bss(GSupplicantInterface *interface,
+ DBusMessageIter *iter)
+ {
+ GSupplicantNetwork *network;
+ struct g_supplicant_bss *bss;
+ const char *path;
+
+ dbus_message_iter_get_basic(iter, &path);
+ if (g_strcmp0(path, "/") == 0) {
+ interface->current_network = NULL;
+ return;
+ }
+
+ interface_bss_added_without_keys(iter, interface);
+
+ network = g_hash_table_lookup(interface->bss_mapping, path);
+ if (!network)
+ return;
+
+ bss = g_hash_table_lookup(network->bss_table, path);
+ if (!bss)
+ return;
+
+ interface->current_network = network;
+
+ if (bss != network->best_bss) {
+ /*
+ * This is the case where either wpa_s got associated
+ * to a BSS different than the one ConnMan considers
+ * the best, or we are roaming.
+ */
+ SUPPLICANT_DBG("Update best BSS for %s", network->name);
+
+ network->best_bss = bss;
+
+ if (network->signal != bss->signal) {
+ SUPPLICANT_DBG("New network signal %d dBm",
+ bss->signal);
+
+ network->signal = bss->signal;
+ callback_network_changed(network, "Signal");
+ }
+ }
+
+ /*
+ * wpa_s could notify about CurrentBSS in any state once
+ * it got associated. It is not sure such notification will
+ * arrive together with transition to ASSOCIATED state.
+ * In fact, for networks with security WEP or OPEN, it
+ * always arrives together with transition to COMPLETED.
+ */
+ switch (interface->state) {
+ case G_SUPPLICANT_STATE_UNKNOWN:
+ case G_SUPPLICANT_STATE_DISABLED:
+ case G_SUPPLICANT_STATE_DISCONNECTED:
+ case G_SUPPLICANT_STATE_INACTIVE:
+ case G_SUPPLICANT_STATE_SCANNING:
+ case G_SUPPLICANT_STATE_AUTHENTICATING:
+ case G_SUPPLICANT_STATE_ASSOCIATING:
+ return;
+ case G_SUPPLICANT_STATE_ASSOCIATED:
+ case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
+ case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
+ case G_SUPPLICANT_STATE_COMPLETED:
+ callback_network_associated(network);
+ break;
+ }
+ }
+
static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
{
GSupplicantInterface *interface = user_data;
static void set_config_methods(DBusMessageIter *iter, void *user_data)
{
- const char *config_methods = "push_button";
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
+ }
+
+ static void wps_property(const char *key, DBusMessageIter *iter,
+ void *user_data)
+ {
+ GSupplicantInterface *interface = user_data;
+
+ if (!interface)
+ return;
+
+ SUPPLICANT_DBG("key: %s", key);
+
+ if (g_strcmp0(key, "ConfigMethods") == 0) {
+ const char *config_methods = "push_button", *str = NULL;
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (str && strlen(str) > 0) {
+ /* It was already set at wpa_s level, don't modify it. */
+ SUPPLICANT_DBG("%s", str);
+ return;
+ }
+
+ supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface.WPS",
+ "ConfigMethods", DBUS_TYPE_STRING_AS_STRING,
+ set_config_methods, NULL, &config_methods, NULL);
+
+ SUPPLICANT_DBG("No value. Set %s", config_methods);
+ }
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
- &config_methods);
}
static void interface_property(const char *key, DBusMessageIter *iter,
debug_strvalmap("Mode capability", mode_capa_map,
interface->mode_capa);
-
- supplicant_dbus_property_set(interface->path,
+ supplicant_dbus_property_get_all(interface->path,
SUPPLICANT_INTERFACE ".Interface.WPS",
- "ConfigMethods", DBUS_TYPE_STRING_AS_STRING,
- set_config_methods, NULL, NULL, NULL);
+ wps_property, interface, interface);
if (interface->ready)
callback_interface_added(interface);
if (g_strcmp0(key, "Capabilities") == 0) {
supplicant_dbus_property_foreach(iter, interface_capability,
interface);
+#if !defined TIZEN_EXT
if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_P2P)
interface->p2p_support = true;
+#endif
} else if (g_strcmp0(key, "State") == 0) {
const char *str = NULL;
interface->state = string2state(str);
callback_interface_state(interface);
}
+
+ if (interface->ap_create_in_progress) {
+ if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED)
+ callback_ap_create_fail(interface);
+
+ interface->ap_create_in_progress = false;
+ }
+
if (interface->state == G_SUPPLICANT_STATE_DISABLED)
interface->ready = FALSE;
else
g_free(interface->bridge);
interface->bridge = g_strdup(str);
}
+ } else if (g_strcmp0(key, "ConfigFile") == 0) {
+ const char *str = NULL;
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (str && strlen(str) > 0 && interface->ifname) {
+ SUPPLICANT_DBG("New {%s, %s}", interface->ifname, str);
+ g_hash_table_replace(config_file_table,
+ g_strdup(interface->ifname), g_strdup(str));
+ }
} else if (g_strcmp0(key, "CurrentBSS") == 0) {
- interface_bss_added_without_keys(iter, interface);
+ interface_current_bss(interface, iter);
} else if (g_strcmp0(key, "CurrentNetwork") == 0) {
+#if defined TIZEN_EXT
+ if (interface->state != G_SUPPLICANT_STATE_COMPLETED)
+#endif
interface_network_added(iter, interface);
} else if (g_strcmp0(key, "BSSs") == 0) {
supplicant_dbus_array_foreach(iter,
dbus_message_iter_get_basic(iter, &status_code);
callback_assoc_status_code(interface, status_code);
}
- } else
+ } else {
SUPPLICANT_DBG("key %s type %c",
key, dbus_message_iter_get_arg_type(iter));
+ }
}
static void scan_network_update(DBusMessageIter *iter, void *user_data)
{
GSupplicantInterface *interface = user_data;
+/*Fixed : stucking in scanning state when scan failed*/
+#if defined TIZEN_EXT
+ GSupplicantInterfaceCallback scan_callback;
+#endif
+
if (iter)
supplicant_dbus_array_foreach(iter, scan_network_update,
interface);
+#if defined TIZEN_EXT
+ scan_callback = interface->scan_callback;
+#endif
+
if (interface->scan_callback)
interface->scan_callback(0, interface, interface->scan_data);
+#if defined TIZEN_EXT
+ if (interface->scan_callback == scan_callback) {
+#endif
interface->scan_callback = NULL;
interface->scan_data = NULL;
+#if defined TIZEN_EXT
+ }
+#endif
}
static GSupplicantInterface *interface_alloc(const char *path)
g_str_equal, NULL, remove_peer);
interface->group_table = g_hash_table_new_full(g_str_hash,
g_str_equal, NULL, remove_group);
- interface->net_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, NULL);
interface->bss_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, NULL);
{
GSupplicantInterface *interface;
const char *path = NULL;
+ bool properties_appended = GPOINTER_TO_UINT(user_data);
SUPPLICANT_DBG("");
if (!interface)
return;
+ if (!properties_appended) {
+ supplicant_dbus_property_get_all(path,
+ SUPPLICANT_INTERFACE ".Interface",
+ interface_property, interface,
+ interface);
+ return;
+ }
+
dbus_message_iter_next(iter);
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
supplicant_dbus_property_foreach(iter, interface_property,
interface);
interface_property(NULL, NULL, interface);
- return;
}
-
- supplicant_dbus_property_get_all(path,
- SUPPLICANT_INTERFACE ".Interface",
- interface_property, interface,
- interface);
}
static void interface_removed(DBusMessageIter *iter, void *user_data)
g_hash_table_remove_all(bss_mapping);
g_hash_table_remove_all(peer_mapping);
g_hash_table_remove_all(group_mapping);
+ g_hash_table_remove_all(config_file_table);
g_hash_table_remove_all(interface_table);
callback_system_killed();
}
SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
if (g_strcmp0(path, SUPPLICANT_PATH) == 0)
- interface_added(iter, NULL);
+ interface_added(iter, GUINT_TO_POINTER(true));
}
static void signal_interface_removed(const char *path, DBusMessageIter *iter)
return;
supplicant_dbus_property_foreach(iter, bss_property, bss);
-
+#if defined TIZEN_EXT
+ network->frequency = bss->frequency;
+#endif
old_security = network->security;
bss_compute_security(bss);
g_hash_table_remove(interface->network_table, network->group);
- add_or_replace_bss_to_network(new_bss);
+ if (add_or_replace_bss_to_network(new_bss) < 0) {
+ /* Remove entries in hash tables to handle the
+ * failure in add_or_replace_bss_to_network
+ */
+ g_hash_table_remove(bss_mapping, path);
+ g_hash_table_remove(interface->bss_mapping, path);
+ g_hash_table_remove(network->bss_table, path);
+ }
return;
}
+#if defined TIZEN_EXT
+ if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
+ network->wps = TRUE;
+ network->wps_capabilities |= bss->wps_capabilities;
+ } else
+ network->wps = FALSE;
+#endif
+
+ /* Consider only property changes of the connected BSS */
+ if (network == interface->current_network && bss != network->best_bss)
+ return;
+
if (bss->signal == network->signal)
+#ifndef TIZEN_EXT
+ return;
+#else
+ {
+ callback_network_changed(network, "");
return;
+ }
+#endif
/*
* If the new signal is lower than the SSID signal, we need
*/
if (bss->signal < network->signal) {
if (bss != network->best_bss)
+#ifndef TIZEN_EXT
+ return;
+#else
+ {
+ callback_network_changed(network, "");
return;
+ }
+#endif
network->signal = bss->signal;
update_network_signal(network);
} else {
if (g_strcmp0(name, "success") == 0)
interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
- else if (g_strcmp0(name, "fail") == 0)
+ else if (g_strcmp0(name, "failed") == 0)
interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
else
interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
supplicant_dbus_property_foreach(iter, wps_event_args, interface);
}
+#if defined TIZEN_EXT
+static void signal_power_off(const char *path, DBusMessageIter *iter)
+{
+ int poweroff_state = 0;
+
+ dbus_message_iter_get_basic(iter, &poweroff_state);
+
+ SUPPLICANT_DBG("poweroff_state(%d)", poweroff_state);
+
+ /* POWER_OFF_DIRECT 2 && POWER_OFF_RESTART 3 */
+ if (poweroff_state != 2 && poweroff_state != 3)
+ return;
+
+ if (callbacks_pointer == NULL)
+ return;
+
+ if (callbacks_pointer->system_power_off == NULL)
+ return;
+
+ callbacks_pointer->system_power_off();
+}
+#endif
+
+static void signal_station_connected(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ const char *sta_mac = NULL;
+
+ SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
+
+ if (callbacks_pointer->add_station == NULL)
+ return;
+
+ if (g_strcmp0(path, "/") == 0)
+ return;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (interface == NULL)
+ return;
+
+ dbus_message_iter_get_basic(iter, &sta_mac);
+ if (sta_mac == NULL)
+ return;
+
+ SUPPLICANT_DBG("New station %s connected", sta_mac);
+ callbacks_pointer->add_station(sta_mac);
+}
+
+static void signal_station_disconnected(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ const char *sta_mac = NULL;
+
+ SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
+
+ if (callbacks_pointer->remove_station == NULL)
+ return;
+
+ if (g_strcmp0(path, "/") == 0)
+ return;
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (interface == NULL)
+ return;
+
+ dbus_message_iter_get_basic(iter, &sta_mac);
+ if (sta_mac == NULL)
+ return;
+
+ SUPPLICANT_DBG("Station %s disconnected", sta_mac);
+ callbacks_pointer->remove_station(sta_mac);
+}
+
static void create_peer_identifier(GSupplicantPeer *peer)
{
const unsigned char test[ETH_ALEN] = {};
if (!group)
return;
- elem = g_slist_find_custom(data->old_groups, str, g_str_equal);
+ elem = g_slist_find_custom(data->old_groups, str, (GCompareFunc)g_strcmp0);
if (elem) {
data->old_groups = g_slist_remove_link(data->old_groups, elem);
peer->groups = g_slist_concat(elem, peer->groups);
{ SUPPLICANT_INTERFACE ".Interface.WPS", "Credentials", signal_wps_credentials },
{ SUPPLICANT_INTERFACE ".Interface.WPS", "Event", signal_wps_event },
+#if defined TIZEN_EXT
+ { "org.tizen.system.deviced.PowerOff", "ChangeState", signal_power_off },
+#endif
+
+ { SUPPLICANT_INTERFACE".Interface", "StaAuthorized", signal_station_connected },
+ { SUPPLICANT_INTERFACE".Interface", "StaDeauthorized", signal_station_disconnected },
{ SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", signal_peer_found },
{ SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost", signal_peer_lost },
const void *user_data)
{
struct supplicant_regdom *regdom;
+ int ret;
SUPPLICANT_DBG("Country setting %s", alpha2);
regdom->alpha2 = alpha2;
regdom->user_data = user_data;
- return supplicant_dbus_property_set(SUPPLICANT_PATH, SUPPLICANT_INTERFACE,
+ ret = supplicant_dbus_property_set(SUPPLICANT_PATH, SUPPLICANT_INTERFACE,
"Country", DBUS_TYPE_STRING_AS_STRING,
country_params, country_result,
regdom, NULL);
+ if (ret < 0) {
+ dbus_free(regdom);
+ SUPPLICANT_DBG("Unable to set Country configuration");
+ }
+ return ret;
}
int g_supplicant_interface_set_country(GSupplicantInterface *interface,
void *user_data)
{
struct supplicant_regdom *regdom;
+ int ret;
regdom = dbus_malloc0(sizeof(*regdom));
if (!regdom)
regdom->alpha2 = alpha2;
regdom->user_data = user_data;
- return supplicant_dbus_property_set(interface->path,
+ ret = supplicant_dbus_property_set(interface->path,
SUPPLICANT_INTERFACE ".Interface",
"Country", DBUS_TYPE_STRING_AS_STRING,
country_params, country_result,
regdom, NULL);
+ if (ret < 0) {
+ dbus_free(regdom);
+ SUPPLICANT_DBG("Unable to set Country configuration");
+ }
+
+ return ret;
}
bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface)
return peer;
}
- struct interface_data {
- GSupplicantInterface *interface;
- char *path; /* Interface path cannot be taken from interface (above) as
- * it might have been freed already.
- */
- GSupplicantInterfaceCallback callback;
- void *user_data;
- };
-
- struct interface_create_data {
- char *ifname;
- char *driver;
- char *bridge;
- GSupplicantInterface *interface;
- GSupplicantInterfaceCallback callback;
- void *user_data;
- };
-
- struct interface_connect_data {
- GSupplicantInterface *interface;
- char *path;
- GSupplicantInterfaceCallback callback;
- union {
- GSupplicantSSID *ssid;
- GSupplicantPeerParams *peer;
- };
- void *user_data;
- };
-
- struct interface_scan_data {
- GSupplicantInterface *interface;
- char *path;
- GSupplicantInterfaceCallback callback;
- GSupplicantScanParams *scan_params;
- void *user_data;
- };
-
static void interface_create_data_free(struct interface_create_data *data)
{
g_free(data->ifname);
if (!key) {
if (data->callback) {
data->callback(0, data->interface, data->user_data);
+#if !defined TIZEN_EXT
callback_p2p_support(interface);
+#endif
}
interface_create_data_free(data);
{
struct interface_create_data *data = user_data;
DBusMessageIter dict;
+ char *config_file = NULL;
SUPPLICANT_DBG("");
supplicant_dbus_dict_append_basic(&dict, "BridgeIfname",
DBUS_TYPE_STRING, &data->bridge);
+ config_file = g_hash_table_lookup(config_file_table, data->ifname);
+ if (config_file) {
+ SUPPLICANT_DBG("[%s] ConfigFile %s", data->ifname, config_file);
+
+ supplicant_dbus_dict_append_basic(&dict, "ConfigFile",
+ DBUS_TYPE_STRING, &config_file);
+ }
+
supplicant_dbus_dict_close(iter, &dict);
}
if (data->callback) {
data->callback(0, interface, data->user_data);
+#if !defined TIZEN_EXT
callback_p2p_support(interface);
+#endif
}
interface_create_data_free(data);
if (error) {
err = -EIO;
+ SUPPLICANT_DBG("error: %s", error);
goto done;
}
supplicant_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &type);
- supplicant_dbus_dict_append_array(&dict, "SSIDs",
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("[specific_scan] num_ssids %d", data->scan_params->num_ssids);
+ if (data->scan_params->num_ssids != 0)
+#endif
+ supplicant_dbus_dict_append_array(&dict, "SSIDs",
DBUS_TYPE_STRING,
append_ssids,
data->scan_params);
case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
return -EBUSY;
+#if defined TIZEN_EXT
+ case G_SUPPLICANT_STATE_DISABLED:
+ return -ENOLINK;
+ case G_SUPPLICANT_STATE_UNKNOWN:
+#else
case G_SUPPLICANT_STATE_UNKNOWN:
case G_SUPPLICANT_STATE_DISABLED:
+#endif
case G_SUPPLICANT_STATE_DISCONNECTED:
case G_SUPPLICANT_STATE_INACTIVE:
case G_SUPPLICANT_STATE_SCANNING:
data->interface = interface;
data->path = g_strdup(interface->path);
+#if defined TIZEN_EXT
+ data->interface->scan_callback = data->callback = callback;
+ data->interface->scan_data = data->user_data = user_data;
+#else
data->callback = callback;
data->user_data = user_data;
+#endif
data->scan_params = scan_data;
interface->scan_callback = callback;
static int parse_supplicant_error(DBusMessageIter *iter)
{
- int err = -ECANCELED;
+ int err = -ECONNABORTED;
char *key;
if (!iter)
err = 0;
if (error) {
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("SelectNetwork errorFreq %s", error);
+#else
SUPPLICANT_DBG("SelectNetwork error %s", error);
+#endif
err = parse_supplicant_error(iter);
}
{
struct interface_connect_data *data = user_data;
GSupplicantInterface *interface = data->interface;
+#if defined TIZEN_EXT
+ GSupplicantSSID *ssid = data->ssid;
+#endif
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
&interface->network_path);
+#if defined TIZEN_EXT
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
+#endif
}
static void interface_add_network_result(const char *error,
SUPPLICANT_DBG("PATH: %s", path);
- g_free(interface->network_path);
interface->network_path = g_strdup(path);
+ store_network_information(interface, data->ssid);
+
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG(".Interface.SelectNetworkFreq");
+#endif
+
+#if defined TIZEN_EXT
+ supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
+ interface_select_network_params,
+ interface_select_network_result, data,
+ interface);
+#else
supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
interface_select_network_params,
interface_select_network_result, data,
interface);
+#endif
return;
if (!ssid->private_key_path)
return;
+#if !defined TIZEN_EXT
if (!ssid->private_key_passphrase)
return;
+#endif
if (ssid->ca_cert_path)
supplicant_dbus_dict_append_basic(dict, "ca_cert",
supplicant_dbus_dict_append_basic(dict, "private_key",
DBUS_TYPE_STRING,
&ssid->private_key_path);
+#if !defined TIZEN_EXT
supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
DBUS_TYPE_STRING,
&ssid->private_key_passphrase);
+#endif
supplicant_dbus_dict_append_basic(dict, "client_cert",
DBUS_TYPE_STRING,
&ssid->client_cert_path);
if (!ssid->private_key_path)
return;
+#if !defined TIZEN_EXT
if (!ssid->private_key_passphrase)
return;
+#endif
supplicant_dbus_dict_append_basic(dict, "client_cert",
DBUS_TYPE_STRING,
DBUS_TYPE_STRING,
&ssid->private_key_path);
+#if !defined TIZEN_EXT
supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
DBUS_TYPE_STRING,
&ssid->private_key_passphrase);
+#endif
}
g_free(phase2_auth);
}
+#if defined TIZEN_EXT
+static void add_network_security_aka_sim(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ if (!ssid->passphrase)
+ return;
+
+ supplicant_dbus_dict_append_basic(dict, "password",
+ DBUS_TYPE_STRING,
+ &ssid->passphrase);
+}
+#endif
+
static void add_network_security_eap(DBusMessageIter *dict,
GSupplicantSSID *ssid)
{
char *eap_value;
+#if defined TIZEN_EXT
+ if (!ssid->eap)
+#else
if (!ssid->eap || !ssid->identity)
+#endif
return;
if (g_strcmp0(ssid->eap, "tls") == 0) {
add_network_security_tls(dict, ssid);
} else if (g_strcmp0(ssid->eap, "peap") == 0 ||
g_strcmp0(ssid->eap, "ttls") == 0) {
+#if defined TIZEN_EXT
+ if (!ssid->identity)
+ return;
+#endif
add_network_security_peap(dict, ssid);
+
+#if defined TIZEN_EXT
+ } else if (g_strcmp0(ssid->eap, "sim") == 0 ||
+ g_strcmp0(ssid->eap, "aka") == 0) {
+ add_network_security_aka_sim(dict, ssid);
+#endif
} else
return;
supplicant_dbus_dict_append_basic(dict, "eap",
DBUS_TYPE_STRING,
&eap_value);
+#if defined TIZEN_EXT
+ if (ssid->identity != NULL)
+ supplicant_dbus_dict_append_basic(dict, "identity",
+ DBUS_TYPE_STRING,
+ &ssid->identity);
+#else
supplicant_dbus_dict_append_basic(dict, "identity",
DBUS_TYPE_STRING,
&ssid->identity);
+#endif
+ if(ssid->anonymous_identity)
+ supplicant_dbus_dict_append_basic(dict, "anonymous_identity",
+ DBUS_TYPE_STRING,
+ &ssid->anonymous_identity);
+
+ if(ssid->subject_match)
+ supplicant_dbus_dict_append_basic(dict, "subject_match",
+ DBUS_TYPE_STRING,
+ &ssid->subject_match);
+
+ if(ssid->altsubject_match)
+ supplicant_dbus_dict_append_basic(dict, "altsubject_match",
+ DBUS_TYPE_STRING,
+ &ssid->altsubject_match);
+
+ if(ssid->domain_suffix_match)
+ supplicant_dbus_dict_append_basic(dict, "domain_suffix_match",
+ DBUS_TYPE_STRING,
+ &ssid->domain_suffix_match);
+
+ if(ssid->domain_match)
+ supplicant_dbus_dict_append_basic(dict, "domain_match",
+ DBUS_TYPE_STRING,
+ &ssid->domain_match);
g_free(eap_value);
}
add_network_security_ciphers(dict, ssid);
add_network_security_proto(dict, ssid);
break;
+#if defined TIZEN_EXT
+ case G_SUPPLICANT_SECURITY_FT_PSK:
+ key_mgmt = "FT-PSK";
+ add_network_security_psk(dict, ssid);
+ add_network_security_ciphers(dict, ssid);
+ add_network_security_proto(dict, ssid);
+ break;
+ case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
+ key_mgmt = "FT-EAP";
+ add_network_security_eap(dict, ssid);
+ add_network_security_ciphers(dict, ssid);
+ add_network_security_proto(dict, ssid);
+ break;
+#endif
}
supplicant_dbus_dict_append_basic(dict, "key_mgmt",
DBUS_TYPE_BYTE, &ssid->ssid,
ssid->ssid_len);
+ supplicant_dbus_dict_append_basic(&dict, "ignore_broadcast_ssid",
+ DBUS_TYPE_INT32,
+ &ssid->ignore_broadcast_ssid);
+
+#if defined TIZEN_EXT
+ if (ssid->bssid) {
+ char *bssid = NULL;
+ bssid = g_try_malloc0(18);
+ if (bssid == NULL) {
+ SUPPLICANT_DBG("memory allocation error");
+ supplicant_dbus_dict_close(iter, &dict);
+ return;
+ }
+ snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ssid->bssid[0], ssid->bssid[1], ssid->bssid[2],
+ ssid->bssid[3], ssid->bssid[4], ssid->bssid[5]);
+ supplicant_dbus_dict_append_basic(&dict, "bssid",
+ DBUS_TYPE_STRING, &bssid);
+ g_free(bssid);
+ }
+#endif
+
supplicant_dbus_dict_close(iter, &dict);
}
supplicant_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &type);
+#if defined TIZEN_EXT
+ if (ssid->bssid)
+ supplicant_dbus_dict_append_fixed_array(&dict, "Bssid",
+ DBUS_TYPE_BYTE, &ssid->bssid, 6);
+#endif
+
supplicant_dbus_dict_close(iter, &dict);
}
dbus_free(data);
return;
}
-
+#if defined TIZEN_EXT
+ GSupplicantSSID *ssid = data->ssid;
+ if (ssid->pin_wps != NULL) {
+ if (!g_utf8_validate(ssid->pin_wps, 8, NULL)) {
+ SUPPLICANT_DBG("Invalid characters in WPS_PIN");
+ g_free(data->ssid);
+ dbus_free(data);
+ return;
+ }
+ }
+#endif
supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface.WPS", "Start",
interface_add_wps_params,
dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
}
- ret = -EINVAL;
+
+#if defined TIZEN_EXT
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+
+struct dec_method_call_data {
+ struct interface_connect_data *data;
+ DBusPendingCall *pending_call;
+};
+
+static struct dec_method_call_data decrypt_request_data;
+
+static void crypt_method_call_cancel(void)
+{
+ if (decrypt_request_data.pending_call) {
+ dbus_pending_call_cancel(decrypt_request_data.pending_call);
+ dbus_pending_call_unref(decrypt_request_data.pending_call);
+ decrypt_request_data.pending_call = NULL;
+ }
+
+ g_free(decrypt_request_data.data->path);
+ g_free(decrypt_request_data.data->ssid);
+ dbus_free(decrypt_request_data.data);
+ decrypt_request_data.data = NULL;
+}
+
+static void decryption_request_reply(DBusPendingCall *call,
+ void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args;
+ char *out_data;
+ int ret;
+ static gchar* origin_value = NULL;
+ struct interface_connect_data *data = user_data;
+
+ g_free(origin_value);
+ origin_value = NULL;
+
+ SUPPLICANT_DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
+ dbus_error_free(&error);
- ret = -EINVAL;
+ goto done;
+ }
+
+ if (dbus_message_iter_init(reply, &args) == FALSE) {
+ SUPPLICANT_DBG("dbus_message_iter_init() failed");
- done:
+ goto done;
+ }
+
+ dbus_message_iter_get_basic(&args, &out_data);
+
+ origin_value = g_strdup((const gchar *)out_data);
+ data->ssid->passphrase = origin_value;
+
+ ret = supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, data,
+ data->interface);
+
+ if (ret < 0) {
+ SUPPLICANT_DBG("AddNetwork failed %d", ret);
+ callback_assoc_failed(decrypt_request_data.data->user_data);
+ g_free(data->path);
+ g_free(data->ssid);
+ dbus_free(data);
+ }
+
++done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+
+ decrypt_request_data.pending_call = NULL;
+ decrypt_request_data.data = NULL;
+}
+
+static int send_decryption_request(const char *passphrase,
+ struct interface_connect_data *data)
+{
+ DBusMessage *msg = NULL;
+ DBusPendingCall *call;
+
+ SUPPLICANT_DBG("Decryption request");
+
+ if (!passphrase) {
+ SUPPLICANT_DBG("Invalid parameter");
+ return -EINVAL;
+ }
+
+ if (!connection)
+ return -EINVAL;
+
+ msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
+ NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
+ if (!msg)
+ return -EINVAL;
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_connection_send_with_reply(connection, msg,
+ &call, DBUS_TIMEOUT_USE_DEFAULT)) {
+ dbus_message_unref(msg);
+ return -EIO;
+ }
+
+ if (!call) {
+ dbus_message_unref(msg);
+ return -EIO;
+ }
+
+ decrypt_request_data.pending_call = call;
+ decrypt_request_data.data = data;
+
+ dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
+ dbus_message_unref(msg);
+
+ SUPPLICANT_DBG("Decryption request succeeded");
+
+ return 0;
+}
+#endif
+
int g_supplicant_interface_connect(GSupplicantInterface *interface,
GSupplicantSSID *ssid,
GSupplicantInterfaceCallback callback,
void *user_data)
{
struct interface_connect_data *data;
- int ret;
+ struct interface_data *intf_data;
+ int ret = 0;
+
+ SUPPLICANT_DBG("");
if (!interface)
return -EINVAL;
SUPPLICANT_INTERFACE ".Interface.WPS",
"ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING,
wps_process_credentials, wps_start, data, interface);
- } else
- #if defined TIZEN_EXT
- if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
- ret = send_decryption_request(ssid->passphrase, data);
- if (ret < 0)
- SUPPLICANT_DBG("Decryption request failed %d", ret);
+ } else {
+ /* By the time there is a request for connect and the network
+ * path is not NULL it means that connman has not removed the
+ * previous network pointer. This can happen in the case AP
+ * deauthenticated client and connman does not remove the
+ * previously connected network pointer. This causes supplicant
+ * to reallocate the memory for struct wpa_ssid again even if it
+ * is the same SSID. This causes memory usage of wpa_supplicnat
+ * to go high. The idea here is that if the previously connected
+ * network is not removed at the time of next connection attempt
+ * check if the network path is not NULL. In case it is non-NULL
+ * first remove the network and then once removal is successful, add
+ * the network.
+ */
+
+ if (interface->network_path != NULL) {
+ g_free(data->path);
+ dbus_free(data);
+
+ /*
+ * If this add network is for the same network for
+ * which wpa_supplicant already has a profile then do
+ * not need to add another profile. Only if the
+ * profile that needs to get added is different from
+ * what is there in wpa_s delete the current one. A
+ * network is identified by its SSID, security_type
+ * and passphrase (private passphrase in case security
+ * type is 802.11x).
+ */
+ if (compare_network_parameters(interface, ssid)) {
+ return -EALREADY;
+ }
+
+ intf_data = dbus_malloc0(sizeof(*intf_data));
+ if (!intf_data)
+ return -ENOMEM;
+
+ intf_data->interface = interface;
+ intf_data->path = g_strdup(interface->path);
+ intf_data->callback = callback;
+ intf_data->ssid = ssid;
+ intf_data->user_data = user_data;
+ intf_data->network_remove_in_progress = TRUE;
+ network_remove(intf_data);
- } else {
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
- interface_add_network_params,
- interface_add_network_result, data,
- interface);
- }
- }
+ } else
++#if defined TIZEN_EXT
++ if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
++ ret = send_decryption_request(ssid->passphrase, data);
++ if (ret < 0)
++ SUPPLICANT_DBG("Decryption request failed %d", ret);
++ } else
+#endif
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
- interface_add_network_params,
- interface_add_network_result, data,
- interface);
++ ret = supplicant_dbus_method_call(interface->path,
++ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
++ interface_add_network_params,
++ interface_add_network_result, data,
++ interface);
++ }
if (ret < 0) {
g_free(data->path);
DBusMessageIter *iter, void *user_data)
{
struct interface_data *data = user_data;
+ struct interface_connect_data *connect_data;
int result = 0;
SUPPLICANT_DBG("");
if (error) {
result = -EIO;
+ SUPPLICANT_DBG("error: %s", error);
+
if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
error) == 0)
result = -ECONNABORTED;
}
- g_free(data->path);
+ g_free(data->interface->network_path);
+ data->interface->network_path = NULL;
- if (data->callback)
- data->callback(result, data->interface, data->user_data);
+ remove_network_information(data->interface);
+
+ if (data->network_remove_in_progress == TRUE) {
+ data->network_remove_in_progress = FALSE;
+ connect_data = dbus_malloc0(sizeof(*connect_data));
+ if (!connect_data)
+ return;
+
+ connect_data->interface = data->interface;
+ connect_data->path = g_strdup(data->path);
+ connect_data->callback = data->callback;
+ connect_data->ssid = data->ssid;
+ connect_data->user_data = data->user_data;
+ supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, connect_data,
+ connect_data->interface);
+ } else {
+ if (data->callback)
+ data->callback(result, data->interface, data->user_data);
+ }
+ g_free(data->path);
dbus_free(data);
}
SUPPLICANT_DBG("");
+#if defined TIZEN_EXT
+ GSupplicantInterface *intf = NULL;
+ /*
+ * Check if 'interface' is valid
+ */
+ intf = g_hash_table_lookup(interface_table, interface->path);
+ if (intf == NULL)
+ return -EINVAL;
+#endif
+
return supplicant_dbus_method_call(interface->path,
SUPPLICANT_INTERFACE ".Interface", "RemoveNetwork",
network_remove_params, network_remove_result, data,
if (error) {
result = -EIO;
+ SUPPLICANT_DBG("error: %s", error);
+
if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
error) == 0)
result = -ECONNABORTED;
}
- if (result < 0 && data->callback) {
- data->callback(result, data->interface, data->user_data);
- data->callback = NULL;
- }
-
/* If we are disconnecting from previous WPS successful
* association. i.e.: it did not went through AddNetwork,
* and interface->network_path was never set. */
if (!data->interface->network_path) {
+ if (data->callback)
+ data->callback(result, data->interface,
+ data->user_data);
+
g_free(data->path);
dbus_free(data);
return;
}
+ if (result < 0 && data->callback) {
+ data->callback(result, data->interface, data->user_data);
+ data->callback = NULL;
+ }
+
if (result != -ECONNABORTED) {
if (network_remove(data) < 0) {
g_free(data->path);
if (!system_available)
return -EFAULT;
+#if defined TIZEN_EXT
+ if (decrypt_request_data.pending_call &&
+ decrypt_request_data.data &&
+ decrypt_request_data.data->user_data == user_data) {
+
+ callback_assoc_failed(decrypt_request_data.data->user_data);
+ crypt_method_call_cancel();
+ return 0;
+ }
+#endif
data = dbus_malloc0(sizeof(*data));
if (!data)
return -ENOMEM;
SUPPLICANT_DBG("");
- if (error)
+ if (error) {
+ SUPPLICANT_DBG("error: %s", error);
err = parse_supplicant_error(iter);
+ }
if (data->callback)
data->callback(err, data->interface, data->user_data);
return -ENOTSUP;
data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
data->interface = interface;
data->path = g_strdup(interface->path);
data->peer = peer_params;
return -ENOTSUP;
data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
data->registration = true;
data->interface = interface;
data->service = p2p_service_params;
return -ENOTSUP;
data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
data->interface = interface;
data->service = p2p_service_params;
return -EFAULT;
data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
data->service = p2p_service_params;
data->callback = callback;
data->user_data = user_data;
return -EINPROGRESS;
}
+#if defined TIZEN_EXT
+int g_supplicant_interface_remove_network(GSupplicantInterface *interface)
+{
+ struct interface_data *data;
+
+ SUPPLICANT_DBG("");
+
+ if (interface == NULL)
+ return -EINVAL;
+
+ if (system_available == FALSE)
+ return -EFAULT;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (data == NULL)
+ return -ENOMEM;
+
+ data->interface = interface;
+
+ return network_remove(data);
+}
+#endif
static const char *g_supplicant_rule0 = "type=signal,"
"path=" DBUS_PATH_DBUS ","
"interface=" SUPPLICANT_INTERFACE ".BSS";
static const char *g_supplicant_rule5 = "type=signal,"
"interface=" SUPPLICANT_INTERFACE ".Network";
+#if !defined TIZEN_EXT
static const char *g_supplicant_rule6 = "type=signal,"
"interface=" SUPPLICANT_INTERFACE ".Interface.P2PDevice";
static const char *g_supplicant_rule7 = "type=signal,"
"interface=" SUPPLICANT_INTERFACE ".Peer";
static const char *g_supplicant_rule8 = "type=signal,"
"interface=" SUPPLICANT_INTERFACE ".Group";
+#endif
static void invoke_introspect_method(void)
{
NULL, NULL);
pending_peer_connection = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, NULL);
+ config_file_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
supplicant_dbus_setup(connection);
dbus_bus_add_match(connection, g_supplicant_rule3, NULL);
dbus_bus_add_match(connection, g_supplicant_rule4, NULL);
dbus_bus_add_match(connection, g_supplicant_rule5, NULL);
+#if defined TIZEN_EXT
+ dbus_bus_add_match(connection,
+ "type=signal,interface=org.tizen.system.deviced.PowerOff,"
+ "member=ChangeState", NULL);
+#endif
+#if !defined TIZEN_EXT
dbus_bus_add_match(connection, g_supplicant_rule6, NULL);
dbus_bus_add_match(connection, g_supplicant_rule7, NULL);
dbus_bus_add_match(connection, g_supplicant_rule8, NULL);
+#endif
dbus_connection_flush(connection);
if (dbus_bus_name_has_owner(connection,
SUPPLICANT_DBG("");
if (connection) {
+#if !defined TIZEN_EXT
dbus_bus_remove_match(connection, g_supplicant_rule8, NULL);
dbus_bus_remove_match(connection, g_supplicant_rule7, NULL);
dbus_bus_remove_match(connection, g_supplicant_rule6, NULL);
+#endif
dbus_bus_remove_match(connection, g_supplicant_rule5, NULL);
dbus_bus_remove_match(connection, g_supplicant_rule4, NULL);
dbus_bus_remove_match(connection, g_supplicant_rule3, NULL);
g_supplicant_filter, NULL);
}
+ if (config_file_table) {
+ g_hash_table_destroy(config_file_table);
+ config_file_table = NULL;
+ }
+
if (bss_mapping) {
g_hash_table_destroy(bss_mapping);
bss_mapping = NULL;
if (fd < 0)
return;
- if (connect(fd, &res->dst.sa, sizeof(res->dst)) < 0) {
- close(fd);
- return;
- }
+ if (connect(fd, &res->dst.sa, sizeof(res->dst)) < 0)
+ goto out;
- if (getsockname(fd, &res->src.sa, &sl) < 0) {
- close(fd);
- return;
- }
+ if (getsockname(fd, &res->src.sa, &sl) < 0)
+ goto out;
res->reachable = true;
+
+ out:
close(fd);
}
nameserver->flags = flags;
nameserver->resolv = resolv;
+ debug(resolv, "");
if (connect_udp_channel(nameserver) < 0) {
free_nameserver(nameserver);
return false;
}
+ debug(resolv, "");
resolv->nameserver_list = g_list_append(resolv->nameserver_list,
nameserver);
lookup->result_data = user_data;
lookup->id = resolv->next_lookup_id++;
+ debug(resolv, "");
+
if (resolv->result_family != AF_INET6) {
if (add_query(lookup, hostname, ns_t_a)) {
g_free(lookup);
}
}
+ debug(resolv, "");
+
if (resolv->result_family != AF_INET) {
if (add_query(lookup, hostname, ns_t_aaaa)) {
if (resolv->result_family != AF_INET6) {
}
}
+ debug(resolv, "");
+
g_queue_push_tail(resolv->lookup_queue, lookup);
debug(resolv, "lookup %p id %d", lookup, lookup->id);
char *str;
gchar *value;
+ if (!session->result.last_key)
+ return;
+
str = session->current_header->str;
if (str[0] != ' ' && str[0] != '\t')
g_string_insert_c(session->current_header, 0, ' ');
}
+#if defined TIZEN_EXT
+ if (session->result.last_key == NULL)
+ return;
+#endif
value = g_hash_table_lookup(session->result.headers,
session->result.last_key);
if (value) {
session->addr->ai_addrlen) < 0) {
if (errno != EINPROGRESS) {
debug(session->web, "connect() %s", strerror(errno));
- close(sk);
return -EIO;
}
}
return;
}
+#if defined TIZEN_EXT
+ // check the DNS address validation
+ // if dns is the class c private address
+ // wispr should be stopped - non internet connection
+ if(g_str_has_prefix(results[0],"192.168.")){
+ call_result_func(session, 404);
+ return;
+ }
+#endif
+
g_free(session->address);
session->address = g_strdup(results[0]);
g_free(session->address);
session->address = g_strdup(host);
}
- session->address_action = g_timeout_add(0, already_resolved,
- session);
+ session->address_action = g_idle_add(already_resolved, session);
} else {
session->resolv_action = g_resolv_lookup_hostname(web->resolv,
host, resolv_result, session);
{
GWebParser *parser;
+ if (!begin || !end)
+ return NULL;
+
parser = g_try_new0(GWebParser, 1);
if (!parser)
return NULL;
parser->begin_token = g_strdup(begin);
parser->end_token = g_strdup(end);
-
- if (!parser->begin_token) {
- g_free(parser);
- return NULL;
- }
-
parser->func = func;
parser->user_data = user_data;
bool connman_device_get_scanning(struct connman_device *device);
void connman_device_reset_scanning(struct connman_device *device);
- int connman_device_set_disconnected(struct connman_device *device,
- bool disconnected);
- bool connman_device_get_disconnected(struct connman_device *device);
-
int connman_device_set_string(struct connman_device *device,
const char *key, const char *value);
const char *connman_device_get_string(struct connman_device *device,
const char *security, void *user_data);
int (*set_regdom) (struct connman_device *device,
const char *alpha2);
+#if defined TIZEN_EXT
+ int (*specific_scan) (enum connman_service_type type,
+ struct connman_device *device, int scan_type,
+ GSList *specific_scan_list, void *user_data);
+#endif
};
int connman_device_driver_register(struct connman_device_driver *driver);
CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL = 2,
CONNMAN_NETWORK_ERROR_INVALID_KEY = 3,
CONNMAN_NETWORK_ERROR_CONNECT_FAIL = 4,
- CONNMAN_NETWORK_ERROR_BLOCKED = 5,
+#if defined TIZEN_EXT
+ CONNMAN_NETWORK_ERROR_DHCP_FAIL = 5,
+#endif
+ CONNMAN_NETWORK_ERROR_BLOCKED = 6,
+
};
#define CONNMAN_NETWORK_PRIORITY_LOW -100
const char *connman_network_get_group(struct connman_network *network);
bool connman_network_get_connecting(struct connman_network *network);
+#if defined TIZEN_EXT
+void connman_network_set_connecting(struct connman_network *network);
+#endif
int connman_network_set_available(struct connman_network *network,
bool available);
bool connman_network_get_available(struct connman_network *network);
const char *nameservers);
int connman_network_set_domain(struct connman_network *network,
const char *domain);
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+int connman_network_set_bssid(struct connman_network *network,
+ const unsigned char *bssid);
+unsigned char *connman_network_get_bssid(struct connman_network *network);
+
+int connman_network_set_maxrate(struct connman_network *network,
+ unsigned int maxrate);
+unsigned int connman_network_get_maxrate(struct connman_network *network);
+
+int connman_network_set_enc_mode(struct connman_network *network,
+ const char *encryption_mode);
+const char *connman_network_get_enc_mode(struct connman_network *network);
+
+int connman_network_set_rsn_mode(struct connman_network *network,
+ bool rsn_mode);
+
+int connman_network_set_proxy(struct connman_network *network,
+ const char *proxies);
+
+void connman_network_clear_associating(struct connman_network *network);
+
+int connman_network_set_keymgmt(struct connman_network *network,
+ unsigned int keymgmt);
+unsigned int connman_network_get_keymgmt(struct connman_network *network);
+int connman_network_set_disconnect_reason(struct connman_network *network,
+ int reason_code);
+int connman_network_get_disconnect_reason(struct connman_network *network);
+int connman_network_get_assoc_status_code(struct connman_network *network);
+int connman_network_set_assoc_status_code(struct connman_network *network,
+ int assoc_status_code);
+#endif
+
int connman_network_set_name(struct connman_network *network,
const char *name);
int connman_network_set_strength(struct connman_network *network,
const char *key, const void *data, unsigned int size);
const void *connman_network_get_blob(struct connman_network *network,
const char *key, unsigned int *size);
- #if defined TIZEN_EXT
- void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list);
- void *connman_network_get_vsie_list(struct connman_network *network);
- #endif
struct connman_device *connman_network_get_device(struct connman_network *network);
void (*remove) (struct connman_network *network);
int (*connect) (struct connman_network *network);
int (*disconnect) (struct connman_network *network);
+#if defined TIZEN_EXT
+ int (*merge) (struct connman_network *network);
+#endif
};
int connman_network_driver_register(struct connman_network_driver *driver);
enum connman_provider_type type;
int (*probe) (struct connman_provider *provider);
int (*remove) (struct connman_provider *provider);
- int (*connect) (struct connman_provider *provider);
+ int (*connect) (struct connman_provider *provider,
+ const char *dbus_sender);
int (*disconnect) (struct connman_provider *provider);
int (*save) (struct connman_provider *provider, GKeyFile *keyfile);
int (*set_property) (struct connman_provider *provider,
#include <stdbool.h>
+#if defined TIZEN_EXT
+#include <glib.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
bool connman_service_get_autoconnect(struct connman_service *service);
struct connman_service *connman_service_lookup_from_network(struct connman_network *network);
+ struct connman_service *connman_service_lookup_from_identifier(const char* identifier);
void connman_service_create_ip4config(struct connman_service *service,
int index);
void connman_service_create_ip6config(struct connman_service *service,
int index);
+#if defined TIZEN_EXT
+/*
+ * Description: TIZEN implements system global connection management.
+ * It's only for PDP (cellular) bearer. Wi-Fi is managed by ConnMan automatically.
+ * Reference count can help to manage open/close connection requests by each application.
+ */
+
+/*
+ * Increase reference count of user-initiated packet data network connection
+ */
+void connman_service_user_pdn_connection_ref(struct connman_service *service);
+
+/*
+ * Decrease reference count of user initiated packet data network connection
+ * and return TRUE if counter is zero.
+ */
+gboolean connman_service_user_pdn_connection_unref_and_test(
+ struct connman_service *service);
+
+/*
+ * Test reference count of user initiated packet data network connection
+ * and return TRUE if counter is zero. No impact to reference count
+ */
+gboolean connman_service_is_no_ref_user_pdn_connection(
+ struct connman_service *service);
+#endif
+
+#if defined TIZEN_EXT
+struct connman_service *connman_service_get_default_connection(void);
+
+/*
+ * Description: telephony plug-in requires manual PROXY setting
+ */
+int connman_service_set_proxy(struct connman_service *service,
+ const char *proxy, gboolean active);
+#endif
+
#ifdef __cplusplus
}
#endif
#ifndef __CONNMAN_SESSION_H
#define __CONNMAN_SESSION_H
+ #include <stdint.h>
#include <connman/service.h>
#ifdef __cplusplus
CONNMAN_SESSION_ID_TYPE_LSM = 3,
};
+ enum connman_session_state {
+ CONNMAN_SESSION_STATE_DISCONNECTED = 0,
+ CONNMAN_SESSION_STATE_CONNECTED = 1,
+ CONNMAN_SESSION_STATE_ONLINE = 2,
+ };
+
struct connman_session;
struct connman_session_config {
enum connman_session_type type;
bool ecall;
GSList *allowed_bearers;
+ char *allowed_interface;
+ bool source_ip_rule;
};
typedef int (* connman_session_config_func_t) (struct connman_session *session,
GSList *bearers);
bool (*allowed)(struct connman_session *session,
struct connman_service *service);
+ void (*update_session_state)(struct connman_session* session,
+ enum connman_session_state state);
+ struct connman_service* (*get_service_for_session)(struct connman_session* session,
+ GSList* services);
};
+ uint32_t connman_session_firewall_get_fwmark(struct connman_session *session);
int connman_session_policy_register(struct connman_session_policy *config);
void connman_session_policy_unregister(struct connman_session_policy *config);
struct connman_technology;
- void connman_technology_tethering_notify(struct connman_technology *technology,
+int connman_technology_tethering_add_station(enum connman_service_type type,
+ const char *mac);
+int connman_technology_tethering_remove_station(const char *mac);
+
+ int connman_technology_tethering_notify(struct connman_technology *technology,
bool enabled);
int connman_technology_set_regdom(const char *alpha2);
void connman_technology_regdom_notify(struct connman_technology *technology,
int index);
int (*set_tethering) (struct connman_technology *technology,
const char *identifier, const char *passphrase,
- const char *bridge, bool enabled, bool hidden);
+ const char *bridge, bool enabled);
int (*set_regdom) (struct connman_technology *technology,
const char *alpha2);
};
--- /dev/null
- Version: 1.29
+%bcond_with connman_openconnect
+%bcond_without connman_openvpn
+%bcond_without connman_ipsec
+%bcond_without connman_vpnd
+
+Name: connman
++Version: 1.35
+Release: 26
+License: GPL-2.0+
+Summary: Connection Manager
+Url: http://connman.net
+Group: Network & Connectivity/Connection Management
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: systemd-devel
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(libiptc)
+BuildRequires: pkgconfig(xtables)
+BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(libsystemd-daemon)
+%if %{with connman_openconnect}
+BuildRequires: openconnect
+%endif
+%if %{with connman_openvpn}
+BuildRequires: openvpn
+%endif
+%if %{with connman_ipsec}
+BuildRequires: strongswan
+%endif
+BuildRequires: readline-devel
+#%systemd_requires
+Requires: iptables
+Requires: systemd
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+Requires: net-config
+Requires: security-config
+Provides: %{name}-profile_common = %{version}-%{release}
+Provides: %{name}-profile_mobile = %{version}-%{release}
+Provides: %{name}-profile_wearable = %{version}-%{release}
+
+%define upgrade_script_filename 500.connman_upgrade.sh
+%define upgrade_script_path /usr/share/upgrade/scripts
+
+%description
+Connection Manager provides a daemon for managing Internet connections
+within embedded devices running the Linux operating system.
+
+%if %{with connman_openconnect}
+%package plugin-openconnect
+Summary: Openconnect Support for Connman
+Requires: %{name} = %{version}
+Requires: openconnect
+
+%description plugin-openconnect
+Openconnect Support for Connman.
+%endif
+
+%if %{with connman_openvpn}
+%package plugin-openvpn
+Summary: Openvpn Support for Connman
+Requires: %{name} = %{version}
+Requires: openvpn
+
+%description plugin-openvpn
+OpenVPN support for Connman.
+%endif
+
+%if %{with connman_ipsec}
+%package plugin-ipsec
+Summary: IPsec Support for Connman
+Requires: %{name} = %{version}
+Requires: strongswan
+
+%description plugin-ipsec
+OpenVPN support for Connman.
+%endif
+
+%if %{with connman_vpnd}
+%package connman-vpnd
+Summary: VPN Support for Connman
+#BuildRequires: %{name} = %{version}
+Requires: %{name} = %{version}
+
+%description connman-vpnd
+Provides VPN support for Connman
+%endif
+
+%package test
+Summary: Test Scripts for Connection Manager
+Group: Development/Tools
+Requires: %{name} = %{version}
+Requires: dbus-python
+Requires: pygobject
+Requires: python-xml
+
+%description test
+Scripts for testing Connman and its functionality
+
+%package devel
+Summary: Development Files for connman
+Group: Development/Tools
+Requires: %{name} = %{version}
+
+%description devel
+Header files and development files for connman.
+
+%package extension-tv
+Summary: Connman service script for TV profile
+Requires: %{name} = %{version}-%{release}
+Provides: %{name}-profile_tv = %{version}-%{release}
+Conflicts: %{name}-extension-ivi
+Conflicts: %{name}-extension-disable-eth
+%description extension-tv
+Supplies Tizen TV profile systemd service scripts instead of the default one.
+This overwrites service script of %{name}.
+
+%package extension-ivi
+Summary: Connman configuration for IVI profile
+Requires: %{name} = %{version}-%{release}
+Provides: %{name}-profile_ivi = %{version}-%{release}
+Conflicts: %{name}-extension-tv
+Conflicts: %{name}-extension-disable-eth
+%description extension-ivi
+Supplies Tizen IVI profile configuration instead of the default one.
+This overwrites conf file of %{name}.
+
+%package extension-disable-eth
+Summary: Connman configuration for testing which requires the ethernet to be disabled
+Requires: %{name} = %{version}-%{release}
+Conflicts: %{name}-extension-tv
+Conflicts: %{name}-extension-ivi
+%description extension-disable-eth
+Connman without ethernet support
+This overwrites conf file of %{name}.
+
+%prep
+%setup -q
+
+
+%build
+#CFLAGS+=" -DTIZEN_EXT -lsmack -Werror"
+
+%if %{with connman_vpnd}
+VPN_CFLAGS+=" -DTIZEN_EXT -lsmack -Werror"
+%endif
+
+chmod +x bootstrap
+./bootstrap
+%configure \
+ --sysconfdir=/etc \
+ --enable-client \
+ --enable-tizen-ext \
+ --enable-pacrunner \
+ --enable-wifi=builtin \
+%if %{with connman_openconnect}
+ --enable-openconnect \
+%endif
+%if %{with connman_openvpn}
+ --enable-openvpn \
+%endif
+%if %{with connman_ipsec}
+ --enable-ipsec \
+%endif
+%if 0%{?enable_connman_features}
+ %connman_features \
+%endif
+ --disable-ofono \
+ --enable-telephony=builtin \
+ --enable-test \
+ --enable-loopback \
+ --enable-ethernet \
+ --with-systemdunitdir=%{_libdir}/systemd/system \
+ --enable-pie \
+ --disable-wispr
+
+make %{?_smp_mflags}
+
+%install
+%make_install
+
+#Systemd service file
+mkdir -p %{buildroot}%{_libdir}/systemd/system/
+%if "%{?_lib}" == "lib64"
+mkdir -p %{buildroot}%{_unitdir}
+%endif
+
+%if "%{?_lib}" == "lib64"
+cp src/connman_tv.service %{buildroot}%{_unitdir}/connman.service.tv
+cp src/connman.service %{buildroot}%{_unitdir}/connman.service
+cp vpn/connman-vpn.service %{buildroot}%{_unitdir}/connman-vpn.service
+%else
+cp src/connman_tv.service %{buildroot}%{_libdir}/systemd/system/connman.service.tv
+%endif
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+ln -s ../connman.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/connman.service
+%if "%{?_lib}" == "lib64"
+mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants
+ln -s ../connman.service %{buildroot}%{_unitdir}/multi-user.target.wants/connman.service
+%endif
+
+#Systemd socket file for DNS proxy
+%if "%{?_lib}" == "lib64"
+cp src/connman.socket %{buildroot}%{_unitdir}/connman.socket
+mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants
+ln -s ../connman.socket %{buildroot}%{_unitdir}/sockets.target.wants/connman.socket
+%else
+cp src/connman.socket %{buildroot}%{_libdir}/systemd/system/connman.socket
+mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
+ln -s ../connman.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/connman.socket
+%endif
+
+mkdir -p %{buildroot}/%{_localstatedir}/lib/connman
+cp resources/var/lib/connman/settings %{buildroot}/%{_localstatedir}/lib/connman/settings
+mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services
+cp resources/usr/share/dbus-1/system-services/net.connman.service %{buildroot}%{_datadir}/dbus-1/system-services/net.connman.service
+mkdir -p %{buildroot}/etc/connman
+
+cp src/main_ivi.conf %{buildroot}/etc/connman/main.conf.ivi
+cp src/main_tv.conf %{buildroot}/etc/connman/main.conf.tv
+cp src/main_disable_eth.conf %{buildroot}/etc/connman/main.conf.disable.eth
+cp src/main.conf %{buildroot}/etc/connman/main.conf
+
+rm %{buildroot}%{_sysconfdir}/dbus-1/system.d/*.conf
+mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d/
+cp src/connman.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/
+
+%if %{with connman_vpnd}
+cp vpn/vpn-dbus.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
+%endif
+
+#OS Upgrade
+mkdir -p %{buildroot}%{upgrade_script_path}
+cp -f scripts/%{upgrade_script_filename} %{buildroot}%{upgrade_script_path}
+
+%post
+#chsmack -a 'System' /%{_localstatedir}/lib/connman
+#chsmack -a 'System' /%{_localstatedir}/lib/connman/settings
+
+%preun
+
+%postun
+systemctl daemon-reload
+
+%docs_package
+
+%files
+%manifest connman.manifest
+%attr(500,network_fw,network_fw) %{_bindir}/connmand
+%attr(500,network_fw,network_fw) %{_bindir}/connmanctl
+%attr(755,network_fw,network_fw) /%{_localstatedir}/lib/connman
+%attr(600,network_fw,network_fw) /%{_localstatedir}/lib/connman/settings
+%attr(644,root,root) %{_datadir}/dbus-1/system-services/net.connman.service
+%{_sysconfdir}/dbus-1/system.d/*
+%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf
+%{_sysconfdir}/dbus-1/system.d/*.conf
+%attr(644,root,root) %{_libdir}/systemd/system/connman.service
+%attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/connman.service
+%if "%{?_lib}" == "lib64"
+%attr(644,root,root) %{_unitdir}/connman.service
+%attr(644,root,root) %{_unitdir}/multi-user.target.wants/connman.service
+%attr(644,root,root) %{_unitdir}/connman.socket
+%attr(644,root,root) %{_unitdir}/sockets.target.wants/connman.socket
+%else
+%attr(644,root,root) %{_libdir}/systemd/system/connman.socket
+%attr(644,root,root) %{_libdir}/systemd/system/sockets.target.wants/connman.socket
+%endif
+%license COPYING
+%{upgrade_script_path}/%{upgrade_script_filename}
+
+%files test
+%manifest connman.manifest
+%{_libdir}/%{name}/test/*
+
+%files devel
+%manifest connman.manifest
+%{_includedir}/*
+%{_libdir}/pkgconfig/*.pc
+
+%if %{with connman_openconnect}
+%files plugin-openconnect
+%manifest %{name}.manifest
+%{_libdir}/connman/plugins-vpn/openconnect.so
+%{_libdir}/connman/scripts/openconnect-script
+%license COPYING
+%endif
+
+%if %{with connman_openvpn}
+%files plugin-openvpn
+%manifest %{name}.manifest
+%{_libdir}/%{name}/plugins-vpn/openvpn.so
+%{_libdir}/%{name}/scripts/openvpn-script
+%license COPYING
+%endif
+
+%if %{with connman_ipsec}
+%files plugin-ipsec
+%manifest %{name}.manifest
+%{_libdir}/%{name}/plugins-vpn/ipsec.so
+%{_libdir}/%{name}/scripts/ipsec-script
+%license COPYING
+%endif
+
+%if %{with connman_vpnd}
+%files connman-vpnd
+%manifest %{name}.manifest
+%{_bindir}/connman-vpnd
+%dir %{_libdir}/%{name}
+%dir %{_libdir}/%{name}/scripts
+%dir %{_libdir}/%{name}/plugins-vpn
+%config %{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
+%{_datadir}/dbus-1/system-services/net.connman.vpn.service
+%license COPYING
+%attr(644,root,root) %{_libdir}/systemd/system/connman-vpn.service
+%if "%{?_lib}" == "lib64"
+%attr(644,root,root) %{_unitdir}/connman-vpn.service
+%endif
+%endif
+
+%post extension-tv
+mv -f %{_libdir}/systemd/system/connman.service.tv %{_libdir}/systemd/system/connman.service
+mv -f %{_sysconfdir}/connman/main.conf.tv %{_sysconfdir}/connman/main.conf
+%files extension-tv
+%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.tv
+%license COPYING
+%if "%{?_lib}" == "lib64"
+%attr(644,root,root) %{_unitdir}/connman.service.tv
+%else
+%attr(644,root,root) %{_libdir}/systemd/system/connman.service.tv
+%endif
+%post extension-ivi
+mv -f %{_sysconfdir}/connman/main.conf.ivi %{_sysconfdir}/connman/main.conf
+%files extension-ivi
+%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.ivi
+%license COPYING
+%post extension-disable-eth
+mv -f %{_sysconfdir}/connman/main.conf.disable.eth %{_sysconfdir}/connman/main.conf
+%files extension-disable-eth
+%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.disable.eth
+%license COPYING
return false;
}
+#if defined TIZEN_EXT
+ if (pan->network) {
+#endif
connman_network_set_index(pan->network, index);
connman_network_set_connected(pan->network, true);
+#if defined TIZEN_EXT
+ }
+#endif
return true;
}
DBusMessageIter iter;
pan = g_hash_table_lookup(networks, path);
- if (!pan) {
+ if (!pan || !pan->network) {
DBG("network already removed");
return;
}
+#ifdef TIZEN_EXT
+ /*
+ * Network could be removed because of BT adapter power off
+ * This is to handle the scenario where network is removed
+ * before the connect_cb is called
+ */
+ if (!pan->network) {
+ DBG("network already removed");
+ return;
+ }
+#endif
+
if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
const char *dbus_error = dbus_message_get_error_name(message);
if (strcmp(dbus_error,
"org.bluez.Error.AlreadyConnected") != 0) {
+ connman_network_set_associating(pan->network, false);
connman_network_set_error(pan->network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
return;
g_strdup(path), g_free))
return -EIO;
+#if defined TIZEN_EXT
+ if (pan->network)
+#endif
connman_network_set_associating(pan->network, true);
return -EINPROGRESS;
struct bluetooth_pan *pan;
pan = g_hash_table_lookup(networks, path);
- if (!pan) {
+ if (!pan || !pan->network) {
DBG("network already removed");
return;
}
DBG("network %p", pan->network);
+#if defined TIZEN_EXT
+ if (pan->network)
+#endif
connman_network_set_connected(pan->network, false);
}
if (!pan)
return -EINVAL;
+#if defined TIZEN_EXT
+ if (connman_network_get_associating(network) == TRUE)
+ connman_network_clear_associating(network);
+#endif
+
path = g_dbus_proxy_get_path(pan->btnetwork_proxy);
if (!g_dbus_proxy_method_call(pan->btnetwork_proxy, "Disconnect",
{
struct connman_device *device;
const char* role;
+ const char *adapter;
role = proxy_get_role(pan->btdevice_proxy);
if (!role) {
return;
}
- device = g_hash_table_lookup(devices,
- proxy_get_string(pan->btdevice_proxy, "Adapter"));
+ adapter = proxy_get_string(pan->btdevice_proxy, "Adapter");
+
+ if (!adapter)
+ return;
+
+ device = g_hash_table_lookup(devices, adapter);
if (!device || !connman_device_get_powered(device))
return;
goto out;
}
+#if !defined TIZEN_EXT
enable_device(device, path);
+#endif
+
out:
g_free(path);
}
goto out;
}
+#if !defined TIZEN_EXT
disable_device(device, path);
+#endif
out:
g_free(path);
struct connman_technology *technology, const char *bridge,
bool enabled)
{
- struct tethering_info *tethering;
+ struct tethering_info *tethering = g_new0(struct tethering_info, 1);
GDBusProxy *proxy;
const char *method;
bool result;
DBG("path %s bridge %s", path, bridge);
- if (!bridge)
- return -EINVAL;
+ if (!bridge) {
+ g_free(tethering);
+ return false;
+ }
proxy = g_dbus_proxy_new(client, path, "org.bluez.NetworkServer1");
- if (!proxy)
+ if (!proxy) {
+ g_free(tethering);
return false;
-
- tethering = g_new0(struct tethering_info, 1);
+ }
tethering->technology = technology;
tethering->bridge = g_strdup(bridge);
static int bluetooth_tech_set_tethering(struct connman_technology *technology,
const char *identifier, const char *passphrase,
- const char *bridge, bool enabled)
+ const char *bridge, bool enabled, bool hidden)
{
GHashTableIter hash_iter;
gpointer key, value;
#include <linux/if_vlan.h>
#include <linux/sockios.h>
+ #include <linux/ethtool.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
return vid;
}
+ static int get_dsa_port(const char *ifname)
+ {
+ int sk;
+ int dsaport = -1;
+ struct ifreq ifr;
+ struct ethtool_cmd cmd;
+ struct ethtool_drvinfo drvinfocmd;
+ struct vlan_ioctl_args vifr;
+
+ sk = socket(AF_INET, SOCK_STREAM, 0);
+ if (sk < 0)
+ return -errno;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+ /* check if it is a vlan and get physical interface name*/
+ vifr.cmd = GET_VLAN_REALDEV_NAME_CMD;
+ strncpy(vifr.device1, ifname, sizeof(vifr.device1));
+
+ if(ioctl(sk, SIOCSIFVLAN, &vifr) >= 0)
+ strncpy(ifr.ifr_name, vifr.u.device2, sizeof(ifr.ifr_name));
+
+ /* get driver info */
+ drvinfocmd.cmd = ETHTOOL_GDRVINFO;
+ ifr.ifr_data = (caddr_t)&drvinfocmd;
+
+ if (!ioctl(sk, SIOCETHTOOL, &ifr)) {
+ if(!strcmp(drvinfocmd.driver, "dsa")) {
+ /* get dsa port*/
+ cmd.cmd = ETHTOOL_GSET;
+ ifr.ifr_data = (caddr_t)&cmd;
+
+ if (!ioctl(sk, SIOCETHTOOL, &ifr))
+ dsaport = cmd.phy_address;
+ }
+ }
+ close(sk);
+
+ return dsaport;
+ }
+
static int eth_network_probe(struct connman_network *network)
{
DBG("network %p", network);
struct ethernet_data *ethernet)
{
struct connman_network *network;
- int index, vid;
+ int index;
char *ifname;
network = connman_network_create("carrier",
ifname = connman_inet_ifname(index);
if (!ifname)
return;
- vid = get_vlan_vid(ifname);
connman_network_set_name(network, "Wired");
}
if (!eth_tethering) {
- char group[10] = "cable";
+ char group[16] = "cable";
+ int vid, dsaport;
+
+ vid = get_vlan_vid(ifname);
+ dsaport = get_dsa_port(ifname);
+
/*
* Prevent service from starting the reconnect
* procedure as we do not want the DHCP client
* to run when tethering.
*/
- if (vid >= 0)
+ if((vid >= 0) && (dsaport >= 0))
+ snprintf(group, sizeof(group), "p%02x_%03x_cable", dsaport, vid);
+ else if (vid >= 0)
snprintf(group, sizeof(group), "%03x_cable", vid);
+ else if (dsaport >= 0)
+ snprintf(group, sizeof(group), "p%02x_cable", dsaport);
connman_network_set_group(network, group);
}
static int eth_tech_set_tethering(struct connman_technology *technology,
const char *identifier, const char *passphrase,
- const char *bridge, bool enabled, bool hidden)
+ const char *bridge, bool enabled)
{
if (!connman_technology_is_tethering_allowed(
CONNMAN_SERVICE_TYPE_ETHERNET))
#include <errno.h>
#include <net/if.h>
+#include <stdio.h>
+#include <string.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
};
static GList *cdc_interface_list = NULL;
+static GHashTable *cdc_mac_hash = NULL;
+
+static void add_station(int index)
+{
+ char *path, line[128] = {'\0'};
+ char *ifname = connman_inet_ifname(index);
+ char *mac;
+ FILE *f;
+
+ if (ifname == NULL)
+ return;
+
+ path = g_strdup_printf("/sys/class/usb_mode/%s/f_rndis/ethaddr",
+ ifname);
+
+ f = fopen(path, "re");
+
+ g_free(ifname);
+ g_free(path);
+
+ if (f == NULL)
+ return;
+
+ if (fgets(line, sizeof(line), f) == NULL) {
+ fclose(f);
+ return;
+ }
+
+ fclose(f);
+
+ mac = g_ascii_strdown(line, strlen(line) - 1);
+ DBG("Add station %s in Technology %d", mac,
+ CONNMAN_SERVICE_TYPE_GADGET);
+
+ g_hash_table_insert(cdc_mac_hash, GINT_TO_POINTER(index),
+ mac);
+
+ connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_GADGET,
+ mac);
+}
+
+static void remove_station(int index)
+{
+ char *mac;
+ mac = g_hash_table_lookup(cdc_mac_hash, GINT_TO_POINTER(index));
+ if (mac == NULL)
+ return;
+
+ connman_technology_tethering_remove_station(mac);
+
+ g_hash_table_remove(cdc_mac_hash, GINT_TO_POINTER(index));
+}
+
+static gboolean remove_all_station(gpointer key, gpointer value, gpointer user_data)
+{
+ char *mac;
+ mac = value;
+ if (mac == NULL)
+ return TRUE;
+
+ connman_technology_tethering_remove_station(mac);
+
+ return TRUE;
+}
+
static void gadget_tech_add_interface(struct connman_technology *technology,
int index, const char *name, const char *ident)
cdc_interface_list = g_list_remove(cdc_interface_list,
GINT_TO_POINTER((int) index));
+
+ remove_station(index);
}
static void gadget_tech_enable_tethering(struct connman_technology *technology,
connman_inet_ifup(index);
connman_inet_add_to_bridge(index, bridge);
+
+ add_station(index);
}
}
connman_inet_remove_from_bridge(index, bridge);
+ remove_station(index);
+
connman_inet_ifdown(index);
connman_technology_tethering_notify(technology, false);
static int gadget_tech_set_tethering(struct connman_technology *technology,
const char *identifier, const char *passphrase,
- const char *bridge, bool enabled, bool hidden)
+ const char *bridge, bool enabled)
{
DBG("bridge %s enabled %d", bridge, enabled);
static int gadget_tech_probe(struct connman_technology *technology)
{
+ DBG("tech probe %p", technology);
+
+ cdc_mac_hash = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, NULL, g_free);
+
return 0;
}
static void gadget_tech_remove(struct connman_technology *technology)
{
+ DBG("tech remove %p", technology);
+
g_list_free(cdc_interface_list);
cdc_interface_list = NULL;
+
+ if (cdc_mac_hash) {
+ g_hash_table_foreach_remove(cdc_mac_hash, remove_all_station,
+ NULL);
+ g_hash_table_destroy(cdc_mac_hash);
+ cdc_mac_hash = NULL;
+ }
}
static struct connman_technology_driver gadget_tech_driver = {
&path, DBUS_TYPE_STRING, &type, DBUS_TYPE_INVALID);
if (!dbus_connection_send_with_reply(connection, message,
- ®ister_call, TIMEOUT)) {
- dbus_message_unref(message);
+ ®ister_call, TIMEOUT))
goto out;
- }
if (!dbus_pending_call_set_notify(register_call,
register_agent_cb, NULL, NULL))
struct network_context {
char *path;
int index;
+ struct connman_network *network;
enum connman_ipconfig_method ipv4_method;
struct connman_ipaddress *ipv4_address;
enum connman_ipconfig_method ipv6_method;
struct connman_ipaddress *ipv6_address;
char *ipv6_nameservers;
+
+ int refcount;
+
+ bool active;
+ bool valid_apn; /* APN is 'valid' if length > 0 */
};
struct modem_data {
char *path;
struct connman_device *device;
- struct connman_network *network;
- struct network_context *context;
+ GSList *context_list;
/* Modem Interface */
char *serial;
bool attached;
bool cm_powered;
- /* ConnectionContext Interface */
- bool active;
- bool valid_apn; /* APN is 'valid' if length > 0 */
-
/* SimManager Interface */
char *imsi;
return pos + 1;
}
+ static struct network_context *get_context_with_path(GSList *context_list,
+ const gchar *path)
+ {
+ GSList *list;
+
+ DBG("path %s", path);
+
+ for (list = context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (g_strcmp0(context->path, path) == 0)
+ return context;
+ }
+
+ return NULL;
+ }
+
+ static struct network_context *get_context_with_network(GSList *context_list,
+ const struct connman_network *network)
+ {
+ GSList *list;
+
+ DBG("network %p", network);
+
+ for (list = context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->network == network)
+ return context;
+ }
+
+ return NULL;
+ }
+
static struct network_context *network_context_alloc(const char *path)
{
struct network_context *context;
context->ipv6_address = NULL;
context->ipv6_nameservers = NULL;
+ context->refcount = 1;
+
return context;
}
- static void network_context_free(struct network_context *context)
+ static void network_context_ref(struct network_context *context)
+ {
+ DBG("%p ref %d", context, context->refcount + 1);
+
+ __sync_fetch_and_add(&context->refcount, 1);
+ }
+
+ static void network_context_unref(struct network_context *context)
{
+ DBG("%p ref %d", context, context->refcount - 1);
+
+ if (__sync_fetch_and_sub(&context->refcount, 1) != 1)
+ return;
+
g_free(context->path);
connman_ipaddress_free(context->ipv4_address);
connman_ipaddress_free(context->ipv6_address);
g_free(context->ipv6_nameservers);
- free(context);
+ g_free(context);
}
- static void set_connected(struct modem_data *modem)
+ static void set_connected(struct modem_data *modem,
+ struct network_context *context)
{
struct connman_service *service;
bool setip = false;
DBG("%s", modem->path);
- index = modem->context->index;
+ index = context->index;
- method = modem->context->ipv4_method;
- if (index < 0 || (!modem->context->ipv4_address &&
+ method = context->ipv4_method;
+ if (index < 0 || (!context->ipv4_address &&
method == CONNMAN_IPCONFIG_METHOD_FIXED)) {
connman_error("Invalid index and/or address");
return;
}
- service = connman_service_lookup_from_network(modem->network);
+ service = connman_service_lookup_from_network(context->network);
if (!service)
return;
connman_service_create_ip4config(service, index);
- connman_network_set_ipv4_method(modem->network, method);
+ connman_network_set_ipv4_method(context->network, method);
if (method == CONNMAN_IPCONFIG_METHOD_FIXED ||
method == CONNMAN_IPCONFIG_METHOD_DHCP) {
}
if (method == CONNMAN_IPCONFIG_METHOD_FIXED) {
- connman_network_set_ipaddress(modem->network,
- modem->context->ipv4_address);
+ connman_network_set_ipaddress(context->network,
+ context->ipv4_address);
}
- method = modem->context->ipv6_method;
+ method = context->ipv6_method;
connman_service_create_ip6config(service, index);
- connman_network_set_ipv6_method(modem->network, method);
+ connman_network_set_ipv6_method(context->network, method);
if (method == CONNMAN_IPCONFIG_METHOD_AUTO) {
setip = true;
}
/* Set the nameservers */
- if (modem->context->ipv4_nameservers &&
- modem->context->ipv6_nameservers) {
+ if (context->ipv4_nameservers &&
+ context->ipv6_nameservers) {
nameservers = g_strdup_printf("%s %s",
- modem->context->ipv4_nameservers,
- modem->context->ipv6_nameservers);
- connman_network_set_nameservers(modem->network, nameservers);
+ context->ipv4_nameservers,
+ context->ipv6_nameservers);
+ connman_network_set_nameservers(context->network, nameservers);
g_free(nameservers);
- } else if (modem->context->ipv4_nameservers) {
- connman_network_set_nameservers(modem->network,
- modem->context->ipv4_nameservers);
- } else if (modem->context->ipv6_nameservers) {
- connman_network_set_nameservers(modem->network,
- modem->context->ipv6_nameservers);
+ } else if (context->ipv4_nameservers) {
+ connman_network_set_nameservers(context->network,
+ context->ipv4_nameservers);
+ } else if (context->ipv6_nameservers) {
+ connman_network_set_nameservers(context->network,
+ context->ipv6_nameservers);
}
if (setip) {
- connman_network_set_index(modem->network, index);
- connman_network_set_connected(modem->network, true);
+ connman_network_set_index(context->network, index);
+ connman_network_set_connected(context->network, true);
}
}
- static void set_disconnected(struct modem_data *modem)
+ static void set_disconnected(struct network_context *context)
{
- DBG("%s", modem->path);
+ DBG("%s", context->path);
- if (modem->network)
- connman_network_set_connected(modem->network, false);
+ if (context->network)
+ connman_network_set_connected(context->network, false);
- if (modem->context) {
- g_free(modem->context->ipv4_nameservers);
- modem->context->ipv4_nameservers = NULL;
- if (modem->context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
- modem->context->ipv4_method =
- CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+ g_free(context->ipv4_nameservers);
+ context->ipv4_nameservers = NULL;
+ if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
+ context->ipv4_method =
+ CONNMAN_IPCONFIG_METHOD_UNKNOWN;
- g_free(modem->context->ipv6_nameservers);
- modem->context->ipv6_nameservers = NULL;
- if (modem->context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
- modem->context->ipv6_method =
- CONNMAN_IPCONFIG_METHOD_UNKNOWN;
- }
+ g_free(context->ipv6_nameservers);
+ context->ipv6_nameservers = NULL;
+ if (context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
+ context->ipv6_method =
+ CONNMAN_IPCONFIG_METHOD_UNKNOWN;
}
typedef void (*set_property_cb)(struct modem_data *data,
- bool success);
+ struct network_context *context, bool success);
typedef void (*get_properties_cb)(struct modem_data *data,
DBusMessageIter *dict);
struct property_info {
struct modem_data *modem;
+ struct network_context *context;
const char *path;
const char *interface;
const char *property;
get_properties_cb get_properties_cb;
};
+ static void free_property_info(void * memory)
+ {
+ struct property_info * info = memory;
+
+ if (info->context)
+ network_context_unref(info->context);
+
+ g_free(info);
+ }
+
static void set_property_reply(DBusPendingCall *call, void *user_data)
{
struct property_info *info = user_data;
}
if (info->set_property_cb)
- (*info->set_property_cb)(info->modem, success);
+ (*info->set_property_cb)(info->modem, info->context,
+ success);
dbus_message_unref(reply);
}
static int set_property(struct modem_data *modem,
+ struct network_context *context,
const char *path, const char *interface,
const char *property, int type, void *value,
set_property_cb notify)
if (modem->call_set_property) {
DBG("Cancel pending SetProperty");
-
dbus_pending_call_cancel(modem->call_set_property);
+ dbus_pending_call_unref(modem->call_set_property);
modem->call_set_property = NULL;
}
}
info->modem = modem;
+ info->context = context;
info->path = path;
info->interface = interface;
info->property = property;
info->set_property_cb = notify;
+ if (info->context)
+ network_context_ref(info->context);
+
dbus_pending_call_set_notify(modem->call_set_property,
- set_property_reply, info, g_free);
+ set_property_reply, info, free_property_info);
dbus_message_unref(message);
}
static void context_set_active_reply(struct modem_data *modem,
- bool success)
+ struct network_context *context, bool success)
{
- DBG("%s", modem->path);
+ DBG("%s", context->path);
if (success) {
/*
* cycle the modem in such cases?
*/
- if (!modem->network) {
+ if (!context->network) {
/*
* In the case where we power down the device
* we don't wait for the reply, therefore the network
return;
}
- connman_network_set_error(modem->network,
+ connman_network_set_error(context->network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
}
static int context_set_active(struct modem_data *modem,
- dbus_bool_t active)
+ struct network_context *context,
+ dbus_bool_t active)
{
int err;
DBG("%s active %d", modem->path, active);
- err = set_property(modem, modem->context->path,
+ err = set_property(modem, context, context->path,
OFONO_CONTEXT_INTERFACE,
"Active", DBUS_TYPE_BOOLEAN,
&active,
}
static void cdma_cm_set_powered_reply(struct modem_data *modem,
- bool success)
+ struct network_context *context, bool success)
{
- DBG("%s", modem->path);
+ DBG("%s", context->path);
if (success) {
/*
* cycle the modem in such cases?
*/
- if (!modem->network) {
+ if (!context->network) {
/*
* In the case where we power down the device
* we don't wait for the reply, therefore the network
return;
}
- connman_network_set_error(modem->network,
+ connman_network_set_error(context->network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
}
static int cdma_cm_set_powered(struct modem_data *modem, dbus_bool_t powered)
{
int err;
+ struct network_context *context = NULL;
+
+ if (!modem->context_list)
+ return -1;
DBG("%s powered %d", modem->path, powered);
- err = set_property(modem, modem->path, OFONO_CDMA_CM_INTERFACE,
+ /* In case of CDMA, there is only one context */
+ context = modem->context_list->data;
+ err = set_property(modem, context, modem->path,
+ OFONO_CDMA_CM_INTERFACE,
"Powered", DBUS_TYPE_BOOLEAN,
&powered,
cdma_cm_set_powered_reply);
{
DBG("%s online %d", modem->path, online);
- return set_property(modem, modem->path,
+ return set_property(modem, NULL, modem->path,
OFONO_MODEM_INTERFACE,
"Online", DBUS_TYPE_BOOLEAN,
&online,
DBG("%s powered %d", modem->path, powered);
- err = set_property(modem, modem->path,
+ err = set_property(modem, NULL, modem->path,
OFONO_CM_INTERFACE,
"Powered", DBUS_TYPE_BOOLEAN,
&powered,
modem->set_powered = powered;
- err = set_property(modem, modem->path,
+ err = set_property(modem, NULL, modem->path,
OFONO_MODEM_INTERFACE,
"Powered", DBUS_TYPE_BOOLEAN,
&powered,
connman_ipaddress_free(context->ipv4_address);
context->ipv4_address = NULL;
- context->index = -1;
if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
return;
connman_ipaddress_free(context->ipv6_address);
context->ipv6_address = NULL;
- context->index = -1;
if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
return;
connman_device_set_powered(modem->device, false);
- if (modem->network) {
- connman_device_remove_network(modem->device, modem->network);
- connman_network_unref(modem->network);
- modem->network = NULL;
- }
-
connman_device_unregister(modem->device);
connman_device_unref(modem->device);
modem->device = NULL;
}
- static void add_network(struct modem_data *modem)
+ static void add_network(struct modem_data *modem,
+ struct network_context *context)
{
const char *group;
DBG("%s", modem->path);
- if (modem->network)
+ if (context->network)
return;
- modem->network = connman_network_create(modem->context->path,
- CONNMAN_NETWORK_TYPE_CELLULAR);
- if (!modem->network)
+ context->network = connman_network_create(context->path,
+ CONNMAN_NETWORK_TYPE_CELLULAR);
+ if (!context->network)
return;
- DBG("network %p", modem->network);
+ DBG("network %p", context->network);
- connman_network_set_data(modem->network, modem);
+ connman_network_set_data(context->network, modem);
- connman_network_set_string(modem->network, "Path",
- modem->context->path);
+ connman_network_set_string(context->network, "Path",
+ context->path);
if (modem->name)
- connman_network_set_name(modem->network, modem->name);
+ connman_network_set_name(context->network, modem->name);
else
- connman_network_set_name(modem->network, "");
+ connman_network_set_name(context->network, "");
- connman_network_set_strength(modem->network, modem->strength);
+ connman_network_set_strength(context->network, modem->strength);
- group = get_ident(modem->context->path);
- connman_network_set_group(modem->network, group);
+ group = get_ident(context->path);
+ connman_network_set_group(context->network, group);
- connman_network_set_bool(modem->network, "Roaming",
- modem->roaming);
+ connman_network_set_bool(context->network, "Roaming",
+ modem->roaming);
- if (connman_device_add_network(modem->device, modem->network) < 0) {
- connman_network_unref(modem->network);
- modem->network = NULL;
+ if (connman_device_add_network(modem->device, context->network) < 0) {
+ connman_network_unref(context->network);
+ context->network = NULL;
return;
}
}
- static void remove_network(struct modem_data *modem)
+ static void remove_network(struct modem_data *modem,
+ struct network_context *context)
{
DBG("%s", modem->path);
- if (!modem->network)
+ if (!context || !context->network)
return;
- DBG("network %p", modem->network);
+ DBG("network %p", context->network);
- connman_device_remove_network(modem->device, modem->network);
- connman_network_unref(modem->network);
- modem->network = NULL;
+ if (modem->device)
+ connman_device_remove_network(modem->device, context->network);
+ connman_network_unref(context->network);
+ context->network = NULL;
}
static int set_context_ipconfig(struct network_context *context,
DBG("%s context path %s", modem->path, context_path);
- if (modem->context) {
- /*
- * We have already assigned a context to this modem
- * and we do only support one Internet context.
- */
- return -EALREADY;
- }
-
context = network_context_alloc(context_path);
if (!context)
return -ENOMEM;
dbus_message_iter_get_basic(&value, &apn);
if (apn && strlen(apn) > 0)
- modem->valid_apn = true;
+ context->valid_apn = true;
else
- modem->valid_apn = false;
+ context->valid_apn = false;
DBG("%s AccessPointName '%s'", modem->path, apn);
} else if (g_str_equal(key, "Protocol") &&
}
if (g_strcmp0(context_type, "internet") != 0) {
- network_context_free(context);
+ network_context_unref(context);
return -EINVAL;
}
if (ip_protocol)
set_context_ipconfig(context, ip_protocol);
- modem->context = context;
- modem->active = active;
+ context->active = active;
+ modem->context_list = g_slist_prepend(modem->context_list, context);
g_hash_table_replace(context_hash, g_strdup(context_path), modem);
- if (modem->valid_apn && modem->attached &&
- has_interface(modem->interfaces,
- OFONO_API_NETREG)) {
- add_network(modem);
- }
+ if (context->valid_apn && modem->attached &&
+ has_interface(modem->interfaces, OFONO_API_NETREG))
+ add_network(modem, context);
return 0;
}
static void remove_cm_context(struct modem_data *modem,
- const char *context_path)
+ struct network_context *context)
{
- if (!modem->context)
+ if (!modem->context_list)
return;
+ if (!context)
+ return;
+
+ g_hash_table_remove(context_hash, context->path);
+
+ if (context->network)
+ remove_network(modem, context);
+ modem->context_list = g_slist_remove(modem->context_list, context);
+
+ network_context_unref(context);
+ context = NULL;
+ }
+
+ static void remove_all_contexts(struct modem_data *modem)
+ {
+ GSList *list = NULL;
- if (modem->network)
- remove_network(modem);
+ DBG("");
+
+ if (modem->context_list == NULL)
+ return;
+
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
- g_hash_table_remove(context_hash, context_path);
+ remove_cm_context(modem, context);
+ }
+ g_slist_free(modem->context_list);
+ modem->context_list = NULL;
+ }
- network_context_free(modem->context);
- modem->context = NULL;
+ static void remove_all_networks(struct modem_data *modem)
+ {
+ GSList *list;
- modem->valid_apn = false;
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
- if (modem->network)
- remove_network(modem);
+ remove_network(modem, context);
+ }
}
static gboolean context_changed(DBusConnection *conn,
DBusMessage *message,
void *user_data)
{
+ struct network_context *context = NULL;
const char *context_path = dbus_message_get_path(message);
struct modem_data *modem = NULL;
DBusMessageIter iter, value;
if (!modem)
return TRUE;
+ context = get_context_with_path(modem->context_list, context_path);
+ if (!context)
+ return TRUE;
+
if (!dbus_message_iter_init(message, &iter))
return TRUE;
if (g_str_equal(key, "Settings")) {
DBG("%s Settings", modem->path);
- extract_ipv4_settings(&value, modem->context);
+ extract_ipv4_settings(&value, context);
} else if (g_str_equal(key, "IPv6.Settings")) {
DBG("%s IPv6.Settings", modem->path);
- extract_ipv6_settings(&value, modem->context);
+ extract_ipv6_settings(&value, context);
} else if (g_str_equal(key, "Active")) {
dbus_bool_t active;
dbus_message_iter_get_basic(&value, &active);
- modem->active = active;
+ context->active = active;
- DBG("%s Active %d", modem->path, modem->active);
+ DBG("%s Active %d", modem->path, context->active);
- if (modem->active)
- set_connected(modem);
+ if (context->active)
+ set_connected(modem, context);
else
- set_disconnected(modem);
+ set_disconnected(context);
} else if (g_str_equal(key, "AccessPointName")) {
const char *apn;
DBG("%s AccessPointName %s", modem->path, apn);
if (apn && strlen(apn) > 0) {
- modem->valid_apn = true;
+ context->valid_apn = true;
- if (modem->network)
+ if (context->network)
return TRUE;
if (!modem->attached)
OFONO_API_NETREG))
return TRUE;
- add_network(modem);
+ add_network(modem, context);
- if (modem->active)
- set_connected(modem);
+ if (context->active)
+ set_connected(modem, context);
} else {
- modem->valid_apn = false;
+ context->valid_apn = false;
- if (!modem->network)
+ if (!context->network)
return TRUE;
- remove_network(modem);
+ remove_network(modem, context);
}
} else if (g_str_equal(key, "Protocol") &&
dbus_message_iter_get_basic(&value, &ip_protocol);
- set_context_ipconfig(modem->context, ip_protocol);
+ set_context_ipconfig(context, ip_protocol);
}
return TRUE;
dbus_message_iter_next(&entry);
dbus_message_iter_recurse(&entry, &value);
- if (add_cm_context(modem, context_path, &value) == 0)
+ if (add_cm_context(modem, context_path, &value))
break;
dbus_message_iter_next(&dict);
const char *path = dbus_message_get_path(message);
char *context_path;
struct modem_data *modem;
- DBusMessageIter iter, properties;
+ DBusMessageIter iter, properties, dict;
DBG("%s", path);
dbus_message_iter_next(&iter);
dbus_message_iter_recurse(&iter, &properties);
+ /* Sometimes, we get an array instead of dict */
+ if (dbus_message_iter_get_arg_type(&properties) == DBUS_TYPE_ARRAY) {
+ /* Must recurse again */
+ dbus_message_iter_recurse(&properties, &dict);
+ if (add_cm_context(modem, context_path, &dict) != 0)
+ return TRUE;
+ }
if (add_cm_context(modem, context_path, &properties) != 0)
return TRUE;
const char *path = dbus_message_get_path(message);
const char *context_path;
struct modem_data *modem;
+ struct network_context *context;
DBusMessageIter iter;
DBG("context path %s", path);
if (!modem)
return TRUE;
- remove_cm_context(modem, context_path);
+ context = get_context_with_path(modem->context_list, context_path);
+ remove_cm_context(modem, context);
return TRUE;
}
DBusMessageIter* value)
{
char *name;
+ GSList *list;
dbus_message_iter_get_basic(value, &name);
g_free(modem->name);
modem->name = g_strdup(name);
- if (!modem->network)
+ if (!modem->context_list)
return;
- connman_network_set_name(modem->network, modem->name);
- connman_network_update(modem->network);
+ /* For all the context */
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->network) {
+ connman_network_set_name(context->network, modem->name);
+ connman_network_update(context->network);
+ }
+ }
}
static void netreg_update_strength(struct modem_data *modem,
DBusMessageIter *value)
{
+ GSList *list;
+
dbus_message_iter_get_basic(value, &modem->strength);
DBG("%s Strength %d", modem->path, modem->strength);
- if (!modem->network)
+ if (!modem->context_list)
return;
/*
if (modem->data_strength != 0)
return;
- connman_network_set_strength(modem->network, modem->strength);
- connman_network_update(modem->network);
+ /* For all the context */
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->network) {
+ connman_network_set_strength(context->network,
+ modem->strength);
+ connman_network_update(context->network);
+ }
+ }
}
/* Retrieve 1xEVDO Data Strength signal */
static void netreg_update_datastrength(struct modem_data *modem,
DBusMessageIter *value)
{
+ GSList *list;
+
dbus_message_iter_get_basic(value, &modem->data_strength);
DBG("%s Data Strength %d", modem->path, modem->data_strength);
- if (!modem->network)
+ if (!modem->context_list)
return;
/*
if (modem->data_strength == 0)
return;
- connman_network_set_strength(modem->network, modem->data_strength);
- connman_network_update(modem->network);
+ /* For all the context */
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->network) {
+ connman_network_set_strength(context->network,
+ modem->data_strength);
+ connman_network_update(context->network);
+ }
+ }
}
static void netreg_update_status(struct modem_data *modem,
{
char *status;
bool roaming;
+ GSList *list;
dbus_message_iter_get_basic(value, &status);
modem->roaming = roaming;
- if (!modem->network)
+ if (!modem->context_list)
return;
- connman_network_set_bool(modem->network,
+ /* For all the context */
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->network) {
+ connman_network_set_bool(context->network,
"Roaming", modem->roaming);
- connman_network_update(modem->network);
+ connman_network_update(context->network);
+ }
+ }
}
static void netreg_update_regdom(struct modem_data *modem,
static void netreg_properties_reply(struct modem_data *modem,
DBusMessageIter *dict)
{
+ GSList *list = NULL;
+
DBG("%s", modem->path);
while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
dbus_message_iter_next(dict);
}
- if (!modem->context) {
+ if (!modem->context_list) {
/*
* netgreg_get_properties() was issued after we got
* cm_get_contexts_reply() where we create the
*/
return;
}
-
- if (modem->valid_apn)
- add_network(modem);
-
- if (modem->active)
- set_connected(modem);
+ /* Check for all contexts if they are valids and/or actives */
+ for (list = modem->context_list; list; list = list->next) {
+ struct network_context *context = list->data;
+
+ if (context->valid_apn)
+ add_network(modem, context);
+ if (context->active)
+ set_connected(modem, context);
+ }
}
static int netreg_get_properties(struct modem_data *modem)
static void add_cdma_network(struct modem_data *modem)
{
+ struct network_context *context = NULL;
/* Be sure that device is created before adding CDMA network */
if (!modem->device)
return;
* CDMA modems don't need contexts for data call, however the current
* add_network() logic needs one, so we create one to proceed.
*/
- if (!modem->context)
- modem->context = network_context_alloc(modem->path);
+ if (!modem->context_list) {
+ context = network_context_alloc(modem->path);
+ modem->context_list = g_slist_prepend(modem->context_list,
+ context);
+ } else
+ context = modem->context_list->data;
if (!modem->name)
modem->name = g_strdup("CDMA Network");
- add_network(modem);
+ add_network(modem, context);
if (modem->cdma_cm_powered)
- set_connected(modem);
+ set_connected(modem, context);
}
static gboolean cdma_netreg_changed(DBusConnection *conn,
if (modem->registered)
add_cdma_network(modem);
else
- remove_network(modem);
+ remove_all_networks(modem);
return TRUE;
}
if (modem->registered)
add_cdma_network(modem);
else
- remove_network(modem);
+ remove_all_networks(modem);
}
static int cdma_netreg_get_properties(struct modem_data *modem)
DBG("%s Attached %d", modem->path, modem->attached);
if (!modem->attached) {
- remove_network(modem);
+ remove_all_networks(modem);
return;
}
static void cdma_cm_update_powered(struct modem_data *modem,
DBusMessageIter *value)
{
+ struct network_context *context = NULL;
dbus_bool_t cdma_cm_powered;
dbus_message_iter_get_basic(value, &cdma_cm_powered);
DBG("%s CDMA cm Powered %d", modem->path, modem->cdma_cm_powered);
- if (!modem->network)
+ if (!modem->context_list)
return;
+ /* In case of CDMA, there is only one context */
+ context = modem->context_list->data;
if (modem->cdma_cm_powered)
- set_connected(modem);
+ set_connected(modem, context);
else
- set_disconnected(modem);
+ set_disconnected(context);
}
static void cdma_cm_update_settings(struct modem_data *modem,
{
DBG("%s Settings", modem->path);
- extract_ipv4_settings(value, modem->context);
+ extract_ipv4_settings(value, modem->context_list->data);
}
static gboolean cdma_cm_changed(DBusConnection *conn,
if (!modem)
return TRUE;
- if (modem->online && !modem->network)
+ if (modem->online && !modem->context_list)
cdma_netreg_get_properties(modem);
if (!dbus_message_iter_init(message, &iter))
if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
cdma_netreg_get_properties(modem);
- if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM))
- remove_cm_context(modem, modem->context->path);
+ if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM)) {
+ if (modem->call_get_contexts) {
+ DBG("cancelling pending GetContexts call");
+ dbus_pending_call_cancel(modem->call_get_contexts);
+ dbus_pending_call_unref(modem->call_get_contexts);
+ modem->call_get_contexts = NULL;
+ }
+ remove_all_contexts(modem);
+ }
if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_CM))
- remove_cm_context(modem, modem->context->path);
+ remove_all_contexts(modem);
if (api_removed(old_ifaces, new_ifaces, OFONO_API_NETREG))
- remove_network(modem);
+ remove_all_networks(modem);
if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
- remove_network(modem);
+ remove_all_networks(modem);
}
static gboolean modem_changed(DBusConnection *conn, DBusMessage *message,
DBG("%s Powered %d", modem->path, modem->powered);
- if (!modem->powered)
- modem_set_powered(modem, TRUE);
+ /* Set the powered according to the value */
+ modem_set_powered(modem, powered);
} else if (g_str_equal(key, "Online")) {
dbus_bool_t online;
DBG("%s", modem->path);
- if (modem->call_set_property)
+ if (modem->call_set_property) {
dbus_pending_call_cancel(modem->call_set_property);
+ dbus_pending_call_unref(modem->call_set_property);
+ modem->call_set_property = NULL;
+ }
- if (modem->call_get_properties)
+ if (modem->call_get_properties) {
dbus_pending_call_cancel(modem->call_get_properties);
+ dbus_pending_call_unref(modem->call_get_properties);
+ modem->call_get_properties = NULL;
+ }
- if (modem->call_get_contexts)
+ if (modem->call_get_contexts) {
dbus_pending_call_cancel(modem->call_get_contexts);
+ dbus_pending_call_unref(modem->call_get_contexts);
+ modem->call_get_contexts = NULL;
+ }
+
+ /* Must remove the contexts before the device */
+ if (modem->context_list)
+ remove_all_contexts(modem);
if (modem->device)
destroy_device(modem);
- if (modem->context)
- remove_cm_context(modem, modem->context->path);
-
g_free(modem->serial);
g_free(modem->name);
g_free(modem->imsi);
static int network_connect(struct connman_network *network)
{
+ struct network_context *context;
struct modem_data *modem = connman_network_get_data(network);
DBG("%s network %p", modem->path, network);
+ if (!g_hash_table_lookup(modem_hash, modem->path))
+ return -ENODEV;
+
+ context = get_context_with_network(modem->context_list, network);
+ if (!context)
+ return -ENODEV;
+
if (has_interface(modem->interfaces, OFONO_API_CM))
- return context_set_active(modem, TRUE);
+ return context_set_active(modem, context, TRUE);
else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
return cdma_cm_set_powered(modem, TRUE);
static int network_disconnect(struct connman_network *network)
{
+ struct network_context *context;
struct modem_data *modem = connman_network_get_data(network);
DBG("%s network %p", modem->path, network);
+ if (!g_hash_table_lookup(modem_hash, modem->path))
+ return -ENODEV;
+
+ context = get_context_with_network(modem->context_list, network);
+ if (!context)
+ return -ENODEV;
+
if (has_interface(modem->interfaces, OFONO_API_CM))
- return context_set_active(modem, FALSE);
+ return context_set_active(modem, context, FALSE);
else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
return cdma_cm_set_powered(modem, FALSE);
dbus_message_unref(reply);
}
- static void append_string(DBusMessageIter *iter, void *user_data)
- {
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
- }
-
static void append_string_list(DBusMessageIter *iter, void *user_data)
{
char **list = user_data;
g_free(interface);
}
- str = connman_service_get_domainname(default_service);
- if (str)
- connman_dbus_dict_append_array(&dict, "Domains",
- DBUS_TYPE_STRING, append_string, &str);
-
str_list = connman_service_get_nameservers(default_service);
if (str_list)
connman_dbus_dict_append_array(&dict, "Nameservers",
str = g_key_file_get_string(keyfile, groupname, "AllowedBearers",
NULL);
if (str) {
+ g_slist_free(config->allowed_bearers);
+ config->allowed_bearers = NULL;
tokens = g_strsplit(str, " ", 0);
for (i = 0; tokens[i]; i++) {
for (i = 0; groupnames[i]; i++) {
group = g_new0(struct policy_group, 1);
- group->config = g_new0(struct connman_session_config, 1);
+ group->config = connman_session_create_default_config();
err = load_policy(keyfile, groupnames[i], group);
if (err < 0) {
* We cannot unref the resolver here as resolv struct is manipulated
* by gresolv.c after we return from this callback.
*/
- g_timeout_add_seconds(0, remove_resolv, data);
+ g_idle_add(remove_resolv, data);
data->resolv_id = 0;
}
dbus_pending_call_unref(call);
}
- static int connect_provider(struct connection_data *data, void *user_data)
+ static int connect_provider(struct connection_data *data, void *user_data,
+ const char *dbus_sender)
{
DBusPendingCall *call;
DBusMessage *message;
struct config_create_data *cb_data = user_data;
- DBG("data %p user %p path %s", data, cb_data, data->path);
+ DBG("data %p user %p path %s sender %s", data, cb_data, data->path,
+ dbus_sender);
data->connect_pending = false;
+ #define VPN_CONNECT2 "Connect2"
+
+ /* We need to pass original dbus sender to connman-vpnd,
+ * use a Connect2 method for that.
+ */
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
VPN_CONNECTION_INTERFACE,
- VPN_CONNECT);
+ VPN_CONNECT2);
if (!message)
return -ENOMEM;
+ if (dbus_sender)
+ dbus_message_append_args(message, DBUS_TYPE_STRING,
+ &dbus_sender, NULL);
+ else
+ dbus_sender = "";
+
if (!dbus_connection_send_with_reply(connection, message,
&call, DBUS_TIMEOUT)) {
connman_error("Unable to call %s.%s()",
- VPN_CONNECTION_INTERFACE, VPN_CONNECT);
+ VPN_CONNECTION_INTERFACE, VPN_CONNECT2);
dbus_message_unref(message);
return -EINVAL;
}
connman_provider_set_domain(data->provider,
data->domain);
- if (data->connect_pending)
- connect_provider(data, data->cb_data);
+ if (data->connect_pending) {
+ const char *dbus_sender = NULL;
+
+ if (data->cb_data && data->cb_data->message) {
+ dbus_sender =
+ dbus_message_get_sender(data->cb_data->message);
+ }
+ connect_provider(data, data->cb_data, dbus_sender);
+ }
return;
return 0;
}
- static int provider_connect(struct connman_provider *provider)
+ static int provider_connect(struct connman_provider *provider,
+ const char *dbus_sender)
{
struct connection_data *data;
if (!data)
return -EINVAL;
- return connect_provider(data, NULL);
+ return connect_provider(data, NULL, dbus_sender);
}
static void disconnect_reply(DBusPendingCall *call, void *user_data)
struct connection_data *data = NULL;
DBusMessageIter iter, value;
bool ip_set = false;
- int err;
+ int err = 0;
char *str;
const char *key;
const char *signature = DBUS_TYPE_STRING_AS_STRING
#define P2P_LISTEN_PERIOD 500
#define P2P_LISTEN_INTERVAL 2000
+ #define ASSOC_STATUS_NO_CLIENT 17
+ #define LOAD_SHAPING_MAX_RETRIES 3
static struct connman_technology *wifi_technology = NULL;
static struct connman_technology *p2p_technology = NULL;
+ enum wifi_ap_capability{
+ WIFI_AP_UNKNOWN = 0,
+ WIFI_AP_SUPPORTED = 1,
+ WIFI_AP_NOT_SUPPORTED = 2,
+ };
+
struct hidden_params {
char ssid[32];
unsigned int ssid_len;
char *identity;
+ char *anonymous_identity;
+ char *subject_match;
+ char *altsubject_match;
+ char *domain_suffix_match;
+ char *domain_match;
char *passphrase;
char *security;
GSupplicantScanParams *scan_params;
unsigned int timeout;
};
+ struct wifi_tethering_info {
+ struct wifi_data *wifi;
+ struct connman_technology *technology;
+ char *ifname;
+ GSupplicantSSID *ssid;
+ };
+
struct wifi_data {
char *identifier;
struct connman_device *device;
bool connected;
bool disconnecting;
bool tethering;
+ enum wifi_ap_capability ap_supported;
bool bridged;
bool interface_ready;
const char *bridge;
unsigned flags;
unsigned int watch;
int retries;
+ int load_shaping_retries;
struct hidden_params *hidden;
bool postpone_hidden;
+ struct wifi_tethering_info *tethering_param;
/**
* autoscan "emulation".
*/
unsigned int p2p_find_timeout;
unsigned int p2p_connection_timeout;
struct connman_peer *pending_peer;
- GSupplicantPeer *peer;
+ GSList *peers;
bool p2p_connecting;
bool p2p_device;
int servicing;
+#if defined TIZEN_EXT
+ int assoc_retry_count;
+ struct connman_network *scan_pending_network;
+ bool allow_full_scan;
+#endif
int disconnect_code;
int assoc_code;
};
+#if defined TIZEN_EXT
+#include "connman.h"
+#include "dbus.h"
+
+#define TIZEN_ASSOC_RETRY_COUNT 4
+
+static gboolean wifi_first_scan = false;
+static gboolean found_with_first_scan = false;
+static gboolean is_wifi_notifier_registered = false;
+#endif
+
+
static GList *iface_list = NULL;
static GList *pending_wifi_device = NULL;
bool wfd_service_registered = false;
static void start_autoscan(struct connman_device *device);
+
+ static int tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
+ const char *bridge, bool enabled);
+
+#if defined TIZEN_EXT
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
+
+struct enc_method_call_data {
+ DBusConnection *connection;
+ struct connman_network *network;
+};
+
+static struct enc_method_call_data encrypt_request_data;
+
+static void encryption_request_reply(DBusPendingCall *call,
+ void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args;
+ char *out_data;
+ struct connman_service *service;
+ gchar* encrypted_value = NULL;
+ struct connman_network *network = encrypt_request_data.network;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ DBG("send_encryption_request() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_get_basic(&args, &out_data);
+
+ encrypted_value = g_strdup((const gchar *)out_data);
+ service = connman_service_lookup_from_network(network);
+
+ if (!service) {
+ DBG("encryption result: no service");
+ goto done;
+ }
+
+ if (connman_service_get_favorite(service)) {
+ __connman_service_set_passphrase(service, encrypted_value);
+ __connman_service_save(service);
+ } else
+ connman_network_set_string(network, "WiFi.Passphrase",
+ encrypted_value);
+
+ DBG("encryption result: succeeded");
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ dbus_connection_unref(encrypt_request_data.connection);
+ g_free(encrypted_value);
+
+ encrypt_request_data.connection = NULL;
+ encrypt_request_data.network = NULL;
+}
+
+static int send_encryption_request(const char *passphrase,
+ struct connman_network *network)
+{
+ DBusConnection *connection = NULL;
+ DBusMessage *msg = NULL;
+ DBusPendingCall *call;
+
+ if (!passphrase) {
+ DBG("Invalid parameter");
+ return -EINVAL;
+ }
+
+ connection = connman_dbus_get_connection();
+ if (!connection) {
+ DBG("dbus connection does not exist");
+ return -EINVAL;
+ }
+
+ msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
+ NETCONFIG_WIFI_INTERFACE, "EncryptPassphrase");
+ if (!msg) {
+ dbus_connection_unref(connection);
+ return -EINVAL;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_connection_send_with_reply(connection, msg,
+ &call, DBUS_TIMEOUT_USE_DEFAULT)) {
+ dbus_message_unref(msg);
+ dbus_connection_unref(connection);
+ return -EIO;
+ }
+
+ if (!call) {
+ dbus_message_unref(msg);
+ dbus_connection_unref(connection);
+ return -EIO;
+ }
+
+ encrypt_request_data.connection = connection;
+ encrypt_request_data.network = network;
+
+ dbus_pending_call_set_notify(call, encryption_request_reply, NULL, NULL);
+ dbus_message_unref(msg);
+
+ return 0;
+}
+#endif
+
static int p2p_tech_probe(struct connman_technology *technology)
{
p2p_technology = technology;
connman_peer_unref(wifi->pending_peer);
wifi->pending_peer = NULL;
}
-
- wifi->peer = NULL;
}
static gboolean peer_connect_timeout(gpointer data)
if (wifi->p2p_connecting) {
enum connman_peer_state state = CONNMAN_PEER_STATE_FAILURE;
+ GSupplicantPeer *gs_peer =
+ g_supplicant_interface_peer_lookup(wifi->interface,
+ connman_peer_get_identifier(wifi->pending_peer));
- if (g_supplicant_peer_has_requested_connection(wifi->peer))
+ if (g_supplicant_peer_has_requested_connection(gs_peer))
state = CONNMAN_PEER_STATE_IDLE;
connman_peer_set_state(wifi->pending_peer, state);
return -ENODEV;
wifi = connman_device_get_data(device);
- if (!wifi)
+ if (!wifi || !wifi->interface)
return -ENODEV;
if (wifi->p2p_connecting)
return -EBUSY;
- wifi->peer = NULL;
-
gs_peer = g_supplicant_interface_peer_lookup(wifi->interface,
connman_peer_get_identifier(peer));
if (!gs_peer)
peer_connect_callback, wifi);
if (ret == -EINPROGRESS) {
wifi->pending_peer = connman_peer_ref(peer);
- wifi->peer = gs_peer;
wifi->p2p_connecting = true;
- } else if (ret < 0)
+ } else if (ret < 0) {
+ g_free(peer_params->path);
+ g_free(peer_params->wps_pin);
g_free(peer_params);
+ }
return ret;
}
&peer_params);
g_free(peer_params.path);
- if (ret == -EINPROGRESS)
+ if (ret == -EINPROGRESS) {
peer_cancel_timeout(wifi);
+ wifi->p2p_device = false;
+ }
return ret;
}
struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
struct peer_service_registration *reg_data = user_data;
+#if defined TIZEN_EXT
+ if (!wifi)
+ return;
+#endif
+
DBG("");
if (result == 0)
return -ENOMEM;
wifi->state = G_SUPPLICANT_STATE_INACTIVE;
+ wifi->ap_supported = WIFI_AP_UNKNOWN;
+ wifi->tethering_param = NULL;
connman_device_set_data(device, wifi);
wifi->device = connman_device_ref(device);
wifi->networks = NULL;
}
+ static void remove_peers(struct wifi_data *wifi)
+ {
+ GSList *list;
+
+ for (list = wifi->peers; list; list = list->next) {
+ struct connman_peer *peer = list->data;
+
+ connman_peer_unregister(peer);
+ connman_peer_unref(peer);
+ }
+
+ g_slist_free(wifi->peers);
+ wifi->peers = NULL;
+ }
+
static void reset_autoscan(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
g_source_remove(wifi->p2p_connection_timeout);
remove_networks(device, wifi);
+ remove_peers(wifi);
connman_device_set_powered(device, false);
connman_device_set_data(device, NULL);
continue;
}
+#if defined TIZEN_EXT
+ value = g_key_file_get_boolean(keyfile,
+ services[i], "AutoConnect", NULL);
+ if (!value) {
+ g_key_file_free(keyfile);
+ continue;
+ }
+#endif
+
ssid = g_key_file_get_string(keyfile,
services[i], "SSID", NULL);
if (wifi->tethering)
return -EBUSY;
-
+#if defined TIZEN_EXT
+ if (connman_device_get_scanning(device) && !wifi->allow_full_scan)
+#else
if (connman_device_get_scanning(device))
+#endif
return -EALREADY;
connman_device_ref(device);
g_free(hidden);
}
+#if defined TIZEN_EXT
+static void service_state_changed(struct connman_service *service,
+ enum connman_service_state state);
+
+static int network_connect(struct connman_network *network);
+
+static struct connman_notifier notifier = {
+ .name = "wifi",
+ .priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
+ .service_state_changed = service_state_changed,
+};
+
+static void service_state_changed(struct connman_service *service,
+ enum connman_service_state state)
+{
+ enum connman_service_type type;
+
+ type = connman_service_get_type(service);
+ if (type != CONNMAN_SERVICE_TYPE_WIFI)
+ return;
+
+ DBG("service %p state %d", service, state);
+
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ connman_notifier_unregister(¬ifier);
+ is_wifi_notifier_registered = FALSE;
+
+ __connman_device_request_scan(type);
+ break;
+
+ default:
+ break;
+ }
+}
+#endif
+
static void scan_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
return scan_callback(ret, interface, user_data);
}
- scanning = connman_device_get_scanning(device);
+#if defined TIZEN_EXT
+ if (wifi && wifi->allow_full_scan) {
+ int ret;
+ DBG("Trigger Full Channel Scan");
+ wifi->allow_full_scan = FALSE;
- if (scanning) {
+ ret = g_supplicant_interface_scan(wifi->interface, NULL,
+ scan_callback, device);
+ if (ret == 0)
+ return;
+
+ /* On error, let's recall scan_callback, which will cleanup */
+ return scan_callback(ret, interface, user_data);
+ }
+#endif
+
+ scanning = connman_device_get_scanning(device);
+ if (scanning)
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
- }
if (result != -ENOLINK)
+#if defined TIZEN_EXT
+ if (result != -EIO)
+#endif
start_autoscan(device);
/*
if (scanning)
connman_device_unref(device);
+
+#if defined TIZEN_EXT
+ if (wifi && wifi->scan_pending_network && result != -EIO) {
+ network_connect(wifi->scan_pending_network);
+ wifi->scan_pending_network = NULL;
+ connman_network_set_connecting(wifi->network);
+ }
+
+ if (is_wifi_notifier_registered != true &&
+ wifi_first_scan == true && found_with_first_scan == true) {
+ wifi_first_scan = false;
+ found_with_first_scan = false;
+
+ connman_notifier_register(¬ifier);
+ is_wifi_notifier_registered = true;
+ }
+#endif
}
static void scan_callback_hidden(int result,
} else
interval = autoscan->interval * autoscan->base;
+#if defined TIZEN_EXT
+ if (autoscan->interval >= autoscan->limit)
+#else
if (interval > autoscan->limit)
+#endif
interval = autoscan->limit;
throw_wifi_scan(wifi->device, scan_callback_hidden);
}
remove_networks(device, wifi);
+ remove_peers(wifi);
+#if defined TIZEN_EXT
+ wifi->scan_pending_network = NULL;
+
+ if (is_wifi_notifier_registered == true) {
+ connman_notifier_unregister(¬ifier);
+ is_wifi_notifier_registered = false;
+ }
+#endif
+
ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
if (ret < 0)
return ret;
DBG("");
- wifi->p2p_find_timeout = 0;
+ if (wifi) {
+ wifi->p2p_find_timeout = 0;
+
+ g_supplicant_interface_p2p_stop_find(wifi->interface);
+ }
connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
- g_supplicant_interface_p2p_stop_find(wifi->interface);
-
connman_device_unref(device);
reset_autoscan(device);
DBG("result %d wifi %p", result, wifi);
+ if (!wifi)
+ goto error;
+
if (wifi->p2p_find_timeout) {
g_source_remove(wifi->p2p_find_timeout);
wifi->p2p_find_timeout = 0;
return ret;
}
+#if defined TIZEN_EXT
+static void specific_scan_callback(int result, GSupplicantInterface *interface,
+ void *user_data)
+{
+ struct connman_device *device = user_data;
+ struct wifi_data *wifi = connman_device_get_data(device);
+ bool scanning;
+
+ DBG("result %d wifi %p", result, wifi);
+
+ if (wifi && wifi->scan_params) {
+ g_supplicant_free_scan_params(wifi->scan_params);
+ wifi->scan_params = NULL;
+ }
+
+ scanning = connman_device_get_scanning(device);
+ if (scanning) {
+ connman_device_set_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI, false);
+ connman_device_unref(device);
+ }
+}
+
+static int wifi_specific_scan(enum connman_service_type type,
+ struct connman_device *device, int scan_type,
+ GSList *specific_scan_list, void *user_data)
+{
+ GSList *list = NULL;
+ char *ssid = NULL;
+ struct wifi_data *wifi = connman_device_get_data(device);
+ GSupplicantScanParams *scan_params = NULL;
+ struct scan_ssid *scan_ssid = NULL;
+ bool scanning;
+ int ret;
+ int freq;
+ int count = 0;
+
+ if (!wifi)
+ return -ENODEV;
+
+ if (wifi->p2p_device)
+ return 0;
+
+ if (type == CONNMAN_SERVICE_TYPE_P2P)
+ return p2p_find(device);
+
+ if (wifi->tethering)
+ return 0;
+
+ scanning = connman_device_get_scanning(device);
+ if (scanning)
+ return -EALREADY;
+
+ DBG("scan_type: %d", scan_type);
+ if (scan_type == 1) { /* ssid based scan */
+ scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+ if (!scan_params) {
+ DBG("Failed to allocate memory.");
+ return -ENOMEM;
+ }
+
+ for (list = specific_scan_list; list; list = list->next) {
+ ssid = (char *)list->data;
+ int ssid_len = strlen(ssid);
+
+ scan_ssid = g_try_new0(struct scan_ssid, 1);
+ if (!scan_ssid) {
+ DBG("Failed to allocate memory.");
+ g_supplicant_free_scan_params(scan_params);
+ return -ENOMEM;
+ }
+
+ memcpy(scan_ssid->ssid, ssid, (ssid_len + 1));
+ DBG("scan ssid %s len: %d", scan_ssid->ssid, ssid_len);
+ scan_ssid->ssid_len = ssid_len;
+ scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
+ count++;
+ }
+ scan_params->num_ssids = count;
+
+ } else if (scan_type == 2) { /* frequency based scan */
+
+ scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+ if (!scan_params) {
+ DBG("Failed to allocate memory.");
+ return -ENOMEM;
+ }
+
+ guint num_freqs = g_slist_length(specific_scan_list);
+ DBG("num_freqs: %d", num_freqs);
+
+ scan_params->freqs = g_try_new0(uint16_t, num_freqs);
+ if (!scan_params->freqs) {
+ DBG("Failed to allocate memory.");
+ g_free(scan_params);
+ return -ENOMEM;
+ }
+
+ count = 0;
+ for (list = specific_scan_list; list; list = list->next) {
+ freq = (int)list->data;
+
+ scan_params->freqs[count] = freq;
+ DBG("scan_params->freqs[%d]: %d", count, scan_params->freqs[count]);
+ count++;
+ }
+ scan_params->num_freqs = count;
+
+ } else {
+ DBG("Invalid scan");
+ return -EINVAL;
+ }
+
+ reset_autoscan(device);
+ connman_device_ref(device);
+
+ ret = g_supplicant_interface_scan(wifi->interface, scan_params,
+ specific_scan_callback, device);
+
+ if (ret == 0) {
+ connman_device_set_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI, true);
+ } else {
+ g_supplicant_free_scan_params(scan_params);
+ connman_device_unref(device);
+ }
+
+ return ret;
+}
+#endif
+
/*
* Note that the hidden scan is only used when connecting to this specific
* hidden AP first time. It is not used when system autoconnects to hidden AP.
return -ENODEV;
if (wifi->p2p_device)
- return 0;
+ return -EBUSY;
+
+ if (wifi->tethering)
+ return -EBUSY;
if (type == CONNMAN_SERVICE_TYPE_P2P)
return p2p_find(device);
DBG("device %p wifi %p hidden ssid %s", device, wifi->interface, ssid);
- if (wifi->tethering)
- return 0;
-
scanning = connman_device_get_scanning(device);
if (!ssid || ssid_len == 0 || ssid_len > 32) {
ret = g_supplicant_interface_scan(wifi->interface, scan_params,
scan_callback, device);
+
if (ret == 0) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, true);
+#if defined TIZEN_EXT
+ /*To allow the Full Scan after ssid based scan, set the flag here
+ It is required because Tizen does not use the ConnMan specific
+ backgroung Scan feature.Tizen has added the BG Scan feature in
+ net-config. To sync with up ConnMan, we need to issue the Full Scan
+ after SSID specific scan.*/
+ wifi->allow_full_scan = TRUE;
+#endif
} else {
g_supplicant_free_scan_params(scan_params);
connman_device_unref(device);
.disable = wifi_disable,
.scan = wifi_scan,
.set_regdom = wifi_set_regdom,
+#if defined TIZEN_EXT
+ .specific_scan = wifi_specific_scan,
+#endif
};
static void system_ready(void)
return;
wifi->network = NULL;
+
+#if defined TIZEN_EXT
+ wifi->disconnecting = false;
+
+ if (wifi->pending_network == network)
+ wifi->pending_network = NULL;
+
+ if (wifi->scan_pending_network == network)
+ wifi->scan_pending_network = NULL;
+#endif
}
static void connect_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
+#if defined TIZEN_EXT
+ GList *list;
+ struct wifi_data *wifi;
+#endif
struct connman_network *network = user_data;
DBG("network %p result %d", network, result);
+#if defined TIZEN_EXT
+ for (list = iface_list; list; list = list->next) {
+ wifi = list->data;
+
+ if (wifi && wifi->network == network)
+ goto found;
+ }
+
+ /* wifi_data may be invalid because wifi is already disabled */
+ return;
+
+found:
+#endif
if (result == -ENOKEY) {
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_INVALID_KEY);
return G_SUPPLICANT_SECURITY_PSK;
else if (g_str_equal(security, "ieee8021x"))
return G_SUPPLICANT_SECURITY_IEEE8021X;
+#if defined TIZEN_EXT
+ else if (g_str_equal(security, "ft_psk") == TRUE)
+ return G_SUPPLICANT_SECURITY_FT_PSK;
+ else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
+ return G_SUPPLICANT_SECURITY_FT_IEEE8021X;
+#endif
return G_SUPPLICANT_SECURITY_UNKNOWN;
}
ssid->security = network_security(security);
ssid->passphrase = connman_network_get_string(network,
"WiFi.Passphrase");
-
ssid->eap = connman_network_get_string(network, "WiFi.EAP");
/*
ssid->identity = connman_network_get_string(network,
"WiFi.AgentIdentity");
+ ssid->anonymous_identity = connman_network_get_string(network,
+ "WiFi.AnonymousIdentity");
ssid->ca_cert_path = connman_network_get_string(network,
"WiFi.CACertFile");
+ ssid->subject_match = connman_network_get_string(network,
+ "WiFi.SubjectMatch");
+ ssid->altsubject_match = connman_network_get_string(network,
+ "WiFi.AltSubjectMatch");
+ ssid->domain_suffix_match = connman_network_get_string(network,
+ "WiFi.DomainSuffixMatch");
+ ssid->domain_match = connman_network_get_string(network,
+ "WiFi.DomainMatch");
ssid->client_cert_path = connman_network_get_string(network,
"WiFi.ClientCertFile");
ssid->private_key_path = connman_network_get_string(network,
ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
+#if defined TIZEN_EXT
+ ssid->bssid = connman_network_get_bssid(network);
+#endif
+#if defined TIZEN_EXT
+ ssid->freq = connman_network_get_frequency(network);
+#endif
+
if (connman_setting_get_bool("BackgroundScanning"))
ssid->bgscan = BGSCAN_DEFAULT;
}
} else {
wifi->network = connman_network_ref(network);
wifi->retries = 0;
+#if defined TIZEN_EXT
+ wifi->scan_pending_network = NULL;
+#endif
return g_supplicant_interface_connect(interface, ssid,
connect_callback, network);
static void disconnect_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
+#if defined TIZEN_EXT
+ GList *list;
+ struct wifi_data *wifi;
+ struct connman_network *network = user_data;
+
+ DBG("network %p result %d", network, result);
+
+ for (list = iface_list; list; list = list->next) {
+ wifi = list->data;
+
+ if (wifi->network == NULL && wifi->disconnecting == true)
+ wifi->disconnecting = false;
+
+ if (wifi->network == network)
+ goto found;
+ }
+
+ /* wifi_data may be invalid because wifi is already disabled */
+ return;
+
+found:
+#else
struct wifi_data *wifi = user_data;
+#endif
DBG("result %d supplicant interface %p wifi %p",
result, interface, wifi);
}
if (wifi->network) {
- /*
- * if result < 0 supplican return an error because
- * the network is not current.
- * we wont receive G_SUPPLICANT_STATE_DISCONNECTED since it
- * failed, call connman_network_set_connected to report
- * disconnect is completed.
- */
- if (result < 0)
- connman_network_set_connected(wifi->network, false);
+ connman_network_set_connected(wifi->network, false);
+ wifi->network = NULL;
}
- wifi->network = NULL;
-
wifi->disconnecting = false;
+ wifi->connected = false;
if (wifi->pending_network) {
network_connect(wifi->pending_network);
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
int err;
+#if defined TIZEN_EXT
+ struct connman_service *service;
+#endif
DBG("network %p", network);
if (!wifi || !wifi->interface)
return -ENODEV;
+#if defined TIZEN_EXT
+ if (connman_network_get_associating(network) == true) {
+ connman_network_clear_associating(network);
+ connman_network_set_bool(network, "WiFi.UseWPS", false);
+ } else {
+ service = connman_service_lookup_from_network(network);
+
+ if (service != NULL &&
+ (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4) == false &&
+ __connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6) == false) &&
+ (connman_service_get_favorite(service) == false))
+ __connman_service_set_passphrase(service, NULL);
+ }
+
+ if (wifi->pending_network == network)
+ wifi->pending_network = NULL;
+
+ if (wifi->scan_pending_network == network)
+ wifi->scan_pending_network = NULL;
+
+#endif
connman_network_set_associating(network, false);
if (wifi->disconnecting)
wifi->disconnecting = true;
+#if defined TIZEN_EXT
+ err = g_supplicant_interface_disconnect(wifi->interface,
+ disconnect_callback, network);
+#else
err = g_supplicant_interface_disconnect(wifi->interface,
disconnect_callback, wifi);
+#endif
+
if (err < 0)
wifi->disconnecting = false;
if (!wifi)
return;
+ wifi->interface = interface;
g_supplicant_interface_set_data(interface, wifi);
p2p_iface_list = g_list_append(p2p_iface_list, wifi);
wifi->p2p_device = true;
if (!wps_ssid || wps_ssid_len != ssid_len ||
memcmp(ssid, wps_ssid, ssid_len) != 0) {
connman_network_set_associating(network, false);
+#if defined TIZEN_EXT
+ g_supplicant_interface_disconnect(wifi->interface,
+ disconnect_callback, wifi->network);
+
+ connman_network_set_bool(network, "WiFi.UseWPS", false);
+ connman_network_set_string(network, "WiFi.PinWPS", NULL);
+#else
g_supplicant_interface_disconnect(wifi->interface,
disconnect_callback, wifi);
+#endif
return false;
}
wps_key = g_supplicant_interface_get_wps_key(interface);
- ret = send_encryption_request(passphrase, network);
+#if defined TIZEN_EXT
+ /* Check the passphrase and encrypt it
+ */
+ int ret;
+ gchar *passphrase = g_strdup(wps_key);
+
+ connman_network_set_string(network, "WiFi.PinWPS", NULL);
+
+ if (check_passphrase_ext(network, passphrase) < 0) {
+ DBG("[WPS] Invalid passphrase");
+ g_free(passphrase);
+ return true;
+ }
+
++ ret = send_encryption_request(passphrase, passphrase);
+
+ g_free(passphrase);
+
+ if (!ret)
+ DBG("[WPS] Encryption request succeeded");
+ else
+ DBG("[WPS] Encryption request failed %d", ret);
+
+#else
connman_network_set_string(network, "WiFi.Passphrase",
wps_key);
connman_network_set_string(network, "WiFi.PinWPS", NULL);
+#endif
}
return true;
}
+ static bool handle_assoc_status_code(GSupplicantInterface *interface,
+ struct wifi_data *wifi)
+ {
+ if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING &&
+ wifi->assoc_code == ASSOC_STATUS_NO_CLIENT &&
+ wifi->load_shaping_retries < LOAD_SHAPING_MAX_RETRIES) {
+ wifi->load_shaping_retries ++;
+ return TRUE;
+ }
+ wifi->load_shaping_retries = 0;
+ return FALSE;
+ }
+
static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
struct connman_network *network,
struct wifi_data *wifi)
{
+#if defined TIZEN_EXT
+ const char *security;
+ struct connman_service *service;
+
+ if (wifi->connected)
+ return false;
+
+ security = connman_network_get_string(network, "WiFi.Security");
+
+ if (security && g_str_equal(security, "ieee8021x") == true &&
+ wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) {
+ wifi->retries = 0;
+ connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
+
+ return false;
+ }
+
+ if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
+ return false;
+#else
struct connman_service *service;
if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
if (wifi->connected)
return false;
+#endif
service = connman_service_lookup_from_network(network);
if (!service)
return false;
}
+#if defined TIZEN_EXT
+static bool handle_wifi_assoc_retry(struct connman_network *network,
+ struct wifi_data *wifi)
+{
+ const char *security;
+
+ if (!wifi->network || wifi->connected || wifi->disconnecting ||
+ connman_network_get_connecting(network) != true) {
+ wifi->assoc_retry_count = 0;
+ return false;
+ }
+
+ if (wifi->state != G_SUPPLICANT_STATE_ASSOCIATING &&
+ wifi->state != G_SUPPLICANT_STATE_ASSOCIATED) {
+ wifi->assoc_retry_count = 0;
+ return false;
+ }
+
+ security = connman_network_get_string(network, "WiFi.Security");
+ if (security && g_str_equal(security, "ieee8021x") == true &&
+ wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) {
+ wifi->assoc_retry_count = 0;
+ return false;
+ }
+
+ if (++wifi->assoc_retry_count >= TIZEN_ASSOC_RETRY_COUNT) {
+ wifi->assoc_retry_count = 0;
+
+ /* Honestly it's not an invalid-key error,
+ * however QA team recommends that the invalid-key error
+ * might be better to display for user experience.
+ */
+ connman_network_set_error(network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+
+ return false;
+ }
+
+ return true;
+}
+#endif
+
static void interface_state(GSupplicantInterface *interface)
{
struct connman_network *network;
struct wifi_data *wifi;
GSupplicantState state = g_supplicant_interface_get_state(interface);
bool wps;
+ bool old_connected;
wifi = g_supplicant_interface_get_data(interface);
if (!wifi)
return;
+ if (state == G_SUPPLICANT_STATE_COMPLETED) {
+ if (wifi->tethering_param) {
+ g_free(wifi->tethering_param->ssid);
+ g_free(wifi->tethering_param);
+ wifi->tethering_param = NULL;
+ }
+ }
+
device = wifi->device;
if (!device)
return;
switch (state) {
case G_SUPPLICANT_STATE_SCANNING:
+ if (wifi->connected)
+ connman_network_set_connected(network, false);
+
break;
case G_SUPPLICANT_STATE_AUTHENTICATING:
case G_SUPPLICANT_STATE_ASSOCIATING:
+#if defined TIZEN_EXT
+ reset_autoscan(device);
+#else
stop_autoscan(device);
+#endif
if (!wifi->connected)
connman_network_set_associating(network, true);
break;
case G_SUPPLICANT_STATE_COMPLETED:
+#if defined TIZEN_EXT
+ /* though it should be already reset: */
+ reset_autoscan(device);
+
+ wifi->assoc_retry_count = 0;
+
+ wifi->scan_pending_network = NULL;
+
+ /* should be cleared scanning flag */
+ bool scanning = connman_device_get_scanning(device);
+ if (scanning){
+ connman_device_set_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI, false);
+ connman_device_unref(device);
+ }
+#else
/* though it should be already stopped: */
stop_autoscan(device);
+#endif
if (!handle_wps_completion(interface, network, device, wifi))
break;
connman_network_set_connected(network, true);
+
wifi->disconnect_code = 0;
wifi->assoc_code = 0;
+ wifi->load_shaping_retries = 0;
break;
case G_SUPPLICANT_STATE_DISCONNECTED:
if (is_idle(wifi))
break;
+ if (handle_assoc_status_code(interface, wifi))
+ break;
+
/* If previous state was 4way-handshake, then
* it's either: psk was incorrect and thus we retry
* or if we reach the maximum retries we declare the
default:
break;
}
-
- /* We disable the selected network, if not then
- * wpa_supplicant will loop retrying */
- if (g_supplicant_interface_enable_selected_network(interface,
- FALSE) != 0)
- DBG("Could not disables selected network");
-
+
+#if defined TIZEN_EXT
+ int err;
+
+ err = g_supplicant_interface_remove_network(wifi->interface);
+ if (err < 0)
+ DBG("Failed to remove network(%d)", err);
+
+
+ /* Some of Wi-Fi networks are not comply Wi-Fi specification.
+ * Retry association until its retry count is expired */
+ if (handle_wifi_assoc_retry(network, wifi) == true) {
+ throw_wifi_scan(wifi->device, scan_callback);
+ wifi->scan_pending_network = wifi->network;
+ break;
+ }
+
+ if(wifi->disconnect_code > 0){
+ DBG("Set disconnect reason code(%d)", wifi->disconnect_code);
+ connman_network_set_disconnect_reason(network, wifi->disconnect_code);
+ }
+
+ /* To avoid unnecessary repeated association in wpa_supplicant,
+ * "RemoveNetwork" should be made when Wi-Fi is disconnected */
+ if (wps != true && wifi->network && wifi->disconnecting == false) {
+ wifi->disconnecting = true;
+ err = g_supplicant_interface_disconnect(wifi->interface,
+ disconnect_callback, wifi->network);
+ if (err < 0)
+ wifi->disconnecting = false;
+
+ connman_network_set_connected(network, false);
+ connman_network_set_associating(network, false);
+
+ start_autoscan(device);
+
+ break;
+ }
+#endif
+
connman_network_set_connected(network, false);
connman_network_set_associating(network, false);
wifi->disconnecting = false;
break;
case G_SUPPLICANT_STATE_INACTIVE:
+#if defined TIZEN_EXT
+ if (handle_wps_completion(interface, network, device, wifi) == false)
+ break;
+#endif
connman_network_set_associating(network, false);
start_autoscan(device);
break;
}
+ old_connected = wifi->connected;
wifi->state = state;
/* Saving wpa_s state policy:
* --> We are not connected
* */
switch (state) {
- #if defined TIZEN_EXT
- case G_SUPPLICANT_STATE_SCANNING:
- break;
- #endif
case G_SUPPLICANT_STATE_AUTHENTICATING:
case G_SUPPLICANT_STATE_ASSOCIATING:
case G_SUPPLICANT_STATE_ASSOCIATED:
if (wifi->connected)
connman_warn("Probably roaming right now!"
" Staying connected...");
- else
- wifi->connected = false;
+ break;
+ case G_SUPPLICANT_STATE_SCANNING:
+ wifi->connected = false;
+
+ if (old_connected)
+ start_autoscan(device);
break;
case G_SUPPLICANT_STATE_COMPLETED:
wifi->connected = true;
static void set_device_type(const char *type, char dev_type[17])
{
const char *oui = "0050F204";
- const char *category = "0100";
+ const char *category = "0001";
const char *sub_category = "0000";
if (!g_strcmp0(type, "handset")) {
- category = "0A00";
- sub_category = "0500";
+ category = "000A";
+ sub_category = "0005";
} else if (!g_strcmp0(type, "vm") || !g_strcmp0(type, "container"))
- sub_category = "0100";
+ sub_category = "0001";
else if (!g_strcmp0(type, "server"))
- sub_category = "0200";
+ sub_category = "0002";
else if (!g_strcmp0(type, "laptop"))
- sub_category = "0500";
+ sub_category = "0005";
else if (!g_strcmp0(type, "desktop"))
- sub_category = "0600";
+ sub_category = "0006";
else if (!g_strcmp0(type, "tablet"))
- sub_category = "0900";
+ sub_category = "0009";
else if (!g_strcmp0(type, "watch"))
- category = "FF00";
+ category = "00FF";
snprintf(dev_type, 17, "%s%s%s", category, oui, sub_category);
}
DBG("");
+ if (!interface)
+ return;
+
if (!g_supplicant_interface_has_p2p(interface))
return;
static void scan_finished(GSupplicantInterface *interface)
{
+#if defined TIZEN_EXT
+ struct wifi_data *wifi;
+ bool is_associating = false;
+ static bool is_scanning = true;
+#endif
+
DBG("");
+
+#if defined TIZEN_EXT
+ wifi = g_supplicant_interface_get_data(interface);
+ if (wifi && wifi->scan_pending_network) {
+ network_connect(wifi->scan_pending_network);
+ wifi->scan_pending_network = NULL;
+ }
+
+ //service state - associating
+ if(!wifi || !wifi->network)
+ return;
+
+ is_associating = connman_network_get_associating(wifi->network);
+ if(is_associating && is_scanning){
+ is_scanning = false;
+ DBG("send scan for connecting");
+ throw_wifi_scan(wifi->device, scan_callback);
+
+ return;
+ }
+ is_scanning = true;
+
+ //go scan
+
+#endif
}
+ static void ap_create_fail(GSupplicantInterface *interface)
+ {
+ struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+ int ret;
+
+ if ((wifi->tethering) && (wifi->tethering_param)) {
+ DBG("%s create AP fail \n",
+ g_supplicant_interface_get_ifname(wifi->interface));
+
+ connman_inet_remove_from_bridge(wifi->index, wifi->bridge);
+ wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
+ wifi->tethering = false;
+
+ ret = tech_set_tethering(wifi->tethering_param->technology,
+ wifi->tethering_param->ssid->ssid,
+ wifi->tethering_param->ssid->passphrase,
+ wifi->bridge, true);
+
+ if ((ret == -EOPNOTSUPP) && (wifi_technology)) {
+ connman_technology_tethering_notify(wifi_technology,false);
+ }
+
+ g_free(wifi->tethering_param->ssid);
+ g_free(wifi->tethering_param);
+ wifi->tethering_param = NULL;
+ }
+
+ return;
+ }
+
static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
{
unsigned char strength;
strength = 120 + g_supplicant_network_get_signal(supplicant_network);
+
+#if !defined TIZEN_EXT
if (strength > 100)
strength = 100;
-
+#endif
return strength;
}
bool wps_ready;
bool wps_advertizing;
- GSList *vsie_list = NULL;
+#if defined TIZEN_EXT
++ const char *wifi_vsie;
++ unsigned int wifi_vsie_len;
+#endif
+
mode = g_supplicant_network_get_mode(supplicant_network);
identifier = g_supplicant_network_get_identifier(supplicant_network);
ssid = g_supplicant_network_get_ssid(supplicant_network, &ssid_len);
++#if defined TIZEN_EXT
++ wifi_vsie = g_supplicant_network_get_wifi_vsie(supplicant_network, &wifi_vsie_len);
++#endif
network = connman_device_get_network(wifi->device, identifier);
if (!network) {
connman_network_set_blob(network, "WiFi.SSID",
ssid, ssid_len);
- vsie_list = (GSList *)g_supplicant_network_get_wifi_vsie(supplicant_network);
- if (vsie_list)
- connman_network_set_vsie_list(network, vsie_list);
- else
- DBG("vsie_list is NULL");
+#if defined TIZEN_EXT
++ if(wifi_vsie_len > 0 && wifi_vsie)
++ connman_network_set_blob(network, "WiFi.Vsie",
++ wifi_vsie, wifi_vsie_len);
+#endif
connman_network_set_string(network, "WiFi.Security", security);
connman_network_set_strength(network,
calculate_strength(supplicant_network));
/* Is AP advertizing for WPS association?
* If so, we decide to use WPS by default */
if (wps_ready && wps_pbc &&
- wps_advertizing)
+ wps_advertizing) {
+#if !defined TIZEN_EXT
connman_network_set_bool(network, "WiFi.UseWPS", true);
+#else
+ DBG("wps is activating by ap but ignore it.");
+#endif
+ }
}
connman_network_set_frequency(network,
g_supplicant_network_get_frequency(supplicant_network));
-
+#if defined TIZEN_EXT
+ connman_network_set_bssid(network,
+ g_supplicant_network_get_bssid(supplicant_network));
+ connman_network_set_maxrate(network,
+ g_supplicant_network_get_maxrate(supplicant_network));
+ connman_network_set_enc_mode(network,
+ g_supplicant_network_get_enc_mode(supplicant_network));
+ connman_network_set_rsn_mode(network,
+ g_supplicant_network_get_rsn_mode(supplicant_network));
+ connman_network_set_keymgmt(network,
+ g_supplicant_network_get_keymgmt(supplicant_network));
+ connman_network_set_bool(network, "WiFi.HS20AP",
+ g_supplicant_network_is_hs20AP(supplicant_network));
+#endif
connman_network_set_available(network, true);
connman_network_set_string(network, "WiFi.Mode", mode);
+#if defined TIZEN_EXT
+ if (group)
+#else
if (ssid)
+#endif
connman_network_set_group(network, group);
+#if defined TIZEN_EXT
+ if (wifi_first_scan == true)
+ found_with_first_scan = true;
+#endif
+
if (wifi->hidden && ssid) {
+#if defined TIZEN_EXT
+ if (network_security(wifi->hidden->security) ==
+ network_security(security) &&
+#else
if (!g_strcmp0(wifi->hidden->security, security) &&
+#endif
wifi->hidden->ssid_len == ssid_len &&
!memcmp(wifi->hidden->ssid, ssid, ssid_len)) {
connman_network_connect_hidden(network,
if (!connman_network)
return;
+#if defined TIZEN_EXT
+ if (connman_network == wifi->scan_pending_network)
+ wifi->scan_pending_network = NULL;
+
+ if (connman_network == wifi->pending_network)
+ wifi->pending_network = NULL;
+
+ if(connman_network_get_connecting(connman_network) == true){
+ connman_network_set_connected(connman_network, false);
+ }
+#endif
+
wifi->networks = g_slist_remove(wifi->networks, connman_network);
connman_device_remove_network(wifi->device, connman_network);
const char *name, *identifier;
struct connman_network *connman_network;
+#if defined TIZEN_EXT
+ const unsigned char *bssid;
+ unsigned int maxrate;
+ uint16_t frequency;
+ bool wps;
+#endif
+
interface = g_supplicant_network_get_interface(network);
wifi = g_supplicant_interface_get_data(interface);
identifier = g_supplicant_network_get_identifier(network);
calculate_strength(network));
connman_network_update(connman_network);
}
+
+#if defined TIZEN_EXT
+ bssid = g_supplicant_network_get_bssid(network);
+ maxrate = g_supplicant_network_get_maxrate(network);
+ frequency = g_supplicant_network_get_frequency(network);
+ wps = g_supplicant_network_get_wps(network);
+
+ connman_network_set_bssid(connman_network, bssid);
+ connman_network_set_maxrate(connman_network, maxrate);
+ connman_network_set_frequency(connman_network, frequency);
+ connman_network_set_bool(connman_network, "WiFi.WPS", wps);
+#endif
}
+ static void network_associated(GSupplicantNetwork *network)
+ {
+ GSupplicantInterface *interface;
+ struct wifi_data *wifi;
+ struct connman_network *connman_network;
+ const char *identifier;
+
+ DBG("");
+
+ interface = g_supplicant_network_get_interface(network);
+ if (!interface)
+ return;
+
+ wifi = g_supplicant_interface_get_data(interface);
+ if (!wifi)
+ return;
+
+ identifier = g_supplicant_network_get_identifier(network);
+
+ connman_network = connman_device_get_network(wifi->device, identifier);
+ if (!connman_network)
+ return;
+
+ if (wifi->network) {
+ if (wifi->network == connman_network)
+ return;
+
+ /*
+ * This should never happen, we got associated with
+ * a network different than the one we were expecting.
+ */
+ DBG("Associated to %p while expecting %p",
+ connman_network, wifi->network);
+
+ connman_network_set_associating(wifi->network, false);
+ }
+
+ DBG("Reconnecting to previous network %p from wpa_s", connman_network);
+
+ wifi->network = connman_network_ref(connman_network);
+ wifi->retries = 0;
+
+ /*
+ * Interface state changes callback (interface_state) is always
+ * called before network_associated callback thus we need to call
+ * interface_state again in order to process the new state now that
+ * we have the network properly set.
+ */
+ interface_state(interface);
+ }
+
static void apply_peer_services(GSupplicantPeer *peer,
struct connman_peer *connman_peer)
{
}
}
+static void add_station(const char *mac)
+{
+ connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_WIFI,
+ mac);
+}
+
+static void remove_station(const char *mac)
+{
+ connman_technology_tethering_remove_station(mac);
+}
+
static void peer_found(GSupplicantPeer *peer)
{
GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
struct connman_peer *connman_peer;
const char *identifier, *name;
int ret;
-
+#if defined TIZEN_EXT
+ if (!wifi)
+ return;
+#endif
identifier = g_supplicant_peer_get_identifier(peer);
name = g_supplicant_peer_get_name(peer);
ret = connman_peer_register(connman_peer);
if (ret < 0 && ret != -EALREADY)
connman_peer_unref(connman_peer);
+ else
+ wifi->peers = g_slist_prepend(wifi->peers, connman_peer);
}
static void peer_lost(GSupplicantPeer *peer)
connman_peer_unregister(connman_peer);
connman_peer_unref(connman_peer);
}
+
+ wifi->peers = g_slist_remove(wifi->peers, connman_peer);
}
static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state)
struct connman_peer *connman_peer;
const char *identifier;
+#if defined TIZEN_EXT
+ if (!wifi)
+ return;
+#endif
+
identifier = g_supplicant_peer_get_identifier(peer);
DBG("ident: %s", identifier);
+ if (!wifi)
+ return;
+
connman_peer = connman_peer_get(wifi->device, identifier);
if (!connman_peer)
return;
connman_peer_set_as_master(connman_peer,
!g_supplicant_peer_is_client(peer));
connman_peer_set_sub_device(connman_peer, g_wifi->device);
+
+ /*
+ * If wpa_supplicant didn't create a dedicated p2p-group
+ * interface then mark this interface as p2p_device to avoid
+ * scan and auto-scan are launched on it while P2P is connected.
+ */
+ if (!g_list_find(p2p_iface_list, g_wifi))
+ wifi->p2p_device = true;
}
connman_peer_set_state(connman_peer, p_state);
struct connman_peer *connman_peer;
const char *identifier;
+#if defined TIZEN_EXT
+ if (!wifi)
+ return;
+#endif
+
identifier = g_supplicant_peer_get_identifier(peer);
DBG("ident: %s", identifier);
connman_peer_request_connection(connman_peer);
}
+#if defined TIZEN_EXT
+static void system_power_off(void)
+{
+ GList *list;
+ struct wifi_data *wifi;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
+
+ if (connman_setting_get_bool("WiFiDHCPRelease") == true) {
+ for (list = iface_list; list; list = list->next) {
+ wifi = list->data;
+
+ if (wifi->network != NULL) {
+ service = connman_service_lookup_from_network(wifi->network);
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ __connman_dhcp_stop(ipconfig_ipv4);
+ }
+ }
+ }
+}
+
+static void network_merged(GSupplicantNetwork *network)
+{
+ GSupplicantInterface *interface;
+ GSupplicantState state;
+ struct wifi_data *wifi;
+ const char *identifier;
+ struct connman_network *connman_network;
+ bool ishs20AP = 0;
+ char *temp = NULL;
+
+ interface = g_supplicant_network_get_interface(network);
+ if (!interface)
+ return;
+
+ state = g_supplicant_interface_get_state(interface);
+ if (state < G_SUPPLICANT_STATE_AUTHENTICATING)
+ return;
+
+ wifi = g_supplicant_interface_get_data(interface);
+ if (!wifi)
+ return;
+
+ identifier = g_supplicant_network_get_identifier(network);
+
+ connman_network = connman_device_get_network(wifi->device, identifier);
+ if (!connman_network)
+ return;
+
+ DBG("merged identifier %s", identifier);
+
+ if (wifi->connected == FALSE) {
+ switch (state) {
+ case G_SUPPLICANT_STATE_AUTHENTICATING:
+ case G_SUPPLICANT_STATE_ASSOCIATING:
+ case G_SUPPLICANT_STATE_ASSOCIATED:
+ case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
+ case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
+ connman_network_set_associating(connman_network, TRUE);
+ break;
+ case G_SUPPLICANT_STATE_COMPLETED:
+ connman_network_set_connected(connman_network, TRUE);
+ break;
+ default:
+ DBG("Not handled the state : %d", state);
+ break;
+ }
+ }
+
+ ishs20AP = g_supplicant_network_is_hs20AP(network);
+
+ if (ishs20AP &&
+ g_strcmp0(g_supplicant_network_get_security(network), "ieee8021x") == 0) {
+ temp = g_ascii_strdown(g_supplicant_network_get_eap(network), -1);
+ connman_network_set_string(connman_network, "WiFi.EAP",
+ temp);
+ connman_network_set_string(connman_network, "WiFi.Identity",
+ g_supplicant_network_get_identity(network));
+ connman_network_set_string(connman_network, "WiFi.Phase2",
+ g_supplicant_network_get_phase2(network));
+
+ g_free(temp);
+ }
+
+ wifi->network = connman_network;
+}
+
+static void assoc_failed(void *user_data)
+{
+ struct connman_network *network = user_data;
+ connman_network_set_associating(network, false);
+}
+#endif
+
static void debug(const char *str)
{
if (getenv("CONNMAN_SUPPLICANT_DEBUG"))
int reasoncode)
{
struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
if (wifi != NULL) {
wifi->disconnect_code = reasoncode;
}
{
struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
- #if defined TIZEN_EXT
- struct connman_network *network;
- #endif
-
if (wifi != NULL) {
wifi->assoc_code = status_code;
-
- #if defined TIZEN_EXT
- network = wifi->network;
- connman_network_set_assoc_status_code(network,status_code);
- #endif
-
}
}
.p2p_support = p2p_support,
.scan_started = scan_started,
.scan_finished = scan_finished,
+ .ap_create_fail = ap_create_fail,
.network_added = network_added,
.network_removed = network_removed,
.network_changed = network_changed,
+ .network_associated = network_associated,
+ .add_station = add_station,
+ .remove_station = remove_station,
.peer_found = peer_found,
.peer_lost = peer_lost,
.peer_changed = peer_changed,
.peer_request = peer_request,
- .network_merged = network_merged,
+#if defined TIZEN_EXT
+ .system_power_off = system_power_off,
++ .network_merged = network_merged,
+ .assoc_failed = assoc_failed,
+#endif
+ .debug = debug,
.disconnect_reasoncode = disconnect_reasoncode,
.assoc_status_code = assoc_status_code,
- .debug = debug,
};
wifi_technology = NULL;
}
- struct wifi_tethering_info {
- struct wifi_data *wifi;
- struct connman_technology *technology;
- char *ifname;
- GSupplicantSSID *ssid;
- };
-
-static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
+static GSupplicantSSID *ssid_ap_init(const char *ssid,
- const char *passphrase, bool hidden)
++ const char *passphrase)
{
GSupplicantSSID *ap;
ap->passphrase = passphrase;
}
- if (hidden)
- ap->ignore_broadcast_ssid =
- G_SUPPLICANT_AP_HIDDEN_SSID_ZERO_CONTENTS;
- else
- ap->ignore_broadcast_ssid = G_SUPPLICANT_AP_NO_SSID_HIDING;
-
return ap;
}
DBG("result %d index %d bridge %s",
result, info->wifi->index, info->wifi->bridge);
- if (result < 0) {
+ if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
connman_inet_remove_from_bridge(info->wifi->index,
info->wifi->bridge);
- connman_technology_tethering_notify(info->technology, false);
+
+ if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+ connman_technology_tethering_notify(info->technology, false);
+ g_free(info->wifi->tethering_param->ssid);
+ g_free(info->wifi->tethering_param);
+ info->wifi->tethering_param = NULL;
+ }
}
g_free(info->ifname);
DBG("result %d ifname %s", result,
g_supplicant_interface_get_ifname(interface));
- if (result < 0) {
+ if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
connman_inet_remove_from_bridge(info->wifi->index,
info->wifi->bridge);
- connman_technology_tethering_notify(info->technology, false);
+
+ if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+ connman_technology_tethering_notify(info->technology, false);
+ g_free(info->wifi->tethering_param->ssid);
+ g_free(info->wifi->tethering_param);
+ info->wifi->tethering_param = NULL;
+
+ }
g_free(info->ifname);
g_free(info->ssid);
DBG("ifname %s result %d ", info->ifname, result);
- if (result < 0) {
- info->wifi->tethering = true;
- if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
++ if (result < 0 || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
+ info->wifi->tethering = false;
+ connman_technology_tethering_notify(info->technology, false);
g_free(info->ifname);
g_free(info->ssid);
g_free(info);
+
+ if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+ g_free(info->wifi->tethering_param->ssid);
+ g_free(info->wifi->tethering_param);
+ info->wifi->tethering_param = NULL;
+ }
return;
}
info->wifi->interface = NULL;
- connman_technology_tethering_notify(info->technology, true);
-
g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge,
ap_create_callback,
info);
}
- static int tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
- const char *bridge, bool enabled, bool hidden)
+ static int enable_wifi_tethering(struct connman_technology *technology,
+ const char *bridge, const char *identifier,
+ const char *passphrase, bool available)
{
GList *list;
GSupplicantInterface *interface;
struct wifi_tethering_info *info;
const char *ifname;
unsigned int mode;
- int err;
-
- DBG("");
-
- if (!enabled) {
- for (list = iface_list; list; list = list->next) {
- wifi = list->data;
-
- if (wifi->tethering) {
- wifi->tethering = false;
-
- connman_inet_remove_from_bridge(wifi->index,
- bridge);
- wifi->bridged = false;
- }
- }
-
- connman_technology_tethering_notify(technology, false);
-
- return 0;
- }
+ int err, berr = 0;
for (list = iface_list; list; list = list->next) {
wifi = list->data;
+ DBG("wifi %p network %p pending_network %p", wifi,
+ wifi->network, wifi->pending_network);
+
interface = wifi->interface;
if (!interface)
continue;
- ifname = g_supplicant_interface_get_ifname(wifi->interface);
- if (!ifname)
++ if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED)
+ continue;
+
+ ifname = g_supplicant_interface_get_ifname(wifi->interface);
+
+ if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED) {
+ DBG("%s does not support AP mode (detected)", ifname);
+ continue;
+ }
+
mode = g_supplicant_interface_get_mode(interface);
if ((mode & G_SUPPLICANT_CAPABILITY_MODE_AP) == 0) {
- DBG("%s does not support AP mode", ifname);
+ wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
+ DBG("%s does not support AP mode (capability)", ifname);
continue;
}
+ if (wifi->network && available)
+ continue;
+
info = g_try_malloc0(sizeof(struct wifi_tethering_info));
if (!info)
return -ENOMEM;
+ wifi->tethering_param = g_try_malloc0(sizeof(struct wifi_tethering_info));
+ if (!wifi->tethering_param) {
+ g_free(info);
+ return -ENOMEM;
+ }
+
info->wifi = wifi;
info->technology = technology;
info->wifi->bridge = bridge;
- info->ssid = ssid_ap_init(identifier, passphrase, hidden);
- if (!info->ssid) {
- g_free(info);
- continue;
- }
+ info->ssid = ssid_ap_init(identifier, passphrase);
+ if (!info->ssid)
+ goto failed;
+
info->ifname = g_strdup(ifname);
- if (!info->ifname) {
- g_free(info->ssid);
- g_free(info);
- continue;
- }
++ if (!info->ifname)
++ goto failed;
+
+ wifi->tethering_param->technology = technology;
+ wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);
+ if (!wifi->tethering_param->ssid)
+ goto failed;
info->wifi->tethering = true;
+ info->wifi->ap_supported = WIFI_AP_SUPPORTED;
+
+ berr = connman_technology_tethering_notify(technology, true);
+ if (berr < 0)
+ goto failed;
err = g_supplicant_interface_remove(interface,
sta_remove_callback,
info);
- if (err == 0)
- return err;
+ if (err >= 0) {
+ DBG("tethering wifi %p ifname %s", wifi, ifname);
+ return 0;
+ }
+
+ failed:
+ g_free(info->ifname);
+ g_free(info->ssid);
+ g_free(info);
+ g_free(wifi->tethering_param);
+ wifi->tethering_param = NULL;
+
+ /*
+ * Remove bridge if it was correctly created but remove
+ * operation failed. Instead, if bridge creation failed then
+ * break out and do not try again on another interface,
+ * bridge set-up does not depend on it.
+ */
+ if (berr == 0)
+ connman_technology_tethering_notify(technology, false);
+ else
+ break;
}
return -EOPNOTSUPP;
}
+ static int tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
+ const char *bridge, bool enabled)
+ {
+ GList *list;
+ struct wifi_data *wifi;
+ int err;
+
+ DBG("");
+
+ if (!enabled) {
+ for (list = iface_list; list; list = list->next) {
+ wifi = list->data;
+
+ if (wifi->tethering) {
+ wifi->tethering = false;
+
+ connman_inet_remove_from_bridge(wifi->index,
+ bridge);
+ wifi->bridged = false;
+ }
+ }
+
+ connman_technology_tethering_notify(technology, false);
+
+ return 0;
+ }
+
+ DBG("trying tethering for available devices");
+ err = enable_wifi_tethering(technology, bridge, identifier, passphrase,
+ true);
+
+ if (err < 0) {
+ DBG("trying tethering for any device");
+ err = enable_wifi_tethering(technology, bridge, identifier,
+ passphrase, false);
+ }
+
+ return err;
+ }
+
static void regdom_callback(int result, const char *alpha2, void *user_data)
{
DBG("");
#!/bin/sh
-DAEMON=@sbindir@/connmand
+DAEMON=@bindir@/connmand
DESC="Connection Manager"
. /lib/lsb/init-functions
. @sysconfdir@/default/connman
fi
+ if [ "CONNMAN_RUNSTATEDIR_RESOLVCONF" != "no" ] ; then
+ mkdir -p @runstatedir@/connman
+ ln -sf @runstatedir@/connman/resolv.conf /etc/
+ fi
+
set -e
do_start() {
{
struct ip_tunnel_parm p;
struct ifreq ifr;
- int fd = -1;
+ int fd;
int ret;
/* ip tunnel add tun6to4 mode sit remote any local 1.2.3.4 ttl 64 */
DBusMessageIter entry, value;
dbus_message_iter_recurse(&dict, &entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
dbus_message_iter_get_basic(&entry, &key);
if (g_str_equal(key, "Identity")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &identity);
} else if (g_str_equal(key, "Passphrase")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &passphrase);
} else if (g_str_equal(key, "WPS")) {
- wps = true;
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
+ wps = true;
dbus_message_iter_get_basic(&value, &wpspin);
break;
} else if (g_str_equal(key, "Name")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &name);
name_len = strlen(name);
} else if (g_str_equal(key, "SSID")) {
- #if defined TIZEN_EXT
- DBusMessageIter array;
- #endif
+ DBusMessageIter array_iter;
+
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
- break;
- #if defined TIZEN_EXT
- dbus_message_iter_recurse(&entry, &array);
- if (dbus_message_iter_get_arg_type(&array)
- != DBUS_TYPE_ARRAY)
- break;
- dbus_message_iter_recurse(&array, &value);
- if (dbus_message_iter_get_arg_type(&value)
- != DBUS_TYPE_BYTE)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
- #else
-
+ }
dbus_message_iter_recurse(&entry, &value);
if (dbus_message_iter_get_arg_type(&value)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_ARRAY) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
- if (dbus_message_iter_get_element_type(&value)
- != DBUS_TYPE_VARIANT)
+ }
+ dbus_message_iter_recurse(&value, &array_iter);
+ if (dbus_message_iter_get_arg_type(&array_iter)
+ != DBUS_TYPE_BYTE) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
- #endif
- dbus_message_iter_get_fixed_array(&value, &name,
+ }
+ dbus_message_iter_get_fixed_array(&array_iter, &name,
&name_len);
}
dbus_message_iter_next(&dict);
value = "wep";
break;
case CONNMAN_SERVICE_SECURITY_PSK:
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_SECURITY_RSN:
+#endif
value = "psk";
break;
case CONNMAN_SERVICE_SECURITY_8021X:
data.type = "wep";
break;
case CONNMAN_SERVICE_SECURITY_PSK:
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_SECURITY_RSN:
+#endif
data.type = "psk";
break;
/*
if (g_str_equal(key, "Username")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &username);
} else if (g_str_equal(key, "Password")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry) !=
- DBUS_TYPE_VARIANT)
+ DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &password);
}
DBusMessageIter entry, value;
dbus_message_iter_recurse(&dict, &entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
dbus_message_iter_get_basic(&entry, &key);
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
break;
+ }
+
dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &wpspin);
break;
}
struct connman_agent_request *request)
{
DBusMessage *message;
+ const char *interface = NULL;
- DBG("send cancel req to %s %s", agent->owner, agent->path);
+ if (request && request->driver)
+ interface = request->driver->interface;
+
+ DBG("send cancel req to %s %s iface %s", agent->owner, agent->path,
+ interface);
message = dbus_message_new_method_call(agent->owner,
agent->path,
- request->driver->interface,
+ interface,
"Cancel");
if (!message) {
connman_error("Couldn't allocate D-Bus message");
user_context) {
DBG("cancel pending %p", request);
+ agent->queue = g_list_delete_link(agent->queue,
+ list);
+
request->callback(NULL, request->user_data);
agent_request_free(request);
-
- agent->queue = g_list_delete_link(agent->queue,
- list);
}
list = next;
message = dbus_message_new_method_call(agent->owner, agent->path,
interface, "Release");
- if (message == NULL) {
+ if (!message) {
connman_error("Couldn't allocate D-Bus message");
return;
}
if (!f)
return -errno;
- fprintf(f, "%d", delay);
+ fprintf(f, "%u", delay);
fclose(f);
unsigned int ssid_len;
char *eap;
char *identity;
+ char *anonymous_identity;
char *ca_cert_file;
+ char *subject_match;
+ char *altsubject_match;
+ char *domain_suffix_match;
+ char *domain_match;
char *client_cert_file;
char *private_key_file;
char *private_key_passphrase;
#define SERVICE_KEY_PRV_KEY_PASS "PrivateKeyPassphrase"
#define SERVICE_KEY_PRV_KEY_PASS_TYPE "PrivateKeyPassphraseType"
#define SERVICE_KEY_IDENTITY "Identity"
+ #define SERVICE_KEY_ANONYMOUS_IDENTITY "AnonymousIdentity"
+ #define SERVICE_KEY_SUBJECT_MATCH "SubjectMatch"
+ #define SERVICE_KEY_ALT_SUBJECT_MATCH "AltSubjectMatch"
+ #define SERVICE_KEY_DOMAIN_SUFF_MATCH "DomainSuffixMatch"
+ #define SERVICE_KEY_DOMAIN_MATCH "DomainMatch"
#define SERVICE_KEY_PHASE2 "Phase2"
#define SERVICE_KEY_PASSPHRASE "Passphrase"
#define SERVICE_KEY_SECURITY "Security"
SERVICE_KEY_PRV_KEY_PASS,
SERVICE_KEY_PRV_KEY_PASS_TYPE,
SERVICE_KEY_IDENTITY,
+ SERVICE_KEY_ANONYMOUS_IDENTITY,
+ SERVICE_KEY_SUBJECT_MATCH,
+ SERVICE_KEY_ALT_SUBJECT_MATCH,
+ SERVICE_KEY_DOMAIN_SUFF_MATCH,
+ SERVICE_KEY_DOMAIN_MATCH,
SERVICE_KEY_PHASE2,
SERVICE_KEY_PASSPHRASE,
SERVICE_KEY_SECURITY,
g_free(config_service->ssid);
g_free(config_service->eap);
g_free(config_service->identity);
+ g_free(config_service->anonymous_identity);
g_free(config_service->ca_cert_file);
+ g_free(config_service->subject_match);
+ g_free(config_service->altsubject_match);
+ g_free(config_service->domain_suffix_match);
+ g_free(config_service->domain_match);
g_free(config_service->client_cert_file);
g_free(config_service->private_key_file);
g_free(config_service->private_key_passphrase);
service->identity = str;
}
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_ANONYMOUS_IDENTITY, NULL);
+ if (str) {
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_SUBJECT_MATCH, NULL);
+ if (str) {
+ g_free(service->subject_match);
+ service->subject_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_ALT_SUBJECT_MATCH, NULL);
+ if (str) {
+ g_free(service->altsubject_match);
+ service->altsubject_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_DOMAIN_SUFF_MATCH, NULL);
+ if (str) {
+ g_free(service->domain_suffix_match);
+ service->domain_suffix_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_DOMAIN_MATCH, NULL);
+ if (str) {
+ g_free(service->domain_match);
+ service->domain_match = str;
+ }
+
str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
if (str) {
g_free(service->phase2);
if (str) {
if (security == CONNMAN_SERVICE_SECURITY_PSK ||
+#if defined TIZEN_EXT
+ security == CONNMAN_SERVICE_SECURITY_RSN ||
+#endif
security == CONNMAN_SERVICE_SECURITY_WEP) {
service->security = security;
} else {
} else
service->security = CONNMAN_SERVICE_SECURITY_PSK;
- }
+ } else if (str) {
+
- if (security != CONNMAN_SERVICE_SECURITY_NONE)
++ if (security != CONNMAN_SERVICE_SECURITY_NONE) {
+ connman_info("Mismatch no security and "
+ "setting %s = %s",
+ SERVICE_KEY_SECURITY, str);
-
- service->security = CONNMAN_SERVICE_SECURITY_NONE;
++ }
++ service->security = CONNMAN_SERVICE_SECURITY_NONE;
+ } else
- service->security = CONNMAN_SERVICE_SECURITY_NONE;
++ service->security = CONNMAN_SERVICE_SECURITY_NONE;
+
+ g_free(str);
service->config_ident = g_strdup(config->ident);
service->config_entry = g_strdup_printf("service_%s", service->ident);
return;
}
- if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
+ if (event->mask & (IN_CREATE | IN_MOVED_TO))
create_config(ident);
- if (event->mask & IN_MODIFY) {
+ if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
struct connman_config *config;
config = g_hash_table_lookup(config_table, ident);
}
}
- if (event->mask & IN_DELETE)
+ if (event->mask & (IN_DELETE | IN_MOVED_FROM))
g_hash_table_remove(config_table, ident);
}
if (!str)
return NULL;
+ /* passphrases can have spaces in the end */
+ if (!g_strcmp0(key, SERVICE_KEY_PASSPHRASE) ||
+ !g_strcmp0(key, SERVICE_KEY_PRV_KEY_PASS))
+ return str;
+
return g_strchomp(str);
}
__connman_service_set_string(service, "Identity",
config->identity);
+ if (config->anonymous_identity)
+ __connman_service_set_string(service, "AnonymousIdentity",
+ config->anonymous_identity);
+
if (config->ca_cert_file)
__connman_service_set_string(service, "CACertFile",
config->ca_cert_file);
+ if (config->subject_match)
+ __connman_service_set_string(service, "SubjectMatch",
+ config->subject_match);
+
+ if (config->altsubject_match)
+ __connman_service_set_string(service, "AltSubjectMatch",
+ config->altsubject_match);
+
+ if (config->domain_suffix_match)
+ __connman_service_set_string(service, "DomainSuffixMatch",
+ config->domain_suffix_match);
+
+ if (config->domain_match)
+ __connman_service_set_string(service, "DomainMatch",
+ config->domain_match);
+
if (config->client_cert_file)
__connman_service_set_string(service, "ClientCertFile",
config->client_cert_file);
if (config->phase2)
__connman_service_set_string(service, "Phase2", config->phase2);
+#if defined TIZEN_EXT
+ else
+ __connman_service_set_string(service, "Phase2", NULL);
+#endif
if (config->passphrase)
__connman_service_set_string(service, "Passphrase",
return FALSE;
}
+#if defined TIZEN_EXT
+static bool __check_address_type(int address_family, const char *address)
+{
+ unsigned char buf[sizeof(struct in6_addr)] = {0, };
+ int err = 0;
+
+ err = inet_pton(address_family, address, buf);
+ if(err > 0)
+ return TRUE;
+
+ return FALSE;
+}
+#endif
+
static int try_provision_service(struct connman_config_service *config,
struct connman_service *service)
{
enum connman_service_type type;
const void *ssid;
unsigned int ssid_len;
- const char *str;
network = __connman_service_get_network(service);
if (!network) {
if (memcmp(config->ssid, ssid, ssid_len))
return -ENOENT;
- str = connman_network_get_string(network, "WiFi.Security");
- if (config->security != __connman_service_string2security(str))
- return -ENOENT;
-
break;
case CONNMAN_SERVICE_TYPE_ETHERNET:
__connman_service_nameserver_clear(service);
for (i = 0; config->nameservers[i]; i++) {
+#if defined TIZEN_EXT
+ if (__check_address_type(AF_INET, config->nameservers[i]))
+ __connman_service_nameserver_append(service,
+ config->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ else if (__check_address_type(AF_INET6, config->nameservers[i]))
+ __connman_service_nameserver_append(service,
+ config->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
__connman_service_nameserver_append(service,
config->nameservers[i], false);
+#endif
}
}
virtual->service = service;
virtual->vfile = config->virtual_file;
- g_timeout_add(0, remove_virtual_config, virtual);
+ g_idle_add(remove_virtual_config, virtual);
return 0;
}
return 0;
}
+ static int
+ find_and_provision_service_from_config(struct connman_service *service,
+ struct connman_config *config)
+ {
+ GHashTableIter iter;
+ gpointer value, key;
+
+ g_hash_table_iter_init(&iter, config->service_table);
+ while (g_hash_table_iter_next(&iter, &key,
+ &value)) {
+ if (!try_provision_service(value, service))
+ return 0;
+ }
+
+ return -ENOENT;
+ }
+
static int find_and_provision_service(struct connman_service *service)
{
- GHashTableIter iter, iter_service;
- gpointer value, key, value_service, key_service;
+ GHashTableIter iter;
+ gpointer value, key;
g_hash_table_iter_init(&iter, config_table);
while (g_hash_table_iter_next(&iter, &key, &value)) {
struct connman_config *config = value;
- g_hash_table_iter_init(&iter_service, config->service_table);
- while (g_hash_table_iter_next(&iter_service, &key_service,
- &value_service)) {
- if (!try_provision_service(value_service, service))
- return 0;
- }
+ if (!find_and_provision_service_from_config(service, config))
+ return 0;
}
return -ENOENT;
type != CONNMAN_SERVICE_TYPE_GADGET)
return -ENOSYS;
+#if defined TIZEN_EXT
+ if(type == CONNMAN_SERVICE_TYPE_WIFI &&
+ __connman_service_get_security(service) ==
+ CONNMAN_SERVICE_SECURITY_NONE)
+ return -ENOSYS;
+#endif
+
return find_and_provision_service(service);
}
}
}
- find_and_provision_service(service);
+ find_and_provision_service_from_config(service, config);
}
return ret;
{
struct connman_config_service *service_config;
struct connman_config *config;
- char *vfile, *group;
+ char *vfile, *group = NULL;
char rstr[11];
DBG("");
if (g_strcmp0(service_config->type, "wifi") == 0)
__connman_device_request_scan(CONNMAN_SERVICE_TYPE_WIFI);
+ g_free(group);
return 0;
error:
DBG("Could not proceed");
g_hash_table_remove(config_table, vfile);
g_free(vfile);
-
+ g_free(group);
return -EINVAL;
}
g_hash_table_iter_init(&iter_file, config_table);
while (g_hash_table_iter_next(&iter_file, &key, &value)) {
struct connman_config *config_file = value;
+ struct connman_config_entry **tmp_entries = entries;
count = g_hash_table_size(config_file->service_table);
entries = g_try_realloc(entries, (i + count + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
g_hash_table_iter_init(&iter_config,
config_file->service_table);
}
if (entries) {
+ struct connman_config_entry **tmp_entries = entries;
+
entries = g_try_realloc(entries, (i + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
entries[i] = NULL;
struct gateway_data {
int index;
struct connman_service *service;
- unsigned int order;
struct gateway_config *ipv4_gateway;
struct gateway_config *ipv6_gateway;
bool default_checked;
data->service = service;
- data->order = __connman_service_get_order(service);
-
/*
* If the service is already in the hash, then we
* must not replace it blindly but disable the gateway
static struct gateway_data *find_default_gateway(void)
{
- struct gateway_data *found = NULL;
- unsigned int order = 0;
- GHashTableIter iter;
- gpointer value, key;
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct gateway_data *data = value;
-
- if (!found || data->order > order) {
- found = data;
- order = data->order;
+ struct connman_service *service;
- DBG("default %p order %d", found, order);
- }
- }
+ service = __connman_service_get_default();
+ if (!service)
+ return NULL;
- return found;
+ return g_hash_table_lookup(gateway_hash, service);
}
static bool choose_default_gateway(struct gateway_data *data,
* this one as default. If the other one is already active
* we mark this one as non default.
*/
- if (data->ipv4_gateway) {
- if (candidate->ipv4_gateway &&
- !candidate->ipv4_gateway->active) {
+ if (data->ipv4_gateway && candidate->ipv4_gateway) {
+
+ if (!candidate->ipv4_gateway->active) {
DBG("ipv4 downgrading %p", candidate);
unset_default_gateway(candidate,
CONNMAN_IPCONFIG_TYPE_IPV4);
}
- if (candidate->ipv4_gateway &&
- candidate->ipv4_gateway->active &&
- candidate->order > data->order) {
+
+ if (candidate->ipv4_gateway->active &&
+ __connman_service_compare(candidate->service,
+ data->service) < 0) {
DBG("ipv4 downgrading this %p", data);
- unset_default_gateway(data,
- CONNMAN_IPCONFIG_TYPE_IPV4);
+ unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
downgraded = true;
}
}
- if (data->ipv6_gateway) {
- if (candidate->ipv6_gateway &&
- !candidate->ipv6_gateway->active) {
+ if (data->ipv6_gateway && candidate->ipv6_gateway) {
+ if (!candidate->ipv6_gateway->active) {
DBG("ipv6 downgrading %p", candidate);
unset_default_gateway(candidate,
CONNMAN_IPCONFIG_TYPE_IPV6);
}
- if (candidate->ipv6_gateway &&
- candidate->ipv6_gateway->active &&
- candidate->order > data->order) {
+ if (candidate->ipv6_gateway->active &&
+ __connman_service_compare(candidate->service,
+ data->service) < 0) {
DBG("ipv6 downgrading this %p", data);
- unset_default_gateway(data,
- CONNMAN_IPCONFIG_TYPE_IPV6);
+ unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
downgraded = true;
}
}
}
if (!found) {
+#if defined TIZEN_EXT
+ if (data->ipv4_gateway != NULL){
+ set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
+ connman_check_proxy_setup_and_wispr_start(data->service);
+ }
+#else
if (data->ipv4_gateway)
set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
+#endif
if (data->ipv6_gateway)
set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
return NULL;
}
- static void update_order(void)
- {
- GHashTableIter iter;
- gpointer value, key;
-
- DBG("");
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct gateway_data *data = value;
-
- data->order = __connman_service_get_order(data->service);
- }
- }
-
- void __connman_connection_gateway_activate(struct connman_service *service,
- enum connman_ipconfig_type type)
- {
- struct gateway_data *data = NULL;
-
- data = g_hash_table_lookup(gateway_hash, service);
- if (!data)
- return;
-
- DBG("gateway %p/%p type %d", data->ipv4_gateway,
- data->ipv6_gateway, type);
-
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- data->ipv4_gateway->active = true;
- else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- data->ipv6_gateway->active = true;
- }
-
static void add_host_route(int family, int index, const char *gateway,
enum connman_service_type service_type)
{
}
}
+#if defined TIZEN_EXT
+static bool __connman_service_is_not_cellular_internet_profile(
+ struct connman_service *cellular)
+{
+ char *suffix;
+ const char *path;
+ const char internet_suffix[] = "_1";
+ const char prepaid_internet_suffix[] = "_3";
+
+ if (connman_service_get_type(cellular) != CONNMAN_SERVICE_TYPE_CELLULAR)
+ return FALSE;
+
+ path = __connman_service_get_path(cellular);
+
+ suffix = strrchr(path, '_');
+
+ if (g_strcmp0(suffix, internet_suffix) != 0 &&
+ g_strcmp0(suffix, prepaid_internet_suffix) != 0) {
+ DBG("not internet service profile: %s", path);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
int __connman_connection_gateway_add(struct connman_service *service,
const char *gateway,
enum connman_ipconfig_type type,
if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV6)
gateway = "::";
+#if defined TIZEN_EXT
+ if (__connman_service_is_not_cellular_internet_profile(service) == TRUE) {
+ /* not internet service should not be default gateway */
+
+ DBG("no internet service %p index %d gateway %s vpn ip %s type %d",
+ service, index, gateway, peer, type);
+
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+ add_host_route(AF_INET, index, gateway, service_type);
+ __connman_service_nameserver_add_routes(service, gateway);
+ type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
+ }
+
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+ add_host_route(AF_INET6, index, gateway, service_type);
+ __connman_service_nameserver_add_routes(service, gateway);
+ type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
+ }
+
+ goto done;
+ }
+#endif
DBG("service %p index %d gateway %s vpn ip %s type %d",
service, index, gateway, peer, type);
}
if (!active_gateway) {
+#if defined TIZEN_EXT
+ if(new_gateway->ipv4_gateway)
+ DBG("ConnMan, Set default gateway[%s], active[%d]",
+ new_gateway->ipv4_gateway->gateway,
+ new_gateway->ipv4_gateway->active);
+#endif
set_default_gateway(new_gateway, type);
goto done;
}
bool updated = false;
GHashTableIter iter;
gpointer value, key;
+#if defined TIZEN_EXT
+ static struct gateway_data *old_default = NULL;
+#endif
if (!gateway_hash)
return updated;
- update_order();
-
default_gateway = find_default_gateway();
- __connman_service_update_ordering();
-
DBG("default %p", default_gateway);
/*
}
}
+#if defined TIZEN_EXT
+ if (updated == false && old_default != default_gateway) {
+ updated = true;
+ old_default = default_gateway;
+ }
+#endif
if (updated && default_gateway) {
if (default_gateway->ipv4_gateway)
set_default_gateway(default_gateway,
bool wps_requested,
const char *dbus_sender,
void *user_data);
-
#include <connman/log.h>
int __connman_log_init(const char *program, const char *debug,
void __connman_log_enable(struct connman_debug_desc *start,
struct connman_debug_desc *stop);
-#include <connman/backtrace.h>
-
#include <connman/option.h>
#include <connman/setting.h>
__connman_inet_rs_cb_t callback, void *user_data);
int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
GSList *prefixes, int router_lifetime);
+#if defined TIZEN_EXT
+void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data);
+#endif
typedef void (*__connman_inet_ns_cb_t) (struct nd_neighbor_advert *reply,
unsigned int length,
int __connman_inet_get_address_netmask(int ifindex,
struct sockaddr_in *address, struct sockaddr_in *netmask);
+ bool __connman_inet_isrootnfs_device(const char *devname);
+ char **__connman_inet_get_pnp_nameservers(const char *pnp_file);
+
#include <connman/resolver.h>
int __connman_resolver_init(gboolean dnsproxy);
void __connman_resolver_cleanup(void);
+ void __connman_resolver_append_fallback_nameservers(void);
int __connman_resolvfile_append(int index, const char *domain, const char *server);
int __connman_resolvfile_remove(int index, const char *domain, const char *server);
int __connman_resolver_redo_servers(int index);
void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const char *broadcast);
const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway);
+
+#if defined TIZEN_EXT
+void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig, int dhcp_lease_duration);
+#endif
+
unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigned char prefixlen);
int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig);
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ * e.g. same interface or same APN of cellular profile
+ */
+int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service);
+#else
int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig);
+#endif
void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
CONNMAN_DHCPV6_STATUS_RESTART = 2,
};
+#if defined TIZEN_EXT
+void set_dhcp_discover_timeout(int timeout_value);
+void set_dhcp_discover_retry_count(int retry_count);
+#endif
+
typedef void (* dhcpv6_cb) (struct connman_network *network,
enum __connman_dhcpv6_status status, gpointer data);
int __connman_connection_get_vpn_index(int phy_index);
bool __connman_connection_update_gateway(void);
- void __connman_connection_gateway_activate(struct connman_service *service,
- enum connman_ipconfig_type type);
int __connman_ntp_start(char *server);
void __connman_ntp_stop();
const char *ssid, unsigned int ssid_len,
const char *identity, const char *passphrase,
const char *security, void *user_data);
+#if defined TIZEN_EXT
+int __connman_device_request_specific_scan(enum connman_service_type type,
+ int scan_type, GSList *specific_scan_list);
+#endif
bool __connman_device_isfiltered(const char *devname);
void __connman_rfkill_cleanup(void);
int __connman_rfkill_block(enum connman_service_type type, bool block);
+#if defined TIZEN_EXT
+char *index2ident(int index, const char *prefix);
+char *index2addr(int index);
+#endif
+
#include <connman/network.h>
int __connman_network_init(void);
void __connman_tethering_cleanup(void);
const char *__connman_tethering_get_bridge(void);
- void __connman_tethering_set_enabled(void);
+ int __connman_tethering_set_enabled(void);
void __connman_tethering_set_disabled(void);
int __connman_private_network_request(DBusMessage *msg, const char *owner);
enum connman_provider_state state);
int __connman_provider_indicate_error(struct connman_provider *provider,
enum connman_provider_error error);
- int __connman_provider_connect(struct connman_provider *provider);
+ int __connman_provider_connect(struct connman_provider *provider,
+ const char *dbus_sender);
int __connman_provider_remove_by_path(const char *path);
void __connman_provider_cleanup(void);
int __connman_provider_init(void);
void __connman_service_list_struct(DBusMessageIter *iter);
+#if defined TIZEN_EXT
+int connman_service_get_ipv6_dns_method(struct connman_service *service);
+enum connman_dnsconfig_method {
+ CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0,
+ CONNMAN_DNSCONFIG_METHOD_MANUAL = 1,
+ CONNMAN_DNSCONFIG_METHOD_DHCP = 2,
+};
+#endif
+
+ int __connman_service_compare(const struct connman_service *a,
+ const struct connman_service *b);
+
struct connman_service *__connman_service_lookup_from_index(int index);
struct connman_service *__connman_service_lookup_from_ident(const char *identifier);
struct connman_service *__connman_service_create_from_network(struct connman_network *network);
struct connman_service *service);
struct connman_ipconfig *__connman_service_get_ipconfig(
struct connman_service *service, int family);
+ void __connman_service_notify_ipv4_configuration(
+ struct connman_service *service);
bool __connman_service_is_connected_state(struct connman_service *service,
enum connman_ipconfig_type type);
const char *__connman_service_get_ident(struct connman_service *service);
const char *__connman_service_get_name(struct connman_service *service);
unsigned int __connman_service_get_order(struct connman_service *service);
enum connman_service_state __connman_service_get_state(struct connman_service *service);
- void __connman_service_update_ordering(void);
struct connman_network *__connman_service_get_network(struct connman_service *service);
enum connman_service_security __connman_service_get_security(struct connman_service *service);
const char *__connman_service_get_phase2(struct connman_service *service);
bool __connman_service_wps_enabled(struct connman_service *service);
+#if defined TIZEN_EXT
+void __connman_service_set_storage_reload(struct connman_service *service,
+ bool storage_reload);
+#endif
int __connman_service_set_favorite(struct connman_service *service,
bool favorite);
int __connman_service_set_favorite_delayed(struct connman_service *service,
struct connman_service *service,
enum connman_ipconfig_type type);
+#if defined TIZEN_EXT
+void connman_check_proxy_setup_and_wispr_start(struct connman_service *service);
+#endif
+
int __connman_service_indicate_error(struct connman_service *service,
enum connman_service_error error);
int __connman_service_clear_error(struct connman_service *service);
int __connman_service_disconnect_all(void);
void __connman_service_set_active_session(bool enable, GSList *list);
void __connman_service_auto_connect(enum connman_service_connect_reason reason);
+
+#if defined TIZEN_EXT
+bool __connman_service_get_auto_connect_mode(void);
+void __connman_service_set_auto_connect_mode(bool enable);
+#endif
+
bool __connman_service_remove(struct connman_service *service);
bool __connman_service_is_provider_pending(struct connman_service *service);
void __connman_service_set_provider_pending(struct connman_service *service,
enum connman_service_type __connman_service_string2type(const char *str);
enum connman_service_security __connman_service_string2security(const char *str);
+#if defined TIZEN_EXT
+int __connman_service_nameserver_append(struct connman_service *service,
+ const char *nameserver, bool is_auto,
+ enum connman_ipconfig_type type);
+int __connman_service_nameserver_remove(struct connman_service *service,
+ const char *nameserver, bool is_auto,
+ enum connman_ipconfig_type type);
+#else
int __connman_service_nameserver_append(struct connman_service *service,
const char *nameserver, bool is_auto);
int __connman_service_nameserver_remove(struct connman_service *service,
const char *nameserver, bool is_auto);
+#endif
void __connman_service_nameserver_clear(struct connman_service *service);
void __connman_service_nameserver_add_routes(struct connman_service *service,
const char *gw);
GSList *ts_list);
void __connman_service_set_pac(struct connman_service *service,
const char *pac);
+#if defined TIZEN_EXT
+/*
+ * Returns profile count if there is any connected profiles
+ * that use same interface
+ */
+int __connman_service_get_connected_count_of_iface(struct connman_service *service);
+void __connman_service_set_proxy(struct connman_service *service,
+ const char *proxies);
+int check_passphrase_ext(struct connman_network *network,
+ const char *passphrase);
+#endif
bool __connman_service_is_hidden(struct connman_service *service);
bool __connman_service_is_split_routing(struct connman_service *service);
bool __connman_service_index_is_split_routing(int index);
void __connman_service_set_identity(struct connman_service *service,
const char *identity);
+ void __connman_service_set_anonymous_identity(struct connman_service *service,
+ const char *anonymous_identity);
+ void __connman_service_set_subject_match(struct connman_service *service,
+ const char *subject_match);
+ void __connman_service_set_altsubject_match(struct connman_service *service,
+ const char *altsubject_match);
+ void __connman_service_set_domain_suffix_match(struct connman_service *service,
+ const char *domain_suffix_match);
+ void __connman_service_set_domain_match(struct connman_service *service,
+ const char *domain_match);
void __connman_service_set_agent_identity(struct connman_service *service,
const char *agent_identity);
int __connman_service_set_passphrase(struct connman_service *service,
const char *passphrase);
const char *__connman_service_get_passphrase(struct connman_service *service);
+ int __connman_service_check_passphrase(enum connman_service_security security,
+ const char *passphrase);
int __connman_service_reset_ipconfig(struct connman_service *service,
enum connman_ipconfig_type type, DBusMessageIter *array,
enum connman_service_state *new_state);
unsigned int rx_error, unsigned int tx_error,
unsigned int rx_dropped, unsigned int tx_dropped);
+bool __connman_service_is_user_allowed(enum connman_service_type type,
+ uid_t uid);
+
int __connman_service_counter_register(const char *counter);
void __connman_service_counter_unregister(const char *counter);
void __connman_rtnl_start(void);
void __connman_rtnl_cleanup(void);
+#if defined TIZEN_EXT
+void __connman_wifi_vsie_list_struct(DBusMessageIter *iter);
+#endif
+
enum connman_device_type __connman_rtnl_get_device_type(int index);
unsigned int __connman_rtnl_update_interval_add(unsigned int interval);
unsigned int __connman_rtnl_update_interval_remove(unsigned int interval);
int __connman_rtnl_request_update(void);
int __connman_rtnl_send(const void *buf, size_t len);
++#if defined TIZEN_EXT
++void rtnl_nameserver_add_all(struct connman_service *service,
++ enum connman_ipconfig_type type);
++#endif
++
bool __connman_session_policy_autoconnect(enum connman_service_connect_reason reason);
int __connman_session_create(DBusMessage *msg);
struct firewall_context *__connman_firewall_create(void);
void __connman_firewall_destroy(struct firewall_context *ctx);
- int __connman_firewall_add_rule(struct firewall_context *ctx,
- const char *table,
- const char *chain,
- const char *rule_fmt, ...);
- int __connman_firewall_enable(struct firewall_context *ctx);
- int __connman_firewall_disable(struct firewall_context *ctx);
- bool __connman_firewall_is_up(void);
+ int __connman_firewall_enable_nat(struct firewall_context *ctx,
+ char *address, unsigned char prefixlen,
+ char *interface);
+ int __connman_firewall_disable_nat(struct firewall_context *ctx);
+ int __connman_firewall_enable_snat(struct firewall_context *ctx,
+ int index, const char *ifname,
+ const char *addr);
+ int __connman_firewall_disable_snat(struct firewall_context *ctx);
+ int __connman_firewall_enable_marking(struct firewall_context *ctx,
+ enum connman_session_id_type id_type,
+ char *id, const char *src_ip,
+ uint32_t mark);
+ int __connman_firewall_disable_marking(struct firewall_context *ctx);
int __connman_firewall_init(void);
void __connman_firewall_cleanup(void);
int __connman_util_get_random(uint64_t *val);
int __connman_util_init(void);
void __connman_util_cleanup(void);
+
+#ifdef TIZEN_EXT
+__attribute__ ((unused)) static int __tizentvextension = -1;
+#define TIZEN_TV_EXT (__builtin_expect(__tizentvextension != -1, 1) ? \
+ __tizentvextension : \
+ (__tizentvextension = connman_setting_get_bool("TizenTVExtension")))
+#else /* TIZEN_EXT */
+#define TIZEN_TV_EXT (0) /* Always False */
+#endif /* TIZEN_EXT */
*/
bool powered;
bool scanning;
- bool disconnected;
char *name;
char *node;
char *address;
clear_pending_trigger(device);
+ g_hash_table_destroy(device->networks);
+ device->networks = NULL;
+
g_free(device->ident);
g_free(device->node);
g_free(device->name);
g_free(device->last_network);
- g_hash_table_destroy(device->networks);
- device->networks = NULL;
-
g_free(device);
}
{
enum connman_service_type type;
- DBG("driver %p powered %d", device, powered);
+ DBG("device %p powered %d", device, powered);
if (device->powered == powered)
return -EALREADY;
__connman_technology_enabled(type);
- connman_device_set_disconnected(device, false);
device->scanning = false;
if (device->driver && device->driver->scan)
DBG("device %p", device);
- connman_device_set_disconnected(device, true);
-
g_hash_table_iter_init(&iter, device->networks);
while (g_hash_table_iter_next(&iter, &key, &value)) {
}
/**
- * connman_device_set_disconnected:
- * @device: device structure
- * @disconnected: disconnected state
- *
- * Change disconnected state of device (only for device with networks)
- */
- int connman_device_set_disconnected(struct connman_device *device,
- bool disconnected)
- {
- DBG("device %p disconnected %d", device, disconnected);
-
- if (device->disconnected == disconnected)
- return -EALREADY;
-
- device->disconnected = disconnected;
-
- return 0;
- }
-
- /**
- * connman_device_get_disconnected:
- * @device: device structure
- *
- * Get device disconnected state
- */
- bool connman_device_get_disconnected(struct connman_device *device)
- {
- return device->disconnected;
- }
-
- /**
* connman_device_set_string:
* @device: device structure
* @key: unique identifier
__connman_technology_notify_regdom_by_device(device, result, alpha2);
}
+#if defined TIZEN_EXT
+static int device_specific_scan(enum connman_service_type type,
+ struct connman_device *device,
+ int scan_type, GSList *specific_scan_list)
+{
+ if (!device->driver || !device->driver->specific_scan)
+ return -EOPNOTSUPP;
+
+ if (!device->powered)
+ return -ENOLINK;
+
+ return device->driver->specific_scan(type, device, scan_type,
+ specific_scan_list, NULL);
+}
+
+int __connman_device_request_specific_scan(enum connman_service_type type,
+ int scan_type, GSList *specific_scan_list)
+{
+ bool success = false;
+ int last_err = -ENOSYS;
+ GSList *list;
+ int err;
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return -EOPNOTSUPP;
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_P2P:
+ break;
+ }
+
+ for (list = device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ enum connman_service_type service_type =
+ __connman_device_get_service_type(device);
+
+ if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+ if (type == CONNMAN_SERVICE_TYPE_P2P) {
+ if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+ } else if (service_type != type)
+ continue;
+ }
+
+ err = device_specific_scan(type, device, scan_type, specific_scan_list);
+ if (err == 0 || err == -EINPROGRESS) {
+ success = true;
+ } else {
+ last_err = err;
+ DBG("device %p err %d", device, err);
+ }
+ }
+
+ if (success)
+ return 0;
+
+ return last_err;
+}
+#endif
+
int __connman_device_request_scan(enum connman_service_type type)
{
bool success = false;
}
err = device_scan(type, device);
+#if defined TIZEN_EXT
+ /* When Scan is already in progress then return Error so that
+ * wifi-manager can block the scan-done signal to be sent to
+ * application and start requested scan after scan already in progress
+ * is completed then notify to application about the scan event */
+ if (err == 0 || err == -EINPROGRESS) {
+#else
if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
+#endif
success = true;
} else {
last_err = err;
passphrase, security, user_data);
}
+#if defined TIZEN_EXT
+char *index2ident(int index, const char *prefix)
+#else
static char *index2ident(int index, const char *prefix)
+#endif
{
struct ifreq ifr;
struct ether_addr eth;
return str;
}
+#if defined TIZEN_EXT
+char *index2addr(int index)
+#else
static char *index2addr(int index)
+#endif
{
struct ifreq ifr;
struct ether_addr eth;
}
list:
+ if (__connman_inet_isrootnfs_device(devname)) {
+ DBG("ignoring device %s (rootnfs)", devname);
+ return true;
+ }
+
blacklisted_interfaces =
connman_setting_get_string_list("NetworkInterfaceBlacklist");
if (!blacklisted_interfaces)
DBG("cleaning up %s index %d", interfaces[i], index);
+#if defined TIZEN_EXT
+ if (strcmp(interfaces[i], "wlan0") != 0)
+#endif
connman_inet_ifdown(index);
/*
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+ #include <net/ethernet.h>
+
+ #ifndef IPV6_MIN_MTU
+ #define IPV6_MIN_MTU 1280
+ #endif
#include <connman/ipconfig.h>
#include <include/setting.h>
GDHCPClient *dhcp_client;
char *ipv4ll_debug_prefix;
char *dhcp_debug_prefix;
+
+ bool ipv4ll_running;
};
static GHashTable *ipconfig_table;
- static bool ipv4ll_running;
static void dhcp_free(struct connman_dhcp *dhcp)
{
+#if defined TIZEN_EXT
+ DBG("dhcp_free [%p]", dhcp);
+#endif
g_strfreev(dhcp->nameservers);
g_strfreev(dhcp->timeservers);
g_free(dhcp->pac);
dhcp->pac = NULL;
g_free(dhcp);
+#if defined TIZEN_EXT
+ dhcp = NULL;
+#endif
}
static void ipv4ll_stop_client(struct connman_dhcp *dhcp)
{
+#if defined TIZEN_EXT
+ DBG("dhcp [%p] ipv4ll_client [%p]", dhcp, dhcp->ipv4ll_client);
+#endif
if (!dhcp->ipv4ll_client)
return;
g_dhcp_client_stop(dhcp->ipv4ll_client);
g_dhcp_client_unref(dhcp->ipv4ll_client);
dhcp->ipv4ll_client = NULL;
- ipv4ll_running = false;
+ dhcp->ipv4ll_running = false;
g_free(dhcp->ipv4ll_debug_prefix);
dhcp->ipv4ll_debug_prefix = NULL;
__connman_service_timeserver_remove(service,
dhcp->timeservers[i]);
}
+ g_strfreev(dhcp->timeservers);
+ dhcp->timeservers = NULL;
}
if (dhcp->nameservers) {
for (i = 0; dhcp->nameservers[i]; i++) {
+#if defined TIZEN_EXT
__connman_service_nameserver_remove(service,
- dhcp->nameservers[i], false,
- CONNMAN_IPCONFIG_TYPE_IPV4);
- dhcp->nameservers[i], false);
++ dhcp->nameservers[i], false,
++ CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
+ __connman_service_nameserver_remove(service,
- dhcp->nameservers[i], false);
++ dhcp->nameservers[i], false);
+#endif
}
+ g_strfreev(dhcp->nameservers);
+ dhcp->nameservers = NULL;
}
return true;
int index;
int err;
+#if defined TIZEN_EXT
+ DBG("dhcp %p", dhcp);
+#endif
+
if (dhcp->ipv4ll_client)
return -EALREADY;
if (error != G_DHCP_CLIENT_ERROR_NONE)
return -EINVAL;
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_DHCP_DEBUG")) {
+#endif
dhcp->ipv4ll_debug_prefix = g_strdup_printf("IPv4LL index %d",
index);
g_dhcp_client_set_debug(ipv4ll_client, dhcp_debug,
dhcp->ipv4ll_debug_prefix);
+#if !defined TIZEN_EXT
}
+#endif
g_dhcp_client_set_id(ipv4ll_client);
return err;
}
- ipv4ll_running = true;
+ dhcp->ipv4ll_running = true;
return 0;
}
struct connman_dhcp *dhcp = user_data;
dhcp->timeout = 0;
-
+#if defined TIZEN_EXT
+ DBG("dhcp %p", dhcp);
+ DBG("dhcp->timeout %d", dhcp->timeout);
+#endif
g_dhcp_client_start(dhcp->dhcp_client,
__connman_ipconfig_get_dhcp_address(dhcp->ipconfig));
struct connman_dhcp *dhcp = user_data;
int err;
- DBG("No lease available ipv4ll %d client %p", ipv4ll_running,
+ DBG("No lease available ipv4ll %d client %p", dhcp->ipv4ll_running,
dhcp->ipv4ll_client);
if (dhcp->timeout > 0)
g_source_remove(dhcp->timeout);
dhcp->timeout = g_timeout_add_seconds(RATE_LIMIT_INTERVAL,
- dhcp_retry_cb,
- dhcp);
- if (ipv4ll_running)
+ dhcp_retry_cb,
+ dhcp);
+ if (dhcp->ipv4ll_running)
return;
err = ipv4ll_start_client(dhcp);
DBG("Cannot start ipv4ll client (%d/%s)", err, strerror(-err));
/* Only notify upper layer if we have a problem */
- dhcp_invalidate(dhcp, !ipv4ll_running);
+ dhcp_invalidate(dhcp, !dhcp->ipv4ll_running);
}
static void lease_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
return false;
}
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCP_MTU);
+ if (option && option->data) {
+ int mtu, index, err;
+
+ mtu = atoi(option->data);
+
+ if (mtu >= IPV6_MIN_MTU && mtu <= ETH_DATA_LEN) {
+ index = __connman_ipconfig_get_index(dhcp->ipconfig);
+ err = connman_inet_set_mtu(index, mtu);
+
+ DBG("MTU %d index %d err %d", mtu, index, err);
+ }
+ }
+
option = g_dhcp_client_get_option(dhcp_client, 252);
if (option)
pac = g_strdup(option->data);
if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
if (dhcp->nameservers) {
+#if defined TIZEN_EXT
+ for (i = 0; dhcp->nameservers[i] != NULL; i++) {
+ __connman_service_nameserver_remove(service,
+ dhcp->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ }
+#else
for (i = 0; dhcp->nameservers[i]; i++) {
__connman_service_nameserver_remove(service,
dhcp->nameservers[i], false);
}
+#endif
g_strfreev(dhcp->nameservers);
}
dhcp->nameservers = nameservers;
for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) {
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service,
+ dhcp->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
__connman_service_nameserver_append(service,
dhcp->nameservers[i], false);
+#endif
}
} else {
g_strfreev(nameservers);
{
struct connman_dhcp *dhcp = user_data;
GList *option = NULL;
+ enum connman_ipconfig_method old_method;
char *address, *netmask = NULL, *gateway = NULL;
const char *c_address, *c_gateway;
unsigned char prefixlen, c_prefixlen;
__connman_ipconfig_set_dhcp_address(dhcp->ipconfig, address);
DBG("last address %s", address);
+#if defined TIZEN_EXT
+ int dhcp_lease_duration = g_dhcp_client_get_dhcp_lease_duration(dhcp_client);
+#endif
+
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
if (option)
netmask = g_strdup(option->data);
} else if (prefixlen != c_prefixlen)
ip_change = true;
+ old_method = __connman_ipconfig_get_method(dhcp->ipconfig);
__connman_ipconfig_set_method(dhcp->ipconfig,
CONNMAN_IPCONFIG_METHOD_DHCP);
+#if defined TIZEN_EXT
+ __connman_ipconfig_set_dhcp_lease_duration(dhcp->ipconfig, dhcp_lease_duration);
+#endif
+
+ /*
+ * Notify IPv4.Configuration's method moved back to DHCP.
+ *
+ * This is the case ConnMan initially set an address by using
+ * IPv4LL because DHCP failed but now we got an address from DHCP.
+ */
+ if (old_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+ struct connman_service *service =
+ connman_service_lookup_from_network(dhcp->network);
+
+ if (service)
+ __connman_service_notify_ipv4_configuration(service);
+ }
+
if (ip_change) {
__connman_ipconfig_set_local(dhcp->ipconfig, address);
__connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
{
struct connman_dhcp *dhcp = user_data;
- char *address, *netmask;
- unsigned char prefixlen;
+ enum connman_ipconfig_method old_method;
+ char *address, *netmask;
+ unsigned char prefixlen;
DBG("IPV4LL available");
prefixlen = connman_ipaddress_calc_netmask_len(netmask);
+ old_method = __connman_ipconfig_get_method(dhcp->ipconfig);
__connman_ipconfig_set_method(dhcp->ipconfig,
- CONNMAN_IPCONFIG_METHOD_DHCP);
+ CONNMAN_IPCONFIG_METHOD_AUTO);
+
+ /*
+ * Notify IPv4.Configuration's method is AUTO now.
+ *
+ * This is the case DHCP failed thus ConnMan used IPv4LL to get an
+ * address. Set IPv4.Configuration method to AUTO allows user to
+ * ask for a DHCP address by setting the method again to DHCP.
+ */
+ if (old_method == CONNMAN_IPCONFIG_METHOD_DHCP) {
+ struct connman_service *service =
+ connman_service_lookup_from_network(dhcp->network);
+
+ if (service)
+ __connman_service_notify_ipv4_configuration(service);
+ }
+
__connman_ipconfig_set_local(dhcp->ipconfig, address);
__connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
__connman_ipconfig_set_gateway(dhcp->ipconfig, NULL);
GDHCPClient *dhcp_client;
GDHCPClientError error;
int index;
+ const char *vendor_class_id;
DBG("dhcp %p", dhcp);
dhcp_client = g_dhcp_client_new(G_DHCP_IPV4, index, &error);
if (error != G_DHCP_CLIENT_ERROR_NONE)
+#if defined TIZEN_EXT
+ {
+ DBG("failed g_dhcp_client_new(%d), index(%d)", error, index);
+#endif
return -EINVAL;
+#if defined TIZEN_EXT
+ }
+#endif
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_DHCP_DEBUG")) {
+#endif
dhcp->dhcp_debug_prefix = g_strdup_printf("DHCP index %d",
index);
g_dhcp_client_set_debug(dhcp_client, dhcp_debug,
dhcp->dhcp_debug_prefix);
+#if !defined TIZEN_EXT
}
+#endif
g_dhcp_client_set_id(dhcp_client);
g_dhcp_client_set_request(dhcp_client, G_DHCP_DOMAIN_NAME);
g_dhcp_client_set_request(dhcp_client, G_DHCP_NTP_SERVER);
g_dhcp_client_set_request(dhcp_client, 252);
+ g_dhcp_client_set_request(dhcp_client, G_DHCP_MTU);
}
- g_dhcp_client_set_request(dhcp_client, G_DHCP_SUBNET);
g_dhcp_client_set_request(dhcp_client, G_DHCP_ROUTER);
+ g_dhcp_client_set_request(dhcp_client, G_DHCP_SUBNET);
+
+ vendor_class_id = connman_option_get_string("VendorClassID");
+ if (vendor_class_id)
+ g_dhcp_client_set_send(dhcp_client, G_DHCP_VENDOR_CLASS_ID,
+ vendor_class_id);
g_dhcp_client_register_event(dhcp_client,
G_DHCP_CLIENT_EVENT_LEASE_AVAILABLE,
struct connman_network *network, dhcp_cb callback,
gpointer user_data)
{
+#if !defined TIZEN_EXT
const char *last_addr = NULL;
+#endif
struct connman_dhcp *dhcp;
int err;
return -EINVAL;
}
+#if !defined TIZEN_EXT
last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
+#endif
dhcp = g_hash_table_lookup(ipconfig_table, ipconfig);
if (!dhcp) {
dhcp->callback = callback;
dhcp->user_data = user_data;
+#if defined TIZEN_EXT
+ DBG("Start DHCP with DHCPDISCOVER request");
+
+ return g_dhcp_client_start(dhcp->dhcp_client, NULL);
+#else
return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
+#endif
}
void __connman_dhcp_stop(struct connman_ipconfig *ipconfig)
}
}
- static inline guint get_random(void)
+ static guint compute_random(guint val)
{
- uint64_t val;
-
- __connman_util_get_random(&val);
+ uint64_t rand;
- /* Make sure the value is always positive so strip MSB */
- return ((uint32_t)val) >> 1;
- }
+ __connman_util_get_random(&rand);
- static guint compute_random(guint val)
- {
return val - val / 10 +
- (get_random() % (2 * 1000)) * val / 10 / 1000;
+ ((guint) rand % (2 * 1000)) * val / 10 / 1000;
}
/* Calculate a random delay, RFC 3315 chapter 14 */
int duid_len;
ident = __connman_service_get_ident(service);
+#if defined TIZEN_EXT
+ if(ident != NULL)
+ DBG("ident : %s", ident);
+#endif
keyfile = connman_storage_load_service(ident);
+
+#if defined TIZEN_EXT
+ if (!keyfile) {
+ keyfile = g_key_file_new();
+ if (!keyfile)
+ return -EIO;
+ }
+#else
if (!keyfile)
return -EINVAL;
+#endif
hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID",
NULL);
hex_duid = convert_to_hex(duid, duid_len);
if (!hex_duid) {
+ g_free(duid);
g_key_file_free(keyfile);
return -ENOMEM;
}
if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
if (dhcp->nameservers) {
for (i = 0; dhcp->nameservers[i]; i++)
+#if defined TIZEN_EXT
+ {
__connman_service_nameserver_remove(service,
- dhcp->nameservers[i],
- false);
+ dhcp->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
+ __connman_service_nameserver_remove(service,
+ dhcp->nameservers[i],
+ false);
+#endif
+#if defined TIZEN_EXT
+ }
+#endif
g_strfreev(dhcp->nameservers);
}
for (i = 0; dhcp->nameservers &&
dhcp->nameservers[i]; i++)
+#if defined TIZEN_EXT
+ {
+ __connman_service_nameserver_append(service,
+ dhcp->nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
__connman_service_nameserver_append(service,
dhcp->nameservers[i],
false);
+#endif
+#if defined TIZEN_EXT
+ }
+#endif
} else
g_strfreev(nameservers);
return -EINVAL;
}
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_DHCPV6_DEBUG"))
+#endif
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
service = connman_service_lookup_from_network(dhcp->network);
if (!slash)
continue;
- prefix = g_strndup(prefix, slash - prefix);
len = strtol(slash + 1, NULL, 10);
if (len < 3 || len > 128)
break;
left = plen % 8;
i = 16 - count;
+ prefix = g_strndup(prefix, slash - prefix);
inet_pton(AF_INET6, prefix, &addr_prefix);
inet_pton(AF_INET6, address, &addr);
if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
if (dhcp->nameservers) {
for (i = 0; dhcp->nameservers[i]; i++)
+#if defined TIZEN_EXT
+ {
+ __connman_service_nameserver_remove(service,
+ dhcp->nameservers[i],
+ false, CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
__connman_service_nameserver_remove(service,
dhcp->nameservers[i],
false);
+#endif
+#if defined TIZEN_EXT
+ }
+#endif
g_strfreev(dhcp->nameservers);
}
for (i = 0; dhcp->nameservers &&
dhcp->nameservers[i]; i++)
+#if defined TIZEN_EXT
+ {
__connman_service_nameserver_append(service,
- dhcp->nameservers[i],
- false);
+ dhcp->nameservers[i],
+ false, CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
+ __connman_service_nameserver_append(service,
+ dhcp->nameservers[i],
+ false);
+#endif
+#if defined TIZEN_EXT
+ }
+#endif
} else
g_strfreev(nameservers);
/* Is this prefix part of the subnet we are suppose to use? */
prefix_len = check_ipv6_addr_prefix(prefixes, address);
+#if defined TIZEN_EXT
+ char *gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
+#endif
__connman_ipconfig_address_remove(ipconfig);
__connman_ipconfig_set_local(ipconfig, address);
__connman_ipconfig_set_prefixlen(ipconfig, prefix_len);
DBG("new address %s/%d", address, prefix_len);
__connman_ipconfig_set_dhcp_address(ipconfig, address);
+#if defined TIZEN_EXT
+ DBG("Set gateway %s", gateway);
+ __connman_ipconfig_set_gateway(ipconfig, gateway);
+ g_free(gateway);
+#endif
__connman_service_save(
__connman_service_lookup_from_index(ifindex));
}
static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
{
struct connman_service *service;
+#if !defined TIZEN_EXT
struct connman_ipconfig *ipconfig_ipv6;
+#endif
GDHCPClient *dhcp_client;
GDHCPClientError error;
int index, ret;
return -EINVAL;
}
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_DHCPV6_DEBUG"))
+#endif
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
service = connman_service_lookup_from_network(dhcp->network);
g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS,
G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS);
+#if defined TIZEN_EXT
+ /**
+ When privacy extension is enabled then connman requests
+ OPTION_IA_TA (4) from DHCPv6 server. This option is used to request
+ temporary IPv6 address from DHCPv6 server but we found that DHCPv6
+ server never provided temporary IPv6 address and connman resend dhcpv6
+ requests. So always set OPTION_IA_NA in dhcpv6 request to get IPv6
+ address from DHCPv6 server.
+ */
+ dhcp->use_ta = FALSE;
+#else
ipconfig_ipv6 = __connman_service_get_ip6config(service);
dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6);
+#endif
g_dhcpv6_client_set_ia(dhcp_client, index,
dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
return NULL;
}
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_DHCPV6_DEBUG"))
+#endif
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6:PD");
service = connman_service_lookup_from_network(dhcp->network);
#include "connman.h"
+#if defined TIZEN_EXT
+#include <sys/smack.h>
+#include <systemd/sd-daemon.h>
+#endif
+
+ #define debug(fmt...) do { } while (0)
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
struct domain_hdr {
uint16_t id;
* By default the TTL (time-to-live) of the DNS response is used
* when setting the cache entry life time. The value is in seconds.
*/
+#if defined TIZEN_EXT
+#define MAX_CACHE_TTL (60 * 60)
+#else
#define MAX_CACHE_TTL (60 * 30)
+#endif
/*
* Also limit the other end, cache at least for 30 seconds.
*/
static GHashTable *cache;
static int cache_refcount;
static GSList *server_list = NULL;
+#if defined TIZEN_EXT
+static GSList *server_list_sec = NULL;
+#endif
static GSList *request_list = NULL;
static GHashTable *listener_table = NULL;
static time_t next_refresh;
static GHashTable *partial_tcp_req_table;
static guint cache_timer = 0;
+#if defined TIZEN_EXT
+static void destroy_server_sec(struct server_data *server);
+static struct server_data *create_server_sec(int index,
+ const char *domain, const char *server,
+ int protocol);
+#endif
+
static guint16 get_id(void)
{
uint64_t rand;
{
GSList *list;
- DBG("index %d server %s proto %d", index, server, protocol);
+ debug("index %d server %s proto %d", index, server, protocol);
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
}
if (!entry->ipv4) {
- DBG("Refresing A record for %s", name);
+ debug("Refreshing A record for %s", name);
g_resolv_lookup_hostname(ipv4_resolve, name,
dummy_resolve_func, NULL);
age = 4;
}
if (!entry->ipv6) {
- DBG("Refresing AAAA record for %s", name);
+ debug("Refreshing AAAA record for %s", name);
g_resolv_lookup_hostname(ipv6_resolve, name,
dummy_resolve_func, NULL);
age = 4;
{
if ((buf[0] & NS_CMPRSFLGS) == NS_CMPRSFLGS) /* compressed name */
return 2;
- return strlen((char *)buf);
+ return strlen((char *)buf) + 1;
}
static void update_cached_ttl(unsigned char *buf, int len, int new_ttl)
else
update_cached_ttl((unsigned char *)hdr, adj_len, ttl);
- DBG("sk %d id 0x%04x answers %d ptr %p length %d dns %d",
+ debug("sk %d id 0x%04x answers %d ptr %p length %d dns %d",
sk, hdr->id, answers, ptr, len, dns_len);
err = sendto(sk, ptr, len, MSG_NOSIGNAL, to, tolen);
if (err != len || (dns_len != (len - 2) && protocol == IPPROTO_TCP) ||
(dns_len != len && protocol == IPPROTO_UDP))
- DBG("Packet length mismatch, sent %d wanted %d dns %d",
+ debug("Packet length mismatch, sent %d wanted %d dns %d",
err, len, dns_len);
}
struct domain_hdr *hdr;
int err, offset = protocol_offset(protocol);
- DBG("sk %d", sk);
+ debug("sk %d", sk);
if (offset < 0)
return;
hdr = (void *) (buf + offset);
- DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
+ debug("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
hdr->qr = 1;
hdr->rcode = ns_r_servfail;
if (!req)
return FALSE;
- DBG("id 0x%04x", req->srcid);
+ debug("id 0x%04x", req->srcid);
request_list = g_slist_remove(request_list, req);
* if we get a request timeout from server.
*/
if (req->protocol == IPPROTO_TCP) {
- DBG("client %d removed", req->client_sk);
+ debug("client %d removed", req->client_sk);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(req->client_sk));
}
unsigned char *ptr = buf;
int len;
- DBG("query %s domain %s", query, domain);
+ debug("query %s domain %s", query, domain);
while (query) {
const char *tmp;
if (!cache_check_is_valid(entry->ipv4, current_time)
&& entry->ipv4) {
- DBG("cache timeout \"%s\" type A", entry->key);
+ debug("cache timeout \"%s\" type A", entry->key);
g_free(entry->ipv4->data);
g_free(entry->ipv4);
entry->ipv4 = NULL;
if (!cache_check_is_valid(entry->ipv6, current_time)
&& entry->ipv6) {
- DBG("cache timeout \"%s\" type AAAA", entry->key);
+ debug("cache timeout \"%s\" type AAAA", entry->key);
g_free(entry->ipv6->data);
g_free(entry->ipv6);
entry->ipv6 = NULL;
switch (type) {
case 1: /* IPv4 */
if (!cache_check_is_valid(entry->ipv4, current_time)) {
- DBG("cache %s \"%s\" type A", entry->ipv4 ?
+ debug("cache %s \"%s\" type A", entry->ipv4 ?
"timeout" : "entry missing", question);
if (want_refresh)
case 28: /* IPv6 */
if (!cache_check_is_valid(entry->ipv6, current_time)) {
- DBG("cache %s \"%s\" type AAAA", entry->ipv6 ?
+ debug("cache %s \"%s\" type AAAA", entry->ipv6 ?
"timeout" : "entry missing", question);
if (want_refresh)
cache_timer = 0;
if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) {
- DBG("No cache users, removing it.");
+ debug("No cache users, removing it.");
g_hash_table_destroy(cache);
cache = NULL;
if (buflen < 12)
return -EINVAL;
- DBG("qr %d qdcount %d", hdr->qr, qdcount);
+ debug("qr %d qdcount %d", hdr->qr, qdcount);
/* We currently only cache responses where question count is 1 */
if (hdr->qr != 1 || qdcount != 1)
count = g_hash_table_foreach_remove(cache, cache_check_entry,
&data);
}
- DBG("removed %d in the first pass", count);
+ debug("removed %d in the first pass", count);
/*
* In the second pass, if the first pass turned up blank,
*/
static void cache_invalidate(void)
{
- DBG("Invalidating the DNS cache %p", cache);
+ debug("Invalidating the DNS cache %p", cache);
if (!cache)
return;
*c = '.';
c += jump + 1;
}
- DBG("Refreshing %s\n", dns_name);
+ debug("Refreshing %s\n", dns_name);
/* then refresh the hostname */
refresh_dns_entry(entry, &dns_name[1]);
}
return 0;
/* now the query, which is a name and 2 16 bit words */
- l = dns_name_length(c) + 1;
+ l = dns_name_length(c);
c += l;
type = c[0] << 8 | c[1];
if (offset < 0)
return 0;
- DBG("offset %d hdr %p msg %p rcode %d", offset, hdr, msg, hdr->rcode);
+ debug("offset %d hdr %p msg %p rcode %d", offset, hdr, msg, hdr->rcode);
/* Continue only if response code is 0 (=ok) */
if (hdr->rcode != ns_r_noerror)
cache_size++;
}
- DBG("cache %d %squestion \"%s\" type %d ttl %d size %zd packet %u "
+ debug("cache %d %squestion \"%s\" type %d ttl %d size %zd packet %u "
"dns len %u",
cache_size, new_entry ? "new " : "old ",
question, type, ttl,
int ttl_left = 0;
struct cache_data *data;
- DBG("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
+ debug("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
if (type == 1)
data = entry->ipv4;
else
}
}
+#if defined TIZEN_EXT
+ if (server->protocol == IPPROTO_UDP) {
+ GList *domains;
+ struct server_data *new_server = NULL;
+
+ new_server = create_server_sec(server->index, NULL,
+ server->server, IPPROTO_UDP);
+
+ if (new_server != NULL) {
+ for (domains = server->domains; domains;
+ domains = domains->next) {
+ char *dom = domains->data;
+
+ DBG("Adding domain %s to %s",
+ dom, new_server->server);
+
+ new_server->domains = g_list_append(
+ new_server->domains,
+ g_strdup(dom));
+ }
+
+ server = new_server;
+ }
+ }
+#endif
sk = g_io_channel_unix_get_fd(server->channel);
err = sendto(sk, request, req->request_len, MSG_NOSIGNAL,
server->server_addr, server->server_addr_len);
if (err < 0) {
- DBG("Cannot send message to server %s sock %d "
+ debug("Cannot send message to server %s sock %d "
"protocol %d (%s/%d)",
server->server, sk, server->protocol,
strerror(errno), errno);
alt[1] = req_len & 0xff;
}
- DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid,
+ debug("req %p dstid 0x%04x altid 0x%04x", req, req->dstid,
req->altid);
err = send(sk, alt, req->request_len + domlen, MSG_NOSIGNAL);
pos = dn_expand((u_char *)start, (u_char *)end, (u_char *)ptr,
name, NS_MAXLABEL);
if (pos < 0) {
- DBG("uncompress error [%d/%s]", errno, strerror(errno));
+ debug("uncompress error [%d/%s]", errno, strerror(errno));
goto out;
}
*/
comp_pos = dn_comp(name, (u_char *)uptr, remaining_len, NULL, NULL);
if (comp_pos < 0) {
- DBG("compress error [%d/%s]", errno, strerror(errno));
+ debug("compress error [%d/%s]", errno, strerror(errno));
goto out;
}
{
char *uptr = *uncompressed_ptr; /* position in result buffer */
- DBG("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
+ debug("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
while (field_count-- > 0 && ptr < end) {
int dlen; /* data field length */
ulen = strlen(name);
strncpy(uptr, name, uncomp_len - (uptr - uncompressed));
- DBG("pos %d ulen %d left %d name %s", pos, ulen,
+ debug("pos %d ulen %d left %d name %s", pos, ulen,
(int)(uncomp_len - (uptr - uncompressed)), uptr);
uptr += ulen;
dlen = uptr[-2] << 8 | uptr[-1];
if (ptr + dlen > end) {
- DBG("data len %d too long", dlen);
+ debug("data len %d too long", dlen);
goto out;
}
hdr = (void *)(reply + offset);
dns_id = reply[offset] | reply[offset + 1] << 8;
- DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
+ debug("Received %d bytes (id 0x%04x)", reply_len, dns_id);
req = find_request(dns_id);
if (!req)
return -EINVAL;
- DBG("req %p dstid 0x%04x altid 0x%04x rcode %d",
+ debug("req %p dstid 0x%04x altid 0x%04x rcode %d",
req, req->dstid, req->altid, hdr->rcode);
reply[offset] = req->srcid & 0xff;
ptr[dns_type_pos + 3];
if (dns_type != ns_t_a && dns_type != ns_t_aaaa &&
dns_class != ns_c_in) {
- DBG("Pass msg dns type %d class %d",
+ debug("Pass msg dns type %d class %d",
dns_type, dns_class);
goto pass;
}
(char *)reply + offset, eom,
ptr, uncompressed, NS_MAXDNAME,
&uptr);
- if (ptr == NULL)
+ if (!ptr)
goto out;
ptr = uncompress(ntohs(hdr->nscount),
(char *)reply + offset, eom,
ptr, uncompressed, NS_MAXDNAME,
&uptr);
- if (ptr == NULL)
+ if (!ptr)
goto out;
ptr = uncompress(ntohs(hdr->arcount),
(char *)reply + offset, eom,
ptr, uncompressed, NS_MAXDNAME,
&uptr);
- if (ptr == NULL)
+ if (!ptr)
goto out;
/*
new_len = strip_domains(uncompressed, answers,
uptr - answers);
if (new_len < 0) {
- DBG("Corrupted packet");
+ debug("Corrupted packet");
return -EINVAL;
}
}
if (err < 0)
- DBG("Cannot send msg, sk %d proto %d errno %d/%s", sk,
+ debug("Cannot send msg, sk %d proto %d errno %d/%s", sk,
protocol, errno, strerror(errno));
else
- DBG("proto %d sent %d bytes to %d", protocol, err, sk);
+ debug("proto %d sent %d bytes to %d", protocol, err, sk);
destroy_request_data(req);
static void server_destroy_socket(struct server_data *data)
{
- DBG("index %d server %s proto %d", data->index,
+ debug("index %d server %s proto %d", data->index,
data->server, data->protocol);
if (data->watch > 0) {
static void destroy_server(struct server_data *server)
{
- DBG("index %d server %s sock %d", server->index, server->server,
+ debug("index %d server %s sock %d", server->index, server->server,
server->channel ?
g_io_channel_unix_get_fd(server->channel): -1);
server_destroy_socket(server);
if (server->protocol == IPPROTO_UDP && server->enabled)
- DBG("Removing DNS server %s", server->server);
+ debug("Removing DNS server %s", server->server);
g_free(server->server);
g_list_free_full(server->domains, g_free);
if (err < 0)
return TRUE;
+#if defined TIZEN_EXT
+ GSList *list;
+
+ for (list = server_list_sec; list; list = list->next) {
+ struct server_data *new_data = list->data;
+
+ if (new_data == data) {
+ destroy_server_sec(data);
+ return TRUE;
+ }
+ }
+#endif
+
return TRUE;
}
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
GSList *list;
hangup:
- DBG("TCP server channel closed, sk %d", sk);
+ debug("TCP server channel closed, sk %d", sk);
/*
* Discard any partial response which is buffered; better
g_free(server->incoming_reply);
server->incoming_reply = NULL;
- for (list = request_list; list; list = list->next) {
+ list = request_list;
+ while (list) {
struct request_data *req = list->data;
struct domain_hdr *hdr;
+ list = list->next;
if (req->protocol == IPPROTO_UDP)
continue;
domains = domains->next) {
char *dom = domains->data;
- DBG("Adding domain %s to %s",
+ debug("Adding domain %s to %s",
dom, server->server);
server->domains = g_list_append(server->domains,
continue;
}
- DBG("Sending req %s over TCP", (char *)req->name);
+ debug("Sending req %s over TCP", (char *)req->name);
status = ns_resolv(server, req,
req->request, req->name);
reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
reply_len += 2;
- DBG("TCP reply %d bytes from %d", reply_len, sk);
+ debug("TCP reply %d bytes from %d", reply_len, sk);
reply = g_try_malloc(sizeof(*reply) + reply_len + 2);
if (!reply)
{
struct server_data *server = user_data;
- DBG("");
+ debug("");
if (!server)
return FALSE;
int sk, err;
char *interface;
- DBG("index %d server %s proto %d", data->index,
+ debug("index %d server %s proto %d", data->index,
data->server, data->protocol);
sk = socket(data->server_addr->sa_family,
return -err;
}
- DBG("sk %d", sk);
+ debug("sk %d", sk);
interface = connman_inet_ifname(data->index);
if (interface) {
return 0;
}
+ static void enable_fallback(bool enable)
+ {
+ GSList *list;
+
+ for (list = server_list; list; list = list->next) {
+ struct server_data *data = list->data;
+
+ if (data->index != -1)
+ continue;
+
+ if (enable)
+ DBG("Enabling fallback DNS server %s", data->server);
+ else
+ DBG("Disabling fallback DNS server %s", data->server);
+
+ data->enabled = enable;
+ }
+ }
+
+#if defined TIZEN_EXT
+
+static void destroy_server_sec(struct server_data *server)
+{
+ GList *list;
+ int fd;
+
+ if (server->channel)
+ fd = g_io_channel_unix_get_fd(server->channel);
+ else
+ fd = -1;
+
+ DBG("index %d server %s sock %d", server->index, server->server, fd);
+
+ server_list_sec = g_slist_remove(server_list_sec, server);
+
+ if (fd > 0)
+ close(fd);
+
+ server_destroy_socket(server);
+
+ if (server->protocol == IPPROTO_UDP && server->enabled)
+ DBG("Removing DNS server %s", server->server);
+
+ g_free(server->server);
+ for (list = server->domains; list; list = list->next) {
+ char *domain = list->data;
+
+ server->domains = g_list_remove(server->domains, domain);
+ g_free(domain);
+ }
+ g_free(server->server_addr);
+
+ /*
+ * We do not remove cache right away but delay it few seconds.
+ * The idea is that when IPv6 DNS server is added via RDNSS, it has a
+ * lifetime. When the lifetime expires we decrease the refcount so it
+ * is possible that the cache is then removed. Because a new DNS server
+ * is usually created almost immediately we would then loose the cache
+ * without any good reason. The small delay allows the new RDNSS to
+ * create a new DNS server instance and the refcount does not go to 0.
+ */
+ /* TODO: Need to check this */
+ /* g_timeout_add_seconds(3, try_remove_cache, NULL); */
+
+ g_free(server);
+}
+
+static void destroy_all_server_sec()
+{
+ GSList *list;
+
+ DBG("remove all dns server");
+
+ for (list = server_list_sec; list; list = list->next) {
+ struct server_data *server = list->data;
+ destroy_server_sec(server);
+ }
+ server_list_sec = NULL;
+}
+
+static gboolean sec_udp_idle_timeout(gpointer user_data)
+{
+ struct server_data *server = user_data;
+
+ DBG("");
+
+ if (server == NULL)
+ return FALSE;
+
+ destroy_server_sec(server);
+
+ return FALSE;
+}
+
+static struct server_data *create_server_sec(int index,
+ const char *domain, const char *server,
+ int protocol)
+{
+ struct server_data *data;
+ struct addrinfo hints, *rp;
+ int ret;
+
+ DBG("index %d server %s", index, server);
+
+ data = g_try_new0(struct server_data, 1);
+ if (data == NULL) {
+ connman_error("Failed to allocate server %s data", server);
+ return NULL;
+ }
+
+ data->index = index;
+ if (domain)
+ data->domains = g_list_append(data->domains, g_strdup(domain));
+ data->server = g_strdup(server);
+ data->protocol = protocol;
+
+ memset(&hints, 0, sizeof(hints));
+
+ switch (protocol) {
+ case IPPROTO_UDP:
+ hints.ai_socktype = SOCK_DGRAM;
+ break;
+
+ case IPPROTO_TCP:
+ hints.ai_socktype = SOCK_STREAM;
+ break;
+
+ default:
+ destroy_server_sec(data);
+ return NULL;
+ }
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST;
+
+ ret = getaddrinfo(data->server, "53", &hints, &rp);
+ if (ret) {
+ connman_error("Failed to parse server %s address: %s\n",
+ data->server, gai_strerror(ret));
+ freeaddrinfo(rp);
+ destroy_server_sec(data);
+ return NULL;
+ }
+
+ /* Do not blindly copy this code elsewhere; it doesn't loop over the
+ results using ->ai_next as it should. That's OK in *this* case
+ because it was a numeric lookup; we *know* there's only one. */
+
+ data->server_addr_len = rp->ai_addrlen;
+
+ switch (rp->ai_family) {
+ case AF_INET:
+ data->server_addr = (struct sockaddr *)
+ g_try_new0(struct sockaddr_in, 1);
+ break;
+ case AF_INET6:
+ data->server_addr = (struct sockaddr *)
+ g_try_new0(struct sockaddr_in6, 1);
+ break;
+ default:
+ connman_error("Wrong address family %d", rp->ai_family);
+ break;
+ }
+ if (data->server_addr == NULL) {
+ freeaddrinfo(rp);
+ destroy_server_sec(data);
+ return NULL;
+ }
+ memcpy(data->server_addr, rp->ai_addr, rp->ai_addrlen);
+ freeaddrinfo(rp);
+
+ if (server_create_socket(data) != 0) {
+ destroy_server_sec(data);
+ return NULL;
+ }
+
+ if (protocol == IPPROTO_UDP) {
+ /* Enable new servers by default */
+ data->enabled = TRUE;
+ DBG("Adding DNS server %s", data->server);
+
+ data->timeout = g_timeout_add_seconds(30, sec_udp_idle_timeout,
+ data);
+
+ server_list_sec = g_slist_append(server_list_sec, data);
+ }
+
+ return data;
+}
+#endif
+
static struct server_data *create_server(int index,
const char *domain, const char *server,
int protocol)
data->index)) {
data->enabled = true;
DBG("Adding DNS server %s", data->server);
+
+ enable_fallback(false);
}
server_list = g_slist_append(server_list, data);
continue;
}
- DBG("server %s enabled %d", data->server, data->enabled);
+ debug("server %s enabled %d", data->server, data->enabled);
if (!data->enabled)
continue;
return false;
}
- static void append_domain(int index, const char *domain)
+ static void update_domain(int index, const char *domain, bool append)
{
GSList *list;
}
}
- if (!dom_found) {
+ if (!dom_found && append) {
data->domains =
g_list_append(data->domains, g_strdup(domain));
+ } else if (dom_found && !append) {
+ data->domains =
+ g_list_remove(data->domains, dom);
+ g_free(dom);
}
}
}
+ static void append_domain(int index, const char *domain)
+ {
+ update_domain(index, domain, true);
+ }
+
+ static void remove_domain(int index, const char *domain)
+ {
+ update_domain(index, domain, false);
+ }
+
static void flush_requests(struct server_data *server)
{
GSList *list;
const char *server, int protocol)
{
struct server_data *data;
+ GSList *list;
data = find_server(index, server, protocol);
if (!data)
return;
destroy_server(data);
+
+ for (list = server_list; list; list = list->next) {
+ struct server_data *data = list->data;
+
+ if (data->index != -1 && data->enabled == true)
+ return;
+ }
+
+ enable_fallback(true);
}
int __connman_dnsproxy_remove(int index, const char *domain,
{
DBG("index %d server %s", index, server);
- if (!server)
+ if (!server && !domain)
return -EINVAL;
+ if (!server) {
+ remove_domain(index, domain);
+
+ return 0;
+ }
+
if (g_str_equal(server, "127.0.0.1"))
return -ENODEV;
remove_server(index, domain, server, IPPROTO_UDP);
remove_server(index, domain, server, IPPROTO_TCP);
+#if defined TIZEN_EXT
+ destroy_all_server_sec();
+#endif
+
return 0;
}
static void dnsproxy_default_changed(struct connman_service *service)
{
+ bool server_enabled = false;
GSList *list;
int index;
if (data->index == index) {
DBG("Enabling DNS server %s", data->server);
data->enabled = true;
+ server_enabled = true;
} else {
DBG("Disabling DNS server %s", data->server);
data->enabled = false;
}
}
+ if (!server_enabled)
+ enable_fallback(true);
+
cache_refresh();
}
if (len < 12)
return -EINVAL;
- DBG("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
+ debug("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
hdr->id, hdr->qr, hdr->opcode,
qdcount, arcount);
edns0_bufsize = last_label[7] << 8 | last_label[8];
- DBG("EDNS0 buffer size %u", edns0_bufsize);
+ debug("EDNS0 buffer size %u", edns0_bufsize);
/* This is an evil hack until full TCP support has been
* implemented.
}
}
- DBG("query %s", name);
+ debug("query %s", name);
return 0;
}
return;
if (client->channel) {
- DBG("client %d closing",
+ debug("client %d closing",
g_io_channel_unix_get_fd(client->channel));
g_io_channel_unref(client->channel);
client_sk = g_io_channel_unix_get_fd(client->channel);
if (read_len == 0) {
- DBG("client %d closed, pending %d bytes",
+ debug("client %d closed, pending %d bytes",
client_sk, client->buf_end);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
return false;
}
- DBG("client %d received %d bytes", client_sk, read_len);
+ debug("client %d received %d bytes", client_sk, read_len);
client->buf_end += read_len;
msg_len = get_msg_len(client->buf);
if (msg_len > TCP_MAX_BUF_LEN) {
- DBG("client %d sent too much data %d", client_sk, msg_len);
+ debug("client %d sent too much data %d", client_sk, msg_len);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
return false;
}
read_another:
- DBG("client %d msg len %d end %d past end %d", client_sk, msg_len,
+ debug("client %d msg len %d end %d past end %d", client_sk, msg_len,
client->buf_end, client->buf_end - (msg_len + 2));
if (client->buf_end < (msg_len + 2)) {
- DBG("client %d still missing %d bytes",
+ debug("client %d still missing %d bytes",
client_sk,
msg_len + 2 - client->buf_end);
return true;
}
- DBG("client %d all data %d received", client_sk, msg_len);
+ debug("client %d all data %d received", client_sk, msg_len);
err = parse_request(client->buf + 2, msg_len,
query, sizeof(query));
int ttl_left = 0;
struct cache_data *data;
- DBG("cache hit %s type %s", query, qtype == 1 ? "A" : "AAAA");
+ debug("cache hit %s type %s", query, qtype == 1 ? "A" : "AAAA");
if (qtype == 1)
data = entry->ipv4;
else
g_free(req);
goto out;
} else
- DBG("data missing, ignoring cache for this query");
+ debug("data missing, ignoring cache for this query");
}
for (list = server_list; list; list = list->next) {
out:
if (client->buf_end > (msg_len + 2)) {
- DBG("client %d buf %p -> %p end %d len %d new %d",
+ debug("client %d buf %p -> %p end %d len %d new %d",
client_sk,
client->buf + msg_len + 2,
client->buf, client->buf_end,
*/
msg_len = get_msg_len(client->buf);
if ((msg_len + 2) == client->buf_end) {
- DBG("client %d reading another %d bytes", client_sk,
+ debug("client %d reading another %d bytes", client_sk,
msg_len + 2);
goto read_another;
}
} else {
- DBG("client %d clearing reading buffer", client_sk);
+ debug("client %d clearing reading buffer", client_sk);
client->buf_end = 0;
memset(client->buf, 0, TCP_MAX_BUF_LEN);
if (errno == EAGAIN || errno == EWOULDBLOCK)
return TRUE;
- DBG("client %d cannot read errno %d/%s", client_sk, -errno,
+ debug("client %d cannot read errno %d/%s", client_sk, -errno,
strerror(errno));
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
sock = g_io_channel_unix_get_fd(client->channel);
- DBG("client %d timeout pending %d bytes", sock, client->buf_end);
+ debug("client %d timeout pending %d bytes", sock, client->buf_end);
g_hash_table_remove(partial_tcp_req_table, GINT_TO_POINTER(sock));
return FALSE;
}
+#if defined TIZEN_EXT
+static void recover_listener(GIOChannel *channel, struct listener_data *ifdata)
+{
+ int sk, index;
+
+ index = ifdata->index;
+
+ sk = g_io_channel_unix_get_fd(channel);
+ close(sk);
+
+ __connman_dnsproxy_remove_listener(index);
+
+ if (__connman_dnsproxy_add_listener(index) == 0)
+ DBG("listener %d successfully recovered", index);
+}
+#endif
+
static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition,
struct listener_data *ifdata, int family,
guint *listener_watch)
struct timeval tv;
fd_set readfds;
- DBG("condition 0x%02x channel %p ifdata %p family %d",
+ debug("condition 0x%02x channel %p ifdata %p family %d",
condition, channel, ifdata, family);
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+#if defined TIZEN_EXT
+ connman_error("Error %d with TCP listener channel", condition);
+
+ recover_listener(channel, ifdata);
+#else
if (*listener_watch > 0)
g_source_remove(*listener_watch);
*listener_watch = 0;
connman_error("Error with TCP listener channel");
+#endif
return false;
}
select(sk + 1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(sk, &readfds)) {
client_sk = accept(sk, client_addr, client_addr_len);
- DBG("client %d accepted", client_sk);
+ debug("client %d accepted", client_sk);
} else {
- DBG("No data to read from master %d, waiting.", sk);
+ debug("No data to read from master %d, waiting.", sk);
return true;
}
client->ifdata = ifdata;
- DBG("client %d created %p", client_sk, client);
+ debug("client %d created %p", client_sk, client);
} else {
- DBG("client %d already exists %p", client_sk, client);
+ debug("client %d already exists %p", client_sk, client);
}
if (!client->buf) {
len = recv(client_sk, client->buf, TCP_MAX_BUF_LEN, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
- DBG("client %d no data to read, waiting", client_sk);
+ debug("client %d no data to read, waiting", client_sk);
return true;
}
- DBG("client %d cannot read errno %d/%s", client_sk, -errno,
+ debug("client %d cannot read errno %d/%s", client_sk, -errno,
strerror(errno));
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
}
if (len < 2) {
- DBG("client %d not enough data to read, waiting", client_sk);
+ debug("client %d not enough data to read, waiting", client_sk);
client->buf_end += len;
return true;
}
msg_len = get_msg_len(client->buf);
if (msg_len > TCP_MAX_BUF_LEN) {
- DBG("client %d invalid message length %u ignoring packet",
+ debug("client %d invalid message length %u ignoring packet",
client_sk, msg_len);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
* The packet length bytes do not contain the total message length,
* that is the reason to -2 below.
*/
+#if defined TIZEN_EXT
+ if (msg_len > (unsigned int)(len - 2)) {
+#else
if (msg_len != (unsigned int)(len - 2)) {
- DBG("client %d sent %d bytes but expecting %u pending %d",
+#endif
+ debug("client %d sent %d bytes but expecting %u pending %d",
client_sk, len, msg_len + 2, msg_len + 2 - len);
client->buf_end += len;
int sk, err, len;
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+#if defined TIZEN_EXT
+ connman_error("Error %d with UDP listener channel", condition);
+
+ recover_listener(channel, ifdata);
+#else
connman_error("Error with UDP listener channel");
*listener_watch = 0;
+#endif
return false;
}
if (len < 2)
return true;
- DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
+ debug("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
err = parse_request(buf, len, query, sizeof(query));
if (err < 0 || (g_slist_length(server_list) == 0)) {
req->name = g_strdup(query);
req->request = g_malloc(len);
memcpy(req->request, buf, len);
+#if defined TIZEN_EXT
+ DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid, req->altid);
+ req->timeout = g_timeout_add_seconds(30, request_timeout, req);
+#else
req->timeout = g_timeout_add_seconds(5, request_timeout, req);
+#endif
request_list = g_slist_append(request_list, req);
return true;
{
GIOChannel *channel;
const char *proto;
+#if !defined TIZEN_EXT
union {
struct sockaddr sa;
struct sockaddr_in6 sin6;
struct sockaddr_in sin;
} s;
socklen_t slen;
+#endif
int sk, type;
+#if !defined TIZEN_EXT
char *interface;
+#endif
+#if defined TIZEN_EXT
+ int option;
+ int sd_num = 0;
+ int rv;
+ int is_socket_inet = 0;
+#endif
- DBG("family %d protocol %d index %d", family, protocol, index);
+ debug("family %d protocol %d index %d", family, protocol, index);
switch (protocol) {
case IPPROTO_UDP:
default:
return NULL;
}
+#if defined TIZEN_EXT
+ sd_num = sd_listen_fds(0);
+ DBG("socket type(%s) systemd number of fds(%d)", proto, sd_num);
+ if(sd_num < 1){
+ DBG("fail to get the fd from systemd");
+ return NULL;
+ }
+ if(protocol == IPPROTO_TCP)
+ type = SOCK_STREAM;
+ else
+ type = SOCK_DGRAM;
+
+ for(sk = SD_LISTEN_FDS_START; sk < SD_LISTEN_FDS_START+sd_num; ++sk){
+ rv = sd_is_socket_inet(sk, family, type, -1, 53);
+ if(rv > 0){
+ DBG("socket fd (%d) is passed by systemd", sk);
+ is_socket_inet = 1;
+ break;
+ }
+ }
+
+ if (!is_socket_inet) {
+ DBG("socket fd is not matched what connman requests");
+ return NULL;
+ }
+#else
sk = socket(family, type, protocol);
if (sk < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
connman_error("No IPv6 support");
return NULL;
}
+ /* ConnMan listens DNS from multiple interfaces
+ * E.g. various technology based and tethering interfaces
+ */
interface = connman_inet_ifname(index);
if (!interface || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
interface,
s.sin.sin_family = AF_INET;
s.sin.sin_port = htons(53);
slen = sizeof(s.sin);
-
if (__connman_inet_get_interface_address(index,
AF_INET,
&s.sin.sin_addr) < 0) {
close(sk);
return NULL;
}
-
+#endif
+#if defined TIZEN_EXT
+ /* When ConnMan crashed,
+ * probably DNS listener cannot bind existing address */
+ option = 1;
+ setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
+#endif
+#if !defined TIZEN_EXT
if (bind(sk, &s.sa, slen) < 0) {
connman_error("Failed to bind %s listener socket", proto);
close(sk);
return NULL;
}
+#endif
if (protocol == IPPROTO_TCP) {
-
+#if !defined TIZEN_EXT
if (listen(sk, 10) < 0) {
connman_error("Failed to listen on TCP socket %d/%s",
-errno, strerror(errno));
close(sk);
return NULL;
}
-
+#endif
fcntl(sk, F_SETFL, O_NONBLOCK);
}
ifdata->tcp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
if (ifdata->tcp4_listener_channel)
+#if defined TIZEN_EXT
+ ifdata->tcp4_listener_watch =
+ g_io_add_watch(ifdata->tcp4_listener_channel,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ tcp4_listener_event, (gpointer)ifdata);
+#else
ifdata->tcp4_listener_watch =
g_io_add_watch(ifdata->tcp4_listener_channel,
G_IO_IN, tcp4_listener_event,
(gpointer)ifdata);
+#endif
else
ret |= TCP_IPv4_FAILED;
ifdata->tcp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
if (ifdata->tcp6_listener_channel)
+#if defined TIZEN_EXT
+ ifdata->tcp6_listener_watch =
+ g_io_add_watch(ifdata->tcp6_listener_channel,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ tcp6_listener_event, (gpointer)ifdata);
+#else
ifdata->tcp6_listener_watch =
g_io_add_watch(ifdata->tcp6_listener_channel,
G_IO_IN, tcp6_listener_event,
(gpointer)ifdata);
+#endif
else
ret |= TCP_IPv6_FAILED;
} else {
ifdata->udp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
if (ifdata->udp4_listener_channel)
+#if defined TIZEN_EXT
+ ifdata->udp4_listener_watch =
+ g_io_add_watch(ifdata->udp4_listener_channel,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ udp4_listener_event, (gpointer)ifdata);
+#else
ifdata->udp4_listener_watch =
g_io_add_watch(ifdata->udp4_listener_channel,
G_IO_IN, udp4_listener_event,
(gpointer)ifdata);
+#endif
else
ret |= UDP_IPv4_FAILED;
ifdata->udp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
if (ifdata->udp6_listener_channel)
+#if defined TIZEN_EXT
+ ifdata->udp6_listener_watch =
+ g_io_add_watch(ifdata->udp6_listener_channel,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ udp6_listener_event, (gpointer)ifdata);
+#else
ifdata->udp6_listener_watch =
g_io_add_watch(ifdata->udp6_listener_channel,
G_IO_IN, udp6_listener_event,
(gpointer)ifdata);
+#endif
else
ret |= UDP_IPv6_FAILED;
}
for (list = request_list; list; list = list->next) {
struct request_data *req = list->data;
- DBG("Dropping request (id 0x%04x -> 0x%04x)",
+ debug("Dropping request (id 0x%04x -> 0x%04x)",
req->srcid, req->dstid);
destroy_request_data(req);
list->data = NULL;
return err;
}
+#if defined TIZEN_EXT
+void connman_inet_update_device_ident(struct connman_device *device)
+{
+ int index;
+ enum connman_device_type type;
+ char *ident = NULL, *addr = NULL;
+
+ index = connman_device_get_index(device);
+ type = connman_device_get_type(device);
+
+ switch (type) {
+ case CONNMAN_DEVICE_TYPE_UNKNOWN:
+ return;
+ case CONNMAN_DEVICE_TYPE_ETHERNET:
+ case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ addr = index2addr(index);
+ break;
+ case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+ case CONNMAN_DEVICE_TYPE_CELLULAR:
+ case CONNMAN_DEVICE_TYPE_GPS:
+ case CONNMAN_DEVICE_TYPE_VENDOR:
+ break;
+ }
+
+ switch (type) {
+ case CONNMAN_DEVICE_TYPE_VENDOR:
+ case CONNMAN_DEVICE_TYPE_GPS:
+ break;
+ case CONNMAN_DEVICE_TYPE_ETHERNET:
+ case CONNMAN_DEVICE_TYPE_GADGET:
+ ident = index2ident(index, NULL);
+ break;
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ ident = index2ident(index, NULL);
+ break;
+ case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+ break;
+ case CONNMAN_DEVICE_TYPE_CELLULAR:
+ ident = index2ident(index, NULL);
+ break;
+ }
+
+ if (ident != NULL) {
+ connman_device_set_ident(device, ident);
+ g_free(ident);
+ }
+
+ if (addr != NULL) {
+ connman_device_set_string(device, "Address", addr);
+ g_free(addr);
+ }
+}
+#endif
+
struct in6_ifreq {
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
return FALSE;
}
- static int icmpv6_recv(int fd, gpointer user_data)
+ static int icmpv6_recv(int fd, struct xs_cb_data *data)
{
struct msghdr mhdr;
struct iovec iov;
unsigned char chdr[CMSG_BUF_LEN];
unsigned char buf[1540];
- struct xs_cb_data *data = user_data;
struct nd_router_advert *hdr;
struct sockaddr_in6 saddr;
ssize_t len;
len = recvmsg(fd, &mhdr, 0);
if (len < 0) {
cb(NULL, 0, data->user_data);
- xs_cleanup(data);
return -errno;
}
+#if defined TIZEN_EXT
+ /* Set Received Source Address from router as IPv6 Gateway Address */
+ char src_addr[INET6_ADDRSTRLEN];
+ if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
+ == NULL) {
+ xs_cleanup(data);
+ return -errno;
+ }
+ DBG("Received Source Address %s from router", src_addr);
+
+ /* icmpv6_recv() function can be called in two scenarios :
+ * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
+ * 2. When __connman_inet_ipv6_send_rs() is called from
+ * __connman_6to4_probe()
+ * In the second case it is not required to set DHCPv6 Gateway Address
+ * as DHCPv6 was not started and network structure was not passed as
+ * user_data. If it is tried to add Source Address as Gateway Address
+ * then it will lead to crash because of user_data being ip_address
+ * instead of network structure. So Adding Gateway Address in case 1st
+ * case only.
+ */
+ char *address = data->user_data;
+ int err = 0;
+ unsigned char buffer[sizeof(struct in6_addr)] = {0, };
+ /* Checking if user_data is an ip_address */
+ err = inet_pton(AF_INET, address, buffer);
+ /* Setting Received Source Address from
+ * router as Gateway Address */
+ if(err <= 0)
+ __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
+#endif
hdr = (struct nd_router_advert *)buf;
DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
sizeof(struct nd_router_advert));
return 0;
cb(hdr, len, data->user_data);
- xs_cleanup(data);
return len;
}
static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
int fd, ret;
+ struct xs_cb_data *xs_data = data;
DBG("");
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
+ goto cleanup;
fd = g_io_channel_unix_get_fd(chan);
- ret = icmpv6_recv(fd, data);
+ ret = icmpv6_recv(fd, xs_data);
if (ret == 0)
return TRUE;
- return FALSE;
+ cleanup:
+ xs_cleanup(xs_data);
+ return TRUE;
}
/* Adapted from RFC 1071 "C" Implementation Example */
char cbuf[CMSG_SPACE(sizeof(*pinfo))];
struct iovec iov[2];
int fd, datalen, ret, iovlen = 1;
+#if defined TIZEN_EXT
+ char ebuf[256];
+#endif
DBG("");
msgh.msg_controllen = cmsg->cmsg_len;
ret = sendmsg(fd, &msgh, 0);
+#if defined TIZEN_EXT
+ DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
+#endif
close(fd);
return ret;
xs_cleanup(context);
}
- static int icmpv6_rs_recv(int fd, gpointer user_data)
+ static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
{
struct msghdr mhdr;
struct iovec iov;
unsigned char chdr[CMSG_BUF_LEN];
unsigned char buf[1540];
- struct xs_cb_data *data = user_data;
struct nd_router_solicit *hdr;
struct sockaddr_in6 saddr;
ssize_t len;
gpointer data)
{
int fd, ret;
+ struct xs_cb_data *xs_data = data;
DBG("");
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
+ goto cleanup;
fd = g_io_channel_unix_get_fd(chan);
- ret = icmpv6_rs_recv(fd, data);
+ ret = icmpv6_rs_recv(fd, xs_data);
if (ret == 0)
return TRUE;
+ cleanup:
+ xs_data->watch_id = 0;
return FALSE;
}
return FALSE;
}
- static int icmpv6_nd_recv(int fd, gpointer user_data)
+ static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
{
struct msghdr mhdr;
struct iovec iov;
unsigned char chdr[CMSG_BUF_LEN];
unsigned char buf[1540];
- struct xs_cb_data *data = user_data;
struct nd_neighbor_advert *hdr;
struct sockaddr_in6 saddr;
ssize_t len;
len = recvmsg(fd, &mhdr, 0);
if (len < 0) {
cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
- xs_cleanup(data);
return -errno;
}
return 0;
cb(hdr, len, &data->addr.sin6_addr, data->user_data);
- xs_cleanup(data);
return len;
}
gpointer data)
{
int fd, ret;
+ struct xs_cb_data *xs_data = data;
DBG("");
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
+ goto cleanup;
fd = g_io_channel_unix_get_fd(chan);
- ret = icmpv6_nd_recv(fd, data);
+ ret = icmpv6_nd_recv(fd, xs_data);
if (ret == 0)
return TRUE;
- return FALSE;
+ cleanup:
+ xs_cleanup(xs_data);
+ return TRUE;
}
int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
return FALSE;
}
- static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
+ static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
{
- struct inet_rtnl_cb_data *rtnl_data = user_data;
struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
struct nlmsghdr *h = NULL;
struct sockaddr_nl nladdr;
gpointer user_data)
{
int ret;
+ struct inet_rtnl_cb_data *rtnl_data = user_data;
DBG("");
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
+ goto cleanup;
- ret = inet_rtnl_recv(chan, user_data);
- if (ret != 0)
+ ret = inet_rtnl_recv(chan, rtnl_data);
+ if (ret == 0)
return TRUE;
- return FALSE;
+ cleanup:
+ inet_rtnl_cleanup(rtnl_data);
+ return TRUE;
}
int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
{
struct sockaddr_nl nladdr;
struct inet_rtnl_cb_data *data;
- unsigned seq;
int err;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
- n->nlmsg_seq = seq = ++rtnl->seq;
+ n->nlmsg_seq = ++rtnl->seq;
if (callback) {
data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
inet_rtnl_timeout_cb, data);
data->channel = g_io_channel_unix_new(rtnl->fd);
- g_io_channel_set_close_on_unref(data->channel, TRUE);
g_io_channel_set_encoding(data->channel, NULL, NULL);
g_io_channel_set_buffered(data->channel, FALSE);
g_free(ifr);
- if (count < numif) {
+ if (count < numif)
+ {
char **prev_result = result;
result = g_try_realloc(result, (count + 1) * sizeof(char *));
if (!result) {
g_free(prev_result);
- goto error;
+ return NULL;
}
}
close(sk);
return ret;
}
+
+ static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
+ struct in_addr *addr)
+ {
+ char *s, *nfsargs;
+ size_t len;
+ char addrstr[INET_ADDRSTRLEN];
+ struct in_addr taddr;
+ GError *error = NULL;
+ char *cmdline = NULL;
+ char *pnp = NULL;
+ char **args = NULL;
+ char **pnpent = NULL;
+ char **pp = NULL;
+ int err = -1;
+
+ if (!cmdline_file)
+ cmdline_file = "/proc/cmdline";
+ if (!pnp_file)
+ pnp_file = "/proc/net/pnp";
+ if (!addr)
+ addr = &taddr;
+ addr->s_addr = INADDR_NONE;
+
+ if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
+ connman_error("%s: Cannot read %s %s\n", __func__,
+ cmdline_file, error->message);
+ goto out;
+ }
+
+ if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
+ if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
+ connman_error("%s: Cannot read %s %s\n", __func__,
+ pnp_file, error->message);
+ goto out;
+ }
+ } else {
+ connman_error("%s: File %s doesn't exist\n", __func__, pnp_file);
+ goto out;
+ }
+
+ len = strlen(cmdline);
+ if (len <= 1) {
+ /* too short */
+ goto out;
+ }
+ /* remove newline */
+ if (cmdline[len - 1] == '\n')
+ cmdline[--len] = '\0';
+
+ /* split in arguments (seperated by space) */
+ args = g_strsplit(cmdline, " ", 0);
+ if (!args) {
+ connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
+ cmdline);
+ goto out;
+ }
+
+ /* split in entries (by newlines) */
+ pnpent = g_strsplit(pnp, "\n", 0);
+ if (!pnpent) {
+ connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
+ pnp_file);
+ goto out;
+ }
+
+ /* first find root argument */
+ for (pp = args; *pp; pp++) {
+ if (!strcmp(*pp, "root=/dev/nfs"))
+ break;
+ }
+ /* no rootnfs found */
+ if (!*pp)
+ goto out;
+
+ /* locate nfsroot argument */
+ for (pp = args; *pp; pp++) {
+ if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
+ break;
+ }
+ /* no nfsroot argument found */
+ if (!*pp)
+ goto out;
+
+ /* determine if nfsroot server is provided */
+ nfsargs = strchr(*pp, '=');
+ if (!nfsargs)
+ goto out;
+ nfsargs++;
+
+ /* find whether serverip is present */
+ s = strchr(nfsargs, ':');
+ if (s) {
+ len = s - nfsargs;
+ s = nfsargs;
+ } else {
+ /* no serverip, use bootserver */
+ for (pp = pnpent; *pp; pp++) {
+ if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
+ break;
+ }
+ /* no bootserver found */
+ if (!*pp)
+ goto out;
+ s = *pp + strlen("bootserver ");
+ len = strlen(s);
+ }
+
+ /* copy to addr string buffer */
+ if (len >= sizeof(addrstr)) {
+ connman_error("%s: Bad server\n", __func__);
+ goto out;
+ }
+ memcpy(addrstr, s, len);
+ addrstr[len] = '\0';
+
+ err = inet_pton(AF_INET, addrstr, addr);
+ if (err <= 0) {
+ connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
+ __func__, addrstr);
+ err = -1;
+ goto out;
+ }
+
+ /* all done */
+ err = 0;
+ out:
+ g_strfreev(pnpent);
+ g_strfreev(args);
+ if (error)
+ g_error_free(error);
+ g_free(pnp);
+ g_free(cmdline);
+
+ return err;
+ }
+
+ /* get interface out of which peer is reachable (IPv4 only) */
+ static int get_peer_iface(struct in_addr *addr, char *ifname)
+ {
+ struct ifaddrs *ifaddr, *ifa;
+ struct sockaddr_in saddr, *ifsaddr;
+ socklen_t socklen;
+ int s;
+ int err = -1;
+
+ /* Obtain address(es) matching host/port */
+ err = getifaddrs(&ifaddr);
+ if (err < 0) {
+ connman_error("%s: getifaddrs() failed %d (%s)\n",
+ __func__, errno, strerror(errno));
+ return -1;
+ }
+
+ s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0) {
+ connman_error("%s: socket() failed %d (%s)\n",
+ __func__, errno, strerror(errno));
+ return -1;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0; /* any port */
+ saddr.sin_addr = *addr;
+
+ /* no need to bind, connect will select iface */
+ err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
+ if (err < 0) {
+ connman_error("%s: connect() failed: %d (%s)\n",
+ __func__, errno, strerror(errno));
+ goto out;
+ }
+
+ socklen = sizeof(saddr);
+ err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
+ if (err < 0) {
+ connman_error("%s: getsockname() failed: %d (%s)\n",
+ __func__, errno, strerror(errno));
+ goto out;
+ }
+
+ err = -1;
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr)
+ continue;
+
+ /* only IPv4 address */
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
+
+ /* match address? */
+ if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
+ break;
+ }
+
+ if (ifa) {
+ err = 0;
+ if (ifname)
+ strcpy(ifname, ifa->ifa_name);
+ }
+
+ out:
+ close(s);
+
+ freeifaddrs(ifaddr);
+
+ return err;
+ }
+
+ bool __connman_inet_isrootnfs_device(const char *devname)
+ {
+ struct in_addr addr;
+ char ifname[IFNAMSIZ];
+
+ return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
+ get_peer_iface(&addr, ifname) == 0 &&
+ strcmp(devname, ifname) == 0;
+ }
+
+ char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
+ {
+ char **pp;
+ char *s;
+ int pass, count;
+ GError *error = NULL;
+ char *pnp = NULL;
+ char **pnpent = NULL;
+ char **nameservers = NULL;
+
+ if (!pnp_file)
+ pnp_file = "/proc/net/pnp";
+
+ if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
+ connman_error("%s: Cannot read %s %s\n", __func__,
+ pnp_file, error->message);
+ goto out;
+ }
+
+ /* split in entries (by newlines) */
+ pnpent = g_strsplit(pnp, "\n", 0);
+ if (!pnpent) {
+ connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
+ pnp_file);
+ goto out;
+ }
+
+ /*
+ * Perform two passes to retreive a char ** array of
+ * nameservers that are not 0.0.0.0
+ *
+ * The first pass counts them, the second fills in the
+ * array.
+ */
+ count = 0;
+ nameservers = NULL;
+ for (pass = 1; pass <= 2; pass++) {
+
+ /* at the start of the second pass allocate */
+ if (pass == 2)
+ nameservers = g_new(char *, count + 1);
+
+ count = 0;
+ for (pp = pnpent; *pp; pp++) {
+ /* match 'nameserver ' at the start of each line */
+ if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
+ continue;
+
+ /* compare it against 0.0.0.0 */
+ s = *pp + strlen("nameserver ");
+ if (!strcmp(s, "0.0.0.0"))
+ continue;
+
+ /* on second pass fill in array */
+ if (pass == 2)
+ nameservers[count] = g_strdup(s);
+ count++;
+ }
+
+ /* no nameservers? */
+ if (count == 0)
+ goto out;
+
+ /* and terminate char ** array with NULL */
+ if (pass == 2)
+ nameservers[count] = NULL;
+
+ }
+
+ out:
+ g_strfreev(pnpent);
+ g_free(pnp);
+ if (error)
+ g_error_free(error);
+
+ return nameservers;
+ }
const struct connman_ipconfig_ops *ops;
void *ops_data;
- bool enabled;
enum connman_ipconfig_method method;
struct connman_ipaddress *address;
struct connman_ipaddress *system;
+#if defined TIZEN_EXT
+ int dhcp_lease_duration;
+#endif
+
int ipv6_privacy_config;
char *last_dhcp_address;
char **last_dhcpv6_prefixes;
g_free(ipdevice);
}
- static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
- {
- DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
- ipdevice->config_ipv6);
- #if defined TIZEN_EXT
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->enabled == TRUE)
- return;
-
- char *ifname = connman_inet_ifname(ipdevice->index);
-
- if (__connman_device_isfiltered(ifname) == FALSE) {
- ipdevice->ipv6_enabled = get_ipv6_state(ifname);
- set_ipv6_state(ifname, FALSE);
- }
- g_free(ifname);
- #endif
- }
-
- static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
- {
- DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
- ipdevice->config_ipv6);
-
- if (ipdevice->config_ipv4)
- connman_inet_clear_address(ipdevice->index,
- ipdevice->config_ipv4->address);
-
- if (ipdevice->config_ipv6)
- connman_inet_clear_ipv6_address(ipdevice->index,
- ipdevice->config_ipv6->address->local,
- ipdevice->config_ipv6->address->prefixlen);
- }
-
static void update_stats(struct connman_ipdevice *ipdevice,
const char *ifname, struct rtnl_link_stats *stats)
{
index, type, type2str(type));
update:
+#if defined TIZEN_EXT
+ if (g_strcmp0(ipdevice->address, address) != 0) {
+ /* If an original address is built-in physical device,
+ * it's hardly get an address at a initial creation
+ */
+ g_free(ipdevice->address);
+ ipdevice->address = g_strdup(address);
+ }
+#endif
+
ipdevice->mtu = mtu;
update_stats(ipdevice, ifname, stats);
g_list_free(ipconfig_copy);
- if (lower_up)
- __connman_ipconfig_lower_up(ipdevice);
- if (lower_down)
- __connman_ipconfig_lower_down(ipdevice);
-
out:
g_free(ifname);
}
g_free(ifname);
- __connman_ipconfig_lower_down(ipdevice);
-
g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
}
ipconfig->address->gateway = g_strdup(gateway);
}
+#if defined TIZEN_EXT
+void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig,
+ int dhcp_lease_duration)
+{
+ ipconfig->dhcp_lease_duration = dhcp_lease_duration;
+}
+#endif
+
+#if defined TIZEN_EXT
+int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service)
+#else
int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
+#endif
{
+#if !defined TIZEN_EXT
struct connman_service *service;
+#endif
DBG("");
if (!ipconfig->address)
return -EINVAL;
+#if !defined TIZEN_EXT
service = __connman_service_lookup_from_index(ipconfig->index);
+#endif
if (!service)
return -EINVAL;
struct connman_ipconfig *ipv6config;
struct connman_ipdevice *ipdevice;
- DBG("index %d", index);
-
ipv6config = g_try_new0(struct connman_ipconfig, 1);
if (!ipv6config)
return NULL;
ipv6config->refcount = 1;
ipv6config->index = index;
- ipv6config->enabled = false;
ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
if (!is_ipv6_supported)
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
if (ipdevice)
+#if !defined TIZEN_EXT
ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
-
+#else
+ ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy = 2;
+#endif
ipv6config->address = connman_ipaddress_alloc(AF_INET6);
if (!ipv6config->address) {
g_free(ipv6config);
ipv6config->system = connman_ipaddress_alloc(AF_INET6);
- DBG("ipconfig %p method %s", ipv6config,
+ DBG("ipconfig %p index %d method %s", ipv6config, index,
__connman_ipconfig_method2string(ipv6config->method));
return ipv6config;
if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
return create_ipv6config(index);
- DBG("index %d", index);
-
ipconfig = g_try_new0(struct connman_ipconfig, 1);
if (!ipconfig)
return NULL;
ipconfig->refcount = 1;
ipconfig->index = index;
- ipconfig->enabled = false;
ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
ipconfig->address = connman_ipaddress_alloc(AF_INET);
ipconfig->system = connman_ipaddress_alloc(AF_INET);
- DBG("ipconfig %p", ipconfig);
+ DBG("ipconfig %p index %d", ipconfig, index);
return ipconfig;
}
int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
{
- DBG("");
-
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
{
int err;
- DBG("");
-
if (!ipconfig)
return 0;
- DBG("method %d", ipconfig->method);
-
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
{
int err;
- DBG("");
-
if (!ipconfig)
return 0;
+#if defined TIZEN_EXT
+ DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type);
+#else
+ DBG("method %d", ipconfig->method);
+#endif
+
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
{
struct connman_ipdevice *ipdevice;
- DBG("ipconfig %p", ipconfig);
-
if (!ipconfig || ipconfig->index < 0)
return -ENODEV;
{
struct connman_ipdevice *ipdevice;
- DBG("ipconfig %p", ipconfig);
-
if (!ipconfig || ipconfig->index < 0)
return NULL;
} else
return -EINVAL;
- ipconfig->enabled = true;
-
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
ipdevice->config_ipv4) {
ipconfig_list = g_list_remove(ipconfig_list,
if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
return -EINVAL;
- ipconfig->enabled = false;
-
if (ipdevice->config_ipv4 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
if (ipdevice->config_ipv6 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+#if defined TIZEN_EXT
+ if (ipdevice->config_ipv6->method ==
+ CONNMAN_IPCONFIG_METHOD_AUTO)
+ disable_ipv6(ipdevice->config_ipv6);
+#endif
connman_ipaddress_clear(ipdevice->config_ipv6->system);
__connman_ipconfig_unref(ipdevice->config_ipv6);
ipdevice->config_ipv6 = NULL;
if (!ipconfig)
return -EINVAL;
- DBG("ipconfig %p privacy %s", ipconfig, value);
-
privacy = string2privacy(value);
ipconfig->ipv6_privacy_config = privacy;
{
struct connman_ipaddress *append_addr = NULL;
const char *str;
- #if defined TIZEN_EXT
- DBG("");
- #endif
if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
return;
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
return;
case CONNMAN_IPCONFIG_METHOD_FIXED:
append_addr = ipconfig->address;
break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
case CONNMAN_IPCONFIG_METHOD_DHCP:
append_addr = ipconfig->system;
+#if defined TIZEN_EXT
+ /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
+ if (append_addr && append_addr->local == NULL)
+ append_addr = ipconfig->address;
+#endif
break;
}
if (append_addr->gateway)
connman_dbus_dict_append_basic(iter, "Gateway",
DBUS_TYPE_STRING, &append_addr->gateway);
+
+#if defined TIZEN_EXT
+ if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
+ char *server_ip;
+ server_ip = __connman_dhcp_get_server_address(ipconfig);
+ if (server_ip) {
+ connman_dbus_dict_append_basic(iter, "DHCPServerIP",
+ DBUS_TYPE_STRING, &server_ip);
+ g_free(server_ip);
+ }
+ connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
+ DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
+ }
+#endif
}
void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
{
struct connman_ipaddress *append_addr = NULL;
const char *str, *privacy;
- #if defined TIZEN_EXT
- DBG("");
- #endif
if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
return;
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_AUTO:
append_addr = ipconfig->system;
+#if defined TIZEN_EXT
+ /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
+ if (append_addr && append_addr->local == NULL)
+ append_addr = ipconfig->address;
+#endif
break;
}
DBusMessageIter *iter)
{
const char *str, *privacy;
- #if !defined TIZEN_EXT
- DBG("");
- #endif
str = __connman_ipconfig_method2string(ipconfig->method);
if (!str)
DBusMessageIter *iter)
{
const char *str;
- #if !defined TIZEN_EXT
- DBG("");
- #endif
str = __connman_ipconfig_method2string(ipconfig->method);
if (!str)
DBusMessageIter dict;
int type = -1;
- DBG("ipconfig %p", ipconfig);
-
if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
return -EINVAL;
case CONNMAN_IPCONFIG_METHOD_OFF:
ipconfig->method = method;
-
+#if defined TIZEN_EXT
+ if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ disable_ipv6(ipconfig);
+#endif
break;
case CONNMAN_IPCONFIG_METHOD_AUTO:
ipconfig->method = method;
if (privacy_string)
ipconfig->ipv6_privacy_config = privacy;
-
+#if defined TIZEN_EXT
+ enable_ipv6(ipconfig);
+#endif
break;
case CONNMAN_IPCONFIG_METHOD_MANUAL:
g_free(key);
break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+
+ if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
+ break;
+
+ /*
+ * If the last used method for IPv4 was AUTO then we
+ * try first DHCP. We will try also to use the last
+ * used DHCP address, if exits.
+ */
+ __connman_ipconfig_set_method(ipconfig,
+ CONNMAN_IPCONFIG_METHOD_DHCP);
+ /* fall through */
+
case CONNMAN_IPCONFIG_METHOD_DHCP:
key = g_strdup_printf("%sDHCP.LastAddress", prefix);
g_free(key);
break;
-
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- break;
}
return 0;
if (ipconfig->address->gateway)
g_key_file_set_string(keyfile, identifier,
key, ipconfig->address->gateway);
+ else
+ g_key_file_remove_key(keyfile, identifier, key, NULL);
g_free(key);
return 0;
};
GSList *allocated_blocks;
- GHashTable *pool_hash;
static uint32_t last_block;
static uint32_t block_16_bits;
if (__sync_fetch_and_sub(&pool->refcount, 1) != 1)
return;
- g_hash_table_remove(pool_hash, pool);
+ if (pool->info) {
+ allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
+ g_free(pool->info);
+ }
+
+ g_free(pool->gateway);
+ g_free(pool->broadcast);
+ g_free(pool->start_ip);
+ g_free(pool->end_ip);
+ g_free(pool->subnet_mask);
+
+ g_free(pool);
}
static char *get_ip(uint32_t ip)
* To only thing we have to make sure is that we terminated if
* there is no block left.
*/
- if (last_block == 0)
- block = block_16_bits;
+ if (last_block)
+ block = last_block;
else
- block = next_block(last_block);
+ block = block_16_bits;
do {
collision = false;
pool->end_ip = get_ip(block + start + range);
allocated_blocks = g_slist_prepend(allocated_blocks, info);
- g_hash_table_insert(pool_hash, pool, pool);
return pool;
}
return pool->subnet_mask;
}
- static void pool_free(gpointer data)
- {
- struct connman_ippool *pool = data;
-
- if (pool->info) {
- allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
- g_free(pool->info);
- }
-
- g_free(pool->gateway);
- g_free(pool->broadcast);
- g_free(pool->start_ip);
- g_free(pool->end_ip);
- g_free(pool->subnet_mask);
-
- g_free(pool);
- }
-
int __connman_ippool_init(void)
{
DBG("");
block_24_bits = ntohl(inet_addr("10.0.0.0"));
subnet_mask_24 = ntohl(inet_addr("255.255.255.0"));
- pool_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
- pool_free);
-
return 0;
}
{
DBG("");
- g_hash_table_destroy(pool_hash);
- pool_hash = NULL;
-
g_slist_free_full(allocated_blocks, g_free);
last_block = 0;
allocated_blocks = NULL;
#include <sys/errno.h>
#include <sys/socket.h>
#include <xtables.h>
+ #include <inttypes.h>
#include <linux/netfilter_ipv4/ip_tables.h>
struct connman_iptables_entry {
int offset;
int builtin;
+ int counter_idx;
struct ipt_entry *entry;
};
{
iterate_entries_cb_t cb = user_data;
- DBG("entry %p hook %d offset %d size %d", entry, hook,
- offset, entry->next_offset);
+ DBG("entry %p hook %u offset %u size %u packets %"PRIu64" bytes %"PRIu64,
+ entry, hook, offset, (unsigned int) entry->next_offset,
+ (uint64_t) entry->counters.pcnt, (uint64_t) entry->counters.bcnt);
return cb(entry, builtin, hook, size, offset, NULL);
}
static int iptables_add_entry(struct connman_iptables *table,
struct ipt_entry *entry, GList *before,
- int builtin)
+ int builtin, int counter_idx)
{
struct connman_iptables_entry *e, *entry_before;
e->entry = entry;
e->builtin = builtin;
+ e->counter_idx = counter_idx;
table->entries = g_list_insert_before(table->entries, before, e);
table->num_entries++;
error->t.u.user.target_size = ALIGN(sizeof(struct error_target));
g_stpcpy(error->error, name);
- if (iptables_add_entry(table, entry_head, last, -1) < 0)
+ if (iptables_add_entry(table, entry_head, last, -1, -1) < 0)
goto err_head;
/* tail entry */
ALIGN(sizeof(struct ipt_standard_target));
standard->verdict = XT_RETURN;
- if (iptables_add_entry(table, entry_return, last, -1) < 0)
+ if (iptables_add_entry(table, entry_return, last, -1, -1) < 0)
goto err;
return 0;
if (!new_entry)
return -EINVAL;
- ret = iptables_add_entry(table, new_entry, chain_tail->prev, builtin);
+ ret = iptables_add_entry(table, new_entry, chain_tail->prev, builtin, -1);
if (ret < 0)
g_free(new_entry);
if (builtin == -1)
chain_head = chain_head->next;
- ret = iptables_add_entry(table, new_entry, chain_head, builtin);
+ ret = iptables_add_entry(table, new_entry, chain_head, builtin, -1);
if (ret < 0)
g_free(new_entry);
target = ipt_get_target(entry->entry);
t = (struct xt_standard_target *)target;
+ if (t->verdict != verdict)
+ entry->counter_idx = -1;
t->verdict = verdict;
return 0;
return 0;
}
+ static int iptables_add_counters(struct connman_iptables *table,
+ struct xt_counters_info *c)
+ {
+ int err;
+
+ err = setsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_SET_ADD_COUNTERS, c,
+ sizeof(*c) + sizeof(struct xt_counters) * c->num_counters);
+ if (err < 0)
+ return -errno;
+
+ return 0;
+ }
+
static int add_entry(struct ipt_entry *entry, int builtin, unsigned int hook,
size_t size, unsigned offset, void *user_data)
{
memcpy(new_entry, entry, entry->next_offset);
- return iptables_add_entry(table, new_entry, NULL, builtin);
+ return iptables_add_entry(table, new_entry, NULL, builtin,
+ table->num_entries);
}
static void table_cleanup(struct connman_iptables *table)
struct xtables_target *xt_t;
GList *xt_m;
struct xtables_rule_match *xt_rm;
+ int proto;
};
static int prepare_getopt_args(const char *str, struct parse_context *ctx)
{
struct xtables_match *m;
struct xtables_rule_match *rm;
+ struct ipt_entry fw;
+
+ memset(&fw, 0, sizeof(fw));
+
+ /* The SNAT parser wants to know the protocol. */
+ if (ctx->proto == 0)
+ ctx->proto = IPPROTO_IP;
+ fw.ip.proto = ctx->proto;
for (rm = ctx->xt_rm; rm; rm = rm->next) {
if (rm->completed != 0)
+ XT_OPTION_OFFSET_SCALE)
continue;
- xtables_option_mpcall(c, ctx->argv, invert, m, NULL);
+ xtables_option_mpcall(c, ctx->argv, invert, m, &fw);
}
if (!ctx->xt_t)
+ XT_OPTION_OFFSET_SCALE)
return 0;
- xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, NULL);
+ xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, &fw);
return 0;
}
ctx->xt_m = g_list_append(ctx->xt_m, xt_m);
break;
+ case 'p':
+ ctx->proto = xtables_parse_protocol(optarg);
+ break;
case 'j':
/* Target */
ctx->xt_t = prepare_target(table, optarg);
struct connman_iptables *table;
struct ipt_replace *repl;
int err;
+ struct xt_counters_info *counters;
+ struct connman_iptables_entry *e;
+ GList *list;
+ unsigned int cnt;
DBG("%s", table_name);
return -EINVAL;
repl = iptables_blob(table);
- #if defined TIZEN_EXT
- if (!repl)
+ if(!repl)
return -ENOMEM;
- #endif
if (debug_enabled)
dump_ipt_replace(repl);
err = iptables_replace(table, repl);
- g_free(repl->counters);
- g_free(repl);
+ if (err < 0)
+ goto out_free;
+
+ counters = g_try_malloc0(sizeof(*counters) +
+ sizeof(struct xt_counters) * table->num_entries);
+ if (!counters) {
+ err = -ENOMEM;
+ goto out_hash_remove;
+ }
+ g_stpcpy(counters->name, table->info->name);
+ counters->num_counters = table->num_entries;
+ for (list = table->entries, cnt = 0; list; list = list->next, cnt++) {
+ e = list->data;
+ if (e->counter_idx >= 0)
+ counters->counters[cnt] = repl->counters[e->counter_idx];
+ }
+ err = iptables_add_counters(table, counters);
+ g_free(counters);
if (err < 0)
- return err;
+ goto out_hash_remove;
- g_hash_table_remove(table_hash, table_name);
+ err = 0;
- return 0;
+ out_hash_remove:
+ g_hash_table_remove(table_hash, table_name);
+ out_free:
+ g_free(repl->counters);
+ g_free(repl);
+ return err;
}
static void remove_table(gpointer user_data)
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
+#include <execinfo.h>
#include <dlfcn.h>
#include "connman.h"
static const char *program_exec;
static const char *program_path;
+#if defined TIZEN_EXT
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#define LOG_FILE_PATH "/opt/usr/data/network/connman.log"
+#define MAX_LOG_SIZE 1 * 1024 * 1024
+#define MAX_LOG_COUNT 1
+
+#define openlog __connman_log_open
+#define closelog __connman_log_close
+#define vsyslog __connman_log
+#define syslog __connman_log_s
+
+static FILE *log_file = NULL;
+
+void __connman_log_open(const char *ident, int option, int facility)
+{
+ if (!log_file)
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+}
+
+void __connman_log_close(void)
+{
+ fclose(log_file);
+ log_file = NULL;
+}
+
+static void __connman_log_update_file_revision(int rev)
+{
+ int next_log_rev = 0;
+ char *log_file = NULL;
+ char *next_log_file = NULL;
+
+ next_log_rev = rev + 1;
+
+ log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
+ next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev);
+
+ if (next_log_rev >= MAX_LOG_COUNT)
+ remove(next_log_file);
+
+ if (access(next_log_file, F_OK) == 0)
+ __connman_log_update_file_revision(next_log_rev);
+
+ if (rename(log_file, next_log_file) != 0)
+ remove(log_file);
+
+ g_free(log_file);
+ g_free(next_log_file);
+}
+
+static void __connman_log_make_backup(void)
+{
+ const int rev = 0;
+ char *backup = NULL;
+
+ backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
+
+ if (access(backup, F_OK) == 0)
+ __connman_log_update_file_revision(rev);
+
+ if (rename(LOG_FILE_PATH, backup) != 0)
+ remove(LOG_FILE_PATH);
+
+ g_free(backup);
+}
+
+static void __connman_log_get_local_time(char *strtime, const int size)
+{
+ struct timeval tv;
+ struct tm *local_ptm;
+ char buf[32];
+
+ gettimeofday(&tv, NULL);
+ local_ptm = localtime(&tv.tv_sec);
+
+ strftime(buf, sizeof(buf), "%m/%d %H:%M:%S", local_ptm);
+ snprintf(strtime, size, "%s.%03ld", buf, tv.tv_usec / 1000);
+}
+
+void __connman_log(const int log_priority, const char *format, va_list ap)
+{
+ int log_size = 0;
+ struct stat buf;
+ char str[256];
+ char strtime[40];
+
+ if (!log_file)
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+
+ if (!log_file)
+ return;
+
+ fstat(fileno(log_file), &buf);
+ log_size = buf.st_size;
+
+ if (log_size >= MAX_LOG_SIZE) {
+ fclose(log_file);
+ log_file = NULL;
+
+ __connman_log_make_backup();
+
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+
+ if (!log_file)
+ return;
+ }
+
+ __connman_log_get_local_time(strtime, sizeof(strtime));
+
+ if (vsnprintf(str, sizeof(str), format, ap) > 0)
+ fprintf(log_file, "%s %s\n", strtime, str);
+}
+
+void __connman_log_s(int log_priority, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vsyslog(LOG_DEBUG, format, ap);
+
+ va_end(ap);
+}
+#endif
+
/**
* connman_info:
* @format: format string
vsyslog(LOG_ERR, format, ap);
va_end(ap);
++ fflush(log_file);
}
/**
vsyslog(LOG_DEBUG, format, ap);
va_end(ap);
++ fflush(log_file);
+}
+
+static void print_backtrace(unsigned int offset)
+{
+ void *frames[99];
+ size_t n_ptrs;
+ unsigned int i;
+ int outfd[2], infd[2];
+ int pathlen;
+ pid_t pid;
+
+ if (!program_exec)
+ return;
+
+ pathlen = strlen(program_path);
+
+ n_ptrs = backtrace(frames, G_N_ELEMENTS(frames));
+ if (n_ptrs < offset)
+ return;
+
+ if (pipe(outfd) < 0)
+ return;
+
+ if (pipe(infd) < 0) {
+ close(outfd[0]);
+ close(outfd[1]);
+ return;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ close(outfd[0]);
+ close(outfd[1]);
+ close(infd[0]);
+ close(infd[1]);
+ return;
+ }
+
+ if (pid == 0) {
+ close(outfd[1]);
+ close(infd[0]);
+
+ dup2(outfd[0], STDIN_FILENO);
+ dup2(infd[1], STDOUT_FILENO);
+
+ execlp("addr2line", "-C", "-f", "-e", program_exec, NULL);
+
+ exit(EXIT_FAILURE);
+ }
+
+ close(outfd[0]);
+ close(infd[1]);
+
+ connman_error("++++++++ backtrace ++++++++");
+
+ for (i = offset; i < n_ptrs - 1; i++) {
+ Dl_info info;
+ char addr[20], buf[PATH_MAX * 2];
+ int len, written;
+ char *ptr, *pos;
+
+ dladdr(frames[i], &info);
+
+ len = snprintf(addr, sizeof(addr), "%p\n", frames[i]);
+ if (len < 0)
+ break;
+
+ written = write(outfd[1], addr, len);
+ if (written < 0)
+ break;
+
+ len = read(infd[0], buf, sizeof(buf) - 1);
+ if (len < 0)
+ break;
+
+ buf[len] = '\0';
+
+ pos = strchr(buf, '\n');
+ *pos++ = '\0';
+
+ if (strcmp(buf, "??") == 0) {
+ connman_error("#%-2u %p in %s", i - offset,
+ frames[i], info.dli_fname);
+ continue;
+ }
+
+ ptr = strchr(pos, '\n');
+ *ptr++ = '\0';
+
+ if (strncmp(pos, program_path, pathlen) == 0)
+ pos += pathlen + 1;
+
+ connman_error("#%-2u %p in %s() at %s", i - offset,
+ frames[i], buf, pos);
+ }
+
+ connman_error("+++++++++++++++++++++++++++");
+
+ kill(pid, SIGTERM);
+
+ close(outfd[1]);
+ close(infd[0]);
}
static void signal_handler(int signo)
{
connman_error("Aborting (signal %d) [%s]", signo, program_exec);
- print_backtrace(program_path, program_exec, 2);
+ print_backtrace(2);
exit(EXIT_FAILURE);
}
#include <string.h>
#include <signal.h>
#include <sys/signalfd.h>
+#include <sys/types.h>
+#include <sys/resource.h>
#include <getopt.h>
#include <sys/stat.h>
#include <net/if.h>
"vboxnet",
"virbr",
"ifb",
+ "ve-",
+ "vb-",
NULL
};
char **pref_timeservers;
unsigned int *auto_connect;
unsigned int *preferred_techs;
+ unsigned int *always_connected_techs;
char **fallback_nameservers;
unsigned int timeout_inputreq;
unsigned int timeout_browserlaunch;
char **tethering_technologies;
bool persistent_tethering_mode;
bool enable_6to4;
+ char *vendor_class_id;
+ bool enable_online_check;
+#if defined TIZEN_EXT
+ char **cellular_interfaces;
+ bool tizen_tv_extension;
+#endif
} connman_settings = {
.bg_scan = true,
.pref_timeservers = NULL,
.auto_connect = NULL,
.preferred_techs = NULL,
+ .always_connected_techs = NULL,
.fallback_nameservers = NULL,
.timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
.timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
.tethering_technologies = NULL,
.persistent_tethering_mode = false,
.enable_6to4 = false,
+ .vendor_class_id = NULL,
+ .enable_online_check = true,
+#if defined TIZEN_EXT
+ .cellular_interfaces = NULL,
+ .tizen_tv_extension = false,
+#endif
};
#define CONF_BG_SCAN "BackgroundScanning"
#define CONF_PREF_TIMESERVERS "FallbackTimeservers"
#define CONF_AUTO_CONNECT "DefaultAutoConnectTechnologies"
+ #define CONF_ALWAYS_CONNECTED_TECHS "AlwaysConnectedTechnologies"
#define CONF_PREFERRED_TECHS "PreferredTechnologies"
#define CONF_FALLBACK_NAMESERVERS "FallbackNameservers"
#define CONF_TIMEOUT_INPUTREQ "InputRequestTimeout"
#define CONF_TETHERING_TECHNOLOGIES "TetheringTechnologies"
#define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode"
#define CONF_ENABLE_6TO4 "Enable6to4"
+ #define CONF_VENDOR_CLASS_ID "VendorClassID"
+ #define CONF_ENABLE_ONLINE_CHECK "EnableOnlineCheck"
+#if defined TIZEN_EXT
+#define CONF_CELLULAR_INTERFACE "NetworkCellularInterfaceList"
+#define CONF_TIZEN_TV_EXT "TizenTVExtension"
+#endif
static const char *supported_options[] = {
CONF_BG_SCAN,
CONF_PREF_TIMESERVERS,
CONF_AUTO_CONNECT,
+ CONF_ALWAYS_CONNECTED_TECHS,
CONF_PREFERRED_TECHS,
CONF_FALLBACK_NAMESERVERS,
CONF_TIMEOUT_INPUTREQ,
CONF_TETHERING_TECHNOLOGIES,
CONF_PERSISTENT_TETHERING_MODE,
CONF_ENABLE_6TO4,
- CONF_VENDOR_CLASS_ID,
+ CONF_ENABLE_ONLINE_CHECK,
+#if defined TIZEN_EXT
+ CONF_CELLULAR_INTERFACE,
+ CONF_TIZEN_TV_EXT,
+#endif
NULL
};
g_strfreev(keys);
}
+#if defined TIZEN_EXT
+static void check_Tizen_configuration(GKeyFile *config)
+{
+ GError *error = NULL;
+ char **cellular_interfaces;
+ bool boolean;
+ gsize len;
+
+ cellular_interfaces = g_key_file_get_string_list(config, "General",
+ CONF_CELLULAR_INTERFACE, &len, &error);
+
+ if (error == NULL)
+ connman_settings.cellular_interfaces = cellular_interfaces;
+
+ g_clear_error(&error);
+
+ boolean = __connman_config_get_bool(config, "General",
+ CONF_TIZEN_TV_EXT, &error);
+ if (!error)
+ connman_settings.tizen_tv_extension = boolean;
+
+ g_clear_error(&error);
+}
+
+static void set_nofile_inc(void)
+{
+ int err;
+ struct rlimit rlim;
+
+ rlim.rlim_cur = 8192;
+ rlim.rlim_max = 8192;
+
+ err = setrlimit(RLIMIT_NOFILE, &rlim);
+ if (err)
+ DBG("fail to increase FILENO err(%d)", err);
+
+ return;
+}
+#endif
+
static void parse_config(GKeyFile *config)
{
GError *error = NULL;
char **interfaces;
char **str_list;
char **tethering;
+ char *vendor_class_id;
gsize len;
int timeout;
g_clear_error(&error);
str_list = __connman_config_get_string_list(config, "General",
+ CONF_ALWAYS_CONNECTED_TECHS, &len, &error);
+
+ if (!error)
+ connman_settings.always_connected_techs =
+ parse_service_types(str_list, len);
+
+ g_strfreev(str_list);
+
+ g_clear_error(&error);
+
+ str_list = __connman_config_get_string_list(config, "General",
CONF_FALLBACK_NAMESERVERS, &len, &error);
if (!error)
g_clear_error(&error);
+ vendor_class_id = __connman_config_get_string(config, "General",
+ CONF_VENDOR_CLASS_ID, &error);
+ if (!error)
+ connman_settings.vendor_class_id = vendor_class_id;
+
+ g_clear_error(&error);
+
+ boolean = __connman_config_get_bool(config, "General",
+ CONF_ENABLE_ONLINE_CHECK, &error);
+ if (!error) {
+ connman_settings.enable_online_check = boolean;
+ if (!boolean)
+ connman_info("Online check disabled by main config.");
+ }
+
+ g_clear_error(&error);
++
+#if defined TIZEN_EXT
+ check_Tizen_configuration(config);
+#endif
}
static int config_init(const char *file)
{
GKeyFile *config;
+#if defined TIZEN_EXT
+ set_nofile_inc();
+#endif
config = load_config(file);
check_config(config);
parse_config(config);
static bool parse_debug(const char *key, const char *value,
gpointer user_data, GError **error)
{
- if (value)
- option_debug = g_strdup(value);
- else
+ if (value) {
+ if (option_debug) {
+ char *prev = option_debug;
+
+ option_debug = g_strconcat(prev, ",", value, NULL);
+ g_free(prev);
+ } else {
+ option_debug = g_strdup(value);
+ }
+ } else {
+ g_free(option_debug);
option_debug = g_strdup("*");
+ }
+
+ return true;
+ }
+
+ static bool parse_noplugin(const char *key, const char *value,
+ gpointer user_data, GError **error)
+ {
+ if (option_noplugin) {
+ char *prev = option_noplugin;
+
+ option_noplugin = g_strconcat(prev, ",", value, NULL);
+ g_free(prev);
+ } else {
+ option_noplugin = g_strdup(value);
+ }
return true;
}
"Specify networking interface to ignore", "DEV" },
{ "plugin", 'p', 0, G_OPTION_ARG_STRING, &option_plugin,
"Specify plugins to load", "NAME,..." },
- { "noplugin", 'P', 0, G_OPTION_ARG_STRING, &option_noplugin,
+ { "noplugin", 'P', 0, G_OPTION_ARG_CALLBACK, &parse_noplugin,
"Specify plugins not to load", "NAME,..." },
{ "wifi", 'W', 0, G_OPTION_ARG_STRING, &option_wifi,
"Specify driver for WiFi/Supplicant", "NAME" },
const char *connman_option_get_string(const char *key)
{
+ if (g_str_equal(key, CONF_VENDOR_CLASS_ID))
+ return connman_settings.vendor_class_id;
+
if (g_strcmp0(key, "wifi") == 0) {
if (!option_wifi)
return "nl80211,wext";
if (g_str_equal(key, CONF_ENABLE_6TO4))
return connman_settings.enable_6to4;
+ if (g_str_equal(key, CONF_ENABLE_ONLINE_CHECK))
+ return connman_settings.enable_online_check;
+
return false;
}
if (g_str_equal(key, CONF_TETHERING_TECHNOLOGIES))
return connman_settings.tethering_technologies;
+#if defined TIZEN_EXT
+ if (g_str_equal(key, CONF_CELLULAR_INTERFACE))
+ return connman_settings.cellular_interfaces;
+#endif
+
return NULL;
}
if (g_str_equal(key, CONF_PREFERRED_TECHS))
return connman_settings.preferred_techs;
+ if (g_str_equal(key, CONF_ALWAYS_CONNECTED_TECHS))
+ return connman_settings.always_connected_techs;
+
return NULL;
}
__connman_device_init(option_device, option_nodevice);
__connman_ippool_init();
- __connman_iptables_init();
__connman_firewall_init();
__connman_nat_init();
__connman_tethering_init();
__connman_stats_init();
__connman_clock_init();
- __connman_resolver_init(option_dnsproxy);
__connman_ipconfig_init();
__connman_rtnl_init();
__connman_task_init();
__connman_plugin_init(option_plugin, option_noplugin);
+ __connman_resolver_init(option_dnsproxy);
__connman_rtnl_start();
__connman_dhcp_init();
__connman_dhcpv6_init();
__connman_wpad_init();
__connman_wispr_init();
+#if !defined TIZEN_EXT
__connman_rfkill_init();
__connman_machine_init();
+#endif
g_free(option_config);
g_free(option_device);
g_source_remove(signal);
+#if !defined TIZEN_EXT
__connman_machine_cleanup();
__connman_rfkill_cleanup();
+#endif
__connman_wispr_cleanup();
__connman_wpad_cleanup();
__connman_dhcpv6_cleanup();
__connman_tethering_cleanup();
__connman_nat_cleanup();
__connman_firewall_cleanup();
- __connman_iptables_cleanup();
__connman_peer_service_cleanup();
__connman_peer_cleanup();
__connman_ippool_cleanup();
# the scan list is empty. In that case, a simple backoff
# mechanism starting from 10s up to 5 minutes will run.
# BackgroundScanning = true
+BackgroundScanning = false
# List of Fallback timeservers separated by ",".
# These timeservers are used for NTP sync when there are
# These can contain mixed combination of fully qualified
# domain names, IPv4 and IPv6 addresses.
# FallbackTimeservers =
+#FallbackTimeservers = pool.ntp.org
# List of fallback nameservers separated by "," used if no
# nameservers are otherwise provided by the service. The
# the default route when compared to either a non-preferred
# type or a preferred type further down in the list.
# PreferredTechnologies =
+PreferredTechnologies = wifi, ethernet
# List of blacklisted network interfaces separated by ",".
# Found interfaces will be compared to the list and will
# not be handled by connman, if their first characters
# match any of the list entries. Default value is
- # vmnet,vboxnet,virbr,ifb.
- # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb
+ # vmnet,vboxnet,virbr,ifb,ve-,vb-.
+ # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb-
+NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w
# Allow connman to change the system hostname. This can
# happen for example if we receive DHCP hostname option.
# setting enabled applications will notice more network breaks than
# normal. Default value is false.
# SingleConnectedTechnology = false
+SingleConnectedTechnology = true
# List of technologies for which tethering is allowed separated by ",".
# The default value is wifi,bluetooth,gadget. Only those technologies
# section 4.1).
# Enable6to4 = false
+ # Enable use of http get as on online status check.
+ # When a service is in a READY state, and is selected as default,
+ # ConnMan will issue an HTTP GET request to verify that end-to-end
+ # connectivity is successful. Only then the service will be
+ # transitioned to ONLINE state.
+ # If this setting is false, the default service will remain in READY state.
+ # Default value is true.
+ # EnableOnlineCheck = false
+
+ # List of technologies with AutoConnect = true which are always connected
+ # regardless of PreferredTechnologies setting. Default value is empty and
+ # will connect a technology only if it is at a higher preference than any
+ # other which is already connected.
+ # This setting has no effect if SingleConnectedTechnologies is enabled.
+ # AlwaysConnectedTechnologies =
++
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
#endif
#include <errno.h>
- #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
#include "connman.h"
static int enable_ip_forward(bool enable)
{
- FILE *f;
+ static char value = 0;
+ int f, err = 0;
- f = fopen("/proc/sys/net/ipv4/ip_forward", "r+");
- if (!f)
+ if ((f = open("/proc/sys/net/ipv4/ip_forward", O_CLOEXEC | O_RDWR)) < 0)
return -errno;
- if (enable)
- fprintf(f, "1");
- else
- fprintf(f, "0");
+ if (!value) {
+ if (read(f, &value, sizeof(value)) < 0)
+ value = 0;
- fclose(f);
+ if (lseek(f, 0, SEEK_SET) < 0)
+ return -errno;
+ }
+
+ if (enable) {
+ char allow = '1';
+
+ if (write (f, &allow, sizeof(allow)) < 0)
+ err = -errno;
+ } else {
+ char deny = '0';
+
+ if (value)
+ deny = value;
+
+ if (write(f, &deny, sizeof(deny)) < 0)
+ err = -errno;
+
+ value = 0;
+ }
+
+ close(f);
- return 0;
+ return err;
}
static int enable_nat(struct connman_nat *nat)
{
- char *cmd;
- int err;
-
g_free(nat->interface);
nat->interface = g_strdup(default_interface);
if (!nat->interface)
return 0;
- /* Enable masquerading */
- cmd = g_strdup_printf("-s %s/%d -o %s -j MASQUERADE",
- nat->address,
- nat->prefixlen,
- nat->interface);
-
- err = __connman_firewall_add_rule(nat->fw, "nat",
- "POSTROUTING", cmd);
- g_free(cmd);
- if (err < 0)
- return err;
-
- return __connman_firewall_enable(nat->fw);
+ return __connman_firewall_enable_nat(nat->fw, nat->address,
+ nat->prefixlen, nat->interface);
}
static void disable_nat(struct connman_nat *nat)
if (!nat->interface)
return;
- /* Disable masquerading */
- __connman_firewall_disable(nat->fw);
+ __connman_firewall_disable_nat(nat->fw);
}
int __connman_nat_enable(const char *name, const char *address,
*/
#define RS_REFRESH_TIMEOUT 3
+#if defined TIZEN_EXT
+#define WIFI_ENCYPTION_MODE_LEN_MAX 6
+#define WIFI_BSSID_LEN_MAX 6
+#endif
+
+/*
+ * As per RFC 4861, a host should transmit up to MAX_RTR_SOLICITATIONS(3)
+ * Router Solicitation messages, each separated by at least
+ * RTR_SOLICITATION_INTERVAL(4) seconds to obtain RA for IPv6 auto-configuration.
+ */
+#define RTR_SOLICITATION_INTERVAL 4
+
static GSList *network_list = NULL;
static GSList *driver_list = NULL;
char *passphrase;
char *eap;
char *identity;
+ char *anonymous_identity;
char *agent_identity;
char *ca_cert_path;
+ char *subject_match;
+ char *altsubject_match;
+ char *domain_suffix_match;
+ char *domain_match;
char *client_cert_path;
char *private_key_path;
char *private_key_passphrase;
bool wps;
bool use_wps;
char *pin_wps;
- GSList *vsie_list;
+#if defined TIZEN_EXT
+ char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
+ unsigned char bssid[WIFI_BSSID_LEN_MAX];
+ unsigned int maxrate;
+ bool isHS20AP;
+ unsigned int keymgmt;
+ char *keymgmt_type;
+ bool rsn_mode;
+ int disconnect_reason;
+ int assoc_status_code;
++ void *wifi_vsie;
++ unsigned int wifi_vsie_len;
+#endif
} wifi;
+#if defined TIZEN_EXT
+ /* Multiple APN services and a default APN which a user selected */
+ bool default_internet;
+#endif
+
};
static const char *type2string(enum connman_network_type type)
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, false);
-
service = connman_service_lookup_from_network(network);
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_CONFIGURATION,
if (err < 0)
goto err;
+#if defined TIZEN_EXT
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
+#endif
if (err < 0)
goto err;
+ __connman_service_save(service);
+
return;
err:
network->connecting = false;
service = connman_service_lookup_from_network(network);
-
ipconfig = __connman_service_get_ip4config(service);
+ __connman_ipconfig_enable(ipconfig);
if (!__connman_ipconfig_get_local(ipconfig))
__connman_service_read_ip4config(service);
if (err < 0)
goto err;
+#if defined TIZEN_EXT
+ err = __connman_ipconfig_gateway_add(ipconfig, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig);
+#endif
if (err < 0)
goto err;
service = connman_service_lookup_from_network(network);
ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ __connman_ipconfig_enable(ipconfig_ipv4);
err = __connman_dhcp_start(ipconfig_ipv4, network,
dhcp_callback, NULL);
return err;
}
+#if defined TIZEN_EXT
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
+#endif
if (err < 0)
return err;
- __connman_connection_gateway_activate(service,
- CONNMAN_IPCONFIG_TYPE_IPV6);
-
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, false);
-
connman_network_set_associating(network, false);
network->connecting = false;
DBG("re-send router solicitation %d",
network->router_solicit_count);
network->router_solicit_count--;
- __connman_inet_ipv6_send_rs(network->index, 1,
+ __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL,
check_dhcpv6, network);
return;
}
+#if defined TIZEN_EXT
+ DBG("RA message is not received from server in reply of RS.");
+#endif
connman_network_unref(network);
return;
}
*/
if (!network->connected) {
connman_network_unref(network);
+#if defined TIZEN_EXT
+ DBG("Network is not connected");
+#endif
return;
}
* We do stateful/stateless DHCPv6 if router advertisement says so.
*/
if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
+#if defined TIZEN_EXT
+ DBG("IPv6 ND_RA_FLAG_MANAGED");
+#endif
__connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
} else {
if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
+#if defined TIZEN_EXT
+ {
+ DBG("IPv6 ND_RA_FLAG_OTHER");
+#endif
__connman_dhcpv6_start_info(network,
dhcpv6_info_callback);
+#if defined TIZEN_EXT
+ }
+#endif
g_slist_free_full(prefixes, g_free);
network->connecting = false;
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, false);
-
+#if defined TIZEN_EXT
+ if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
+ return;
+#endif
+
service = connman_service_lookup_from_network(network);
if (!service)
return;
if (!ipconfig)
return;
+ __connman_ipconfig_enable(ipconfig);
+
__connman_ipconfig_enable_ipv6(ipconfig);
__connman_ipconfig_address_remove(ipconfig);
/* Try to get stateless DHCPv6 information, RFC 3736 */
network->router_solicit_count = 3;
- __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network);
+ __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL,
+ check_dhcpv6, network);
}
static void set_connected(struct connman_network *network)
switch (ipv4_method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ /*
+ * If the current method is AUTO then next time we
+ * try first DHCP. DHCP also needs to be stopped
+ * in this case because if we fell in AUTO means
+ * that DHCP was launched for IPv4 but it failed.
+ */
+ __connman_ipconfig_set_method(ipconfig_ipv4,
+ CONNMAN_IPCONFIG_METHOD_DHCP);
+ __connman_service_notify_ipv4_configuration(service);
+ /* fall through */
case CONNMAN_IPCONFIG_METHOD_DHCP:
__connman_dhcp_stop(ipconfig_ipv4);
break;
CONNMAN_IPCONFIG_TYPE_IPV6);
if (network->connected) {
+#if defined TIZEN_EXT
+ /**
+ * Do not remove gateway and its address,
+ * if there are connected profiles that use same interface (multiple PDN)
+ */
+ if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR ||
+ __connman_service_get_connected_count_of_iface(service) <= 0) {
+#endif
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);
__connman_ipconfig_address_unset(ipconfig_ipv4);
__connman_ipconfig_address_unset(ipconfig_ipv6);
-
+#if defined TIZEN_EXT
+ }
+#endif
/*
* Special handling for IPv6 autoconfigured address.
* The simplest way to remove autoconfigured routes is to
}
}
- static void remove_driver(struct connman_network_driver *driver)
- {
- GSList *list;
-
- DBG("driver %p name %s", driver, driver->name);
-
- for (list = network_list; list; list = list->next) {
- struct connman_network *network = list->data;
-
- if (network->driver == driver)
- network_remove(network);
- }
- }
-
static gint compare_priority(gconstpointer a, gconstpointer b)
{
const struct connman_network_driver *driver1 = a;
*/
void connman_network_driver_unregister(struct connman_network_driver *driver)
{
+ GSList *list;
+
DBG("driver %p name %s", driver, driver->name);
driver_list = g_slist_remove(driver_list, driver);
- remove_driver(driver);
+ for (list = network_list; list; list = list->next) {
+ struct connman_network *network = list->data;
+
+ if (network->driver == driver)
+ network_remove(network);
+ }
}
static void network_destruct(struct connman_network *network)
g_free(network->wifi.passphrase);
g_free(network->wifi.eap);
g_free(network->wifi.identity);
+ g_free(network->wifi.anonymous_identity);
g_free(network->wifi.agent_identity);
g_free(network->wifi.ca_cert_path);
+ g_free(network->wifi.subject_match);
+ g_free(network->wifi.altsubject_match);
+ g_free(network->wifi.domain_suffix_match);
+ g_free(network->wifi.domain_match);
g_free(network->wifi.client_cert_path);
g_free(network->wifi.private_key_path);
g_free(network->wifi.private_key_passphrase);
g_free(network->wifi.phase2_auth);
g_free(network->wifi.pin_wps);
-
+#if defined TIZEN_EXT
- g_slist_free_full(network->wifi.vsie_list, g_free);
++ g_free(network->wifi.wifi_vsie);
+#endif
g_free(network->path);
g_free(network->group);
g_free(network->node);
struct connman_network *network;
char *ident;
- DBG("identifier %s type %d", identifier, type);
-
network = g_try_new0(struct connman_network, 1);
if (!network)
return NULL;
- DBG("network %p", network);
-
network->refcount = 1;
ident = g_strdup(identifier);
network_list = g_slist_prepend(network_list, network);
+ DBG("network %p identifier %s type %s", network, identifier,
+ type2string(type));
return network;
}
return false;
}
+#if defined TIZEN_EXT
+void connman_network_set_connecting(struct connman_network *network)
+{
+ DBG("set network connecting true");
+ network->connecting = TRUE;
+ return;
+}
+#endif
+
bool connman_network_get_connecting(struct connman_network *network)
{
return network->connecting;
int connman_network_set_available(struct connman_network *network,
bool available)
{
+#if !defined TIZEN_EXT
DBG("network %p available %d", network, available);
+#endif
if (network->available == available)
return -EALREADY;
return network->available;
}
+#if defined TIZEN_EXT
+void connman_network_clear_associating(struct connman_network *network)
+{
+ struct connman_service *service;
+ enum connman_service_state state;
+
+ DBG("network %p", network);
+
+ network->connecting = FALSE;
+ network->associating = FALSE;
+
+ service = connman_service_lookup_from_network(network);
+ if (!service)
+ return;
+
+ state = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ if (state != CONNMAN_SERVICE_STATE_IDLE &&
+ state != CONNMAN_SERVICE_STATE_FAILURE)
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+
+ state = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ if (state != CONNMAN_SERVICE_STATE_IDLE &&
+ state != CONNMAN_SERVICE_STATE_FAILURE)
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+}
+
+static gboolean __connman_network_clear_associating_delayed(gpointer user_data)
+{
+ GSList *list;
+ gboolean found = FALSE;
+ enum connman_service_state state_ipv4;
+ enum connman_service_state state_ipv6;
+ struct connman_service *service;
+ struct connman_network *network = (struct connman_network *)user_data;
+
+ for (list = network_list; list != NULL; list = list->next) {
+ struct connman_network *item = list->data;
+
+ if (item == network) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found != TRUE)
+ return FALSE;
+
+ DBG("network %p name %s", network, network->name);
+ service = connman_service_lookup_from_network(network);
+
+ state_ipv4 = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ state_ipv6 = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+
+ DBG("service %p state %d/%d", service, state_ipv4, state_ipv6);
+
+ if (network->associating == FALSE &&
+ state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION &&
+ state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) {
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ } else {
+ if (network->associating == FALSE) {
+ struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
+ enum connman_ipconfig_method ipv4_method, ipv6_method;
+
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
+ ipconfig_ipv6 = __connman_service_get_ip4config(service);
+ ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
+
+ if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
+ (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION))
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
+ (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION))
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ }
+ }
+
+ return FALSE;
+}
+#endif
+
/**
* connman_network_set_associating:
* @network: network structure
CONNMAN_IPCONFIG_TYPE_IPV6);
}
+#if defined TIZEN_EXT
+ if (associating == FALSE &&
+ connman_network_get_bool(network, "WiFi.UseWPS") == FALSE)
+ g_timeout_add_seconds(1,
+ __connman_network_clear_associating_delayed,
+ network);
+#endif
+
return 0;
}
service = connman_service_lookup_from_network(network);
+#if defined TIZEN_EXT
+ __connman_service_indicate_error(service,
+ CONNMAN_SERVICE_ERROR_AUTH_FAILED);
+#else
__connman_service_indicate_error(service,
CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
+#endif
}
static void set_configure_error(struct connman_network *network)
service = connman_service_lookup_from_network(network);
+#if defined TIZEN_EXT
+ if (service)
+ __connman_service_set_favorite(service, false);
+#endif
__connman_service_indicate_error(service,
CONNMAN_SERVICE_ERROR_INVALID_KEY);
}
CONNMAN_SERVICE_ERROR_BLOCKED);
}
+
+#if defined TIZEN_EXT
+static void set_dhcp_error(struct connman_network *network)
+{
+ struct connman_service *service;
+
+ if (network->associating != FALSE)
+ network->associating = FALSE;
+
+ service = connman_service_lookup_from_network(network);
+
+ __connman_service_indicate_error(service,
+ CONNMAN_SERVICE_ERROR_DHCP_FAILED);
+}
+#endif
+
void connman_network_set_ipv4_method(struct connman_network *network,
enum connman_ipconfig_method method)
{
case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
set_connect_error(network);
break;
+#if defined TIZEN_EXT
+ case CONNMAN_NETWORK_ERROR_DHCP_FAIL:
+ set_dhcp_error(network);
+ break;
+#endif
+
case CONNMAN_NETWORK_ERROR_BLOCKED:
set_blocked_error(network);
break;
+
}
__connman_network_disconnect(network);
network->connecting = true;
+#if defined TIZEN_EXT
+ if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
+#endif
__connman_device_disconnect(network->device);
-
+#if defined TIZEN_EXT
+ DBG("ConnMan, Connect Request [%s]", network->name);
+#endif
err = network->driver->connect(network);
if (err < 0) {
- if (err == -EINPROGRESS)
+ if (err == -EINPROGRESS) {
+#if defined TIZEN_EXT
+ if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
+#endif
connman_network_set_associating(network, true);
- else
+ } else
network->connecting = false;
return err;
return -EUNATCH;
network->connecting = false;
-
+#if defined TIZEN_EXT
+ DBG("ConnMan, Disconnect request");
+#endif
if (network->driver->disconnect)
err = network->driver->disconnect(network);
return 0;
}
+#if defined TIZEN_EXT
+void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data)
+{
+ DBG("");
+
+ struct connman_network *network = user_data;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig = NULL;
+
+ service = connman_service_lookup_from_network(network);
+ if (service == NULL)
+ return;
+
+ ipconfig = __connman_service_get_ipconfig(service, AF_INET6);
+ if (ipconfig == NULL)
+ return;
+
+ __connman_ipconfig_set_gateway(ipconfig, gateway);
+
+ return;
+}
+#endif
+
int __connman_network_enable_ipconfig(struct connman_network *network,
struct connman_ipconfig *ipconfig)
{
int r = 0;
enum connman_ipconfig_type type;
enum connman_ipconfig_method method;
+#if defined TIZEN_EXT
+ struct connman_service *service;
+#endif
if (!network || !ipconfig)
return -EINVAL;
break;
case CONNMAN_IPCONFIG_METHOD_AUTO:
+#if defined TIZEN_EXT
+ service = connman_service_lookup_from_network(network);
+
+ if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_CONFIGURATION,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#endif
autoconf_ipv6_set(network);
break;
return 0;
}
-
- int connman_network_set_assoc_status_code(struct connman_network *network,
- int assoc_status_code)
- {
-
- if (network == NULL)
- return 0;
-
- network->wifi.assoc_status_code = assoc_status_code;
- return 0;
- }
-
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+int connman_network_set_bssid(struct connman_network *network,
+ const unsigned char *bssid)
+{
+ int i = 0;
+
+ if (bssid == NULL)
+ return -EINVAL;
+
+ DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5]);
+
+ for (;i < WIFI_BSSID_LEN_MAX;i++)
+ network->wifi.bssid[i] = bssid[i];
+
+ return 0;
+}
+
+unsigned char *connman_network_get_bssid(struct connman_network *network)
+{
+ return (unsigned char *)network->wifi.bssid;
+}
+
+int connman_network_set_maxrate(struct connman_network *network,
+ unsigned int maxrate)
+{
+#if !defined TIZEN_EXT
+ DBG("network %p maxrate %d", network, maxrate);
+#endif
+
+ network->wifi.maxrate = maxrate;
+
+ return 0;
+}
+
+unsigned int connman_network_get_maxrate(struct connman_network *network)
+{
+ return network->wifi.maxrate;
+}
+
+int connman_network_set_enc_mode(struct connman_network *network,
+ const char *encryption_mode)
+{
+ if (encryption_mode == NULL)
+ return -EINVAL;
+
+ DBG("network %p encryption mode %s", network, encryption_mode);
+
+ g_strlcpy(network->wifi.encryption_mode, encryption_mode,
+ WIFI_ENCYPTION_MODE_LEN_MAX);
+
+ return 0;
+}
+
+const char *connman_network_get_enc_mode(struct connman_network *network)
+{
+ return (const char *)network->wifi.encryption_mode;
+}
+
+int connman_network_set_rsn_mode(struct connman_network *network,
+ bool rsn_mode)
+{
+ network->wifi.rsn_mode = rsn_mode;
+
+ return 0;
+}
+
+int connman_network_set_proxy(struct connman_network *network,
+ const char *proxies)
+{
+ struct connman_service *service;
+
+ DBG("network %p proxies %s", network, proxies);
+
+ service = connman_service_lookup_from_network(network);
+ if (service == NULL)
+ return -EINVAL;
+
+ __connman_service_set_proxy(service, proxies);
+
+ connman_service_set_proxy_method(service,
+ CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
+
+ return 0;
+}
+
+int connman_network_set_keymgmt(struct connman_network *network,
+ unsigned int keymgmt)
+{
+ if (network == NULL)
+ return 0;
+
+ network->wifi.keymgmt = keymgmt;
+
+ return 0;
+}
+
+unsigned int connman_network_get_keymgmt(struct connman_network *network)
+{
+ if (network == NULL)
+ return 0;
+
+ return network->wifi.keymgmt;
+}
+
+int connman_network_set_disconnect_reason(struct connman_network *network,
+ int reason_code)
+{
+ if (network == NULL)
+ return 0;
+
+ network->wifi.disconnect_reason = reason_code;
+
+ return 0;
+}
+
+int connman_network_get_disconnect_reason(struct connman_network *network)
+{
+ if (network == NULL)
+ return 0;
+
+ return network->wifi.disconnect_reason;
+}
-
+int connman_network_get_assoc_status_code(struct connman_network *network)
+{
+ if (network == NULL)
+ return 0;
+
+ return network->wifi.assoc_status_code;
+}
+#endif
+
int connman_network_set_nameservers(struct connman_network *network,
const char *nameservers)
{
nameservers_array = g_strsplit(nameservers, " ", 0);
for (i = 0; nameservers_array[i]; i++) {
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service,
+ nameservers_array[i], false,
+ CONNMAN_IPCONFIG_TYPE_ALL);
+#else
__connman_service_nameserver_append(service,
nameservers_array[i], false);
+#endif
}
g_strfreev(nameservers_array);
int connman_network_set_strength(struct connman_network *network,
uint8_t strength)
{
- #if !defined TIZEN_EXT
- DBG("network %p strengh %d", network, strength);
- #endif
-
network->strength = strength;
return 0;
int connman_network_set_frequency(struct connman_network *network,
uint16_t frequency)
{
- #if !defined TIZEN_EXT
- DBG("network %p frequency %d", network, frequency);
- #endif
-
network->frequency = frequency;
return 0;
int connman_network_set_wifi_channel(struct connman_network *network,
uint16_t channel)
{
- DBG("network %p wifi channel %d", network, channel);
-
network->wifi.channel = channel;
return 0;
int connman_network_set_string(struct connman_network *network,
const char *key, const char *value)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s value %s", network, key, value);
- #endif
-
if (g_strcmp0(key, "Name") == 0)
return connman_network_set_name(network, value);
g_free(network->wifi.security);
network->wifi.security = g_strdup(value);
} else if (g_str_equal(key, "WiFi.Passphrase")) {
+#if defined TIZEN_EXT
+ DBG("ConnMan, %p key %s", network, key);
+#endif
g_free(network->wifi.passphrase);
network->wifi.passphrase = g_strdup(value);
} else if (g_str_equal(key, "WiFi.EAP")) {
} else if (g_str_equal(key, "WiFi.Identity")) {
g_free(network->wifi.identity);
network->wifi.identity = g_strdup(value);
+ } else if (g_str_equal(key, "WiFi.AnonymousIdentity")) {
+ g_free(network->wifi.anonymous_identity);
+ network->wifi.anonymous_identity = g_strdup(value);
} else if (g_str_equal(key, "WiFi.AgentIdentity")) {
g_free(network->wifi.agent_identity);
network->wifi.agent_identity = g_strdup(value);
} else if (g_str_equal(key, "WiFi.CACertFile")) {
g_free(network->wifi.ca_cert_path);
network->wifi.ca_cert_path = g_strdup(value);
+ } else if (g_str_equal(key, "WiFi.SubjectMatch")) {
+ g_free(network->wifi.subject_match);
+ network->wifi.subject_match = g_strdup(value);
+ } else if (g_str_equal(key, "WiFi.AltSubjectMatch")) {
+ g_free(network->wifi.altsubject_match);
+ network->wifi.altsubject_match = g_strdup(value);
+ } else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) {
+ g_free(network->wifi.domain_suffix_match);
+ network->wifi.domain_suffix_match = g_strdup(value);
+ } else if (g_str_equal(key, "WiFi.DomainMatch")) {
+ g_free(network->wifi.domain_match);
+ network->wifi.domain_match = g_strdup(value);
} else if (g_str_equal(key, "WiFi.ClientCertFile")) {
g_free(network->wifi.client_cert_path);
network->wifi.client_cert_path = g_strdup(value);
const char *connman_network_get_string(struct connman_network *network,
const char *key)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s", network, key);
- #endif
-
if (g_str_equal(key, "Path"))
return network->path;
else if (g_str_equal(key, "Name"))
else if (g_str_equal(key, "WiFi.Mode"))
return network->wifi.mode;
else if (g_str_equal(key, "WiFi.Security"))
+#if defined TIZEN_EXT
+ if (network->wifi.rsn_mode != true ||
+ g_str_equal(network->wifi.security, "ieee8021x"))
+ return network->wifi.security;
+ else
+ return "rsn";
+#else
return network->wifi.security;
+#endif
else if (g_str_equal(key, "WiFi.Passphrase"))
return network->wifi.passphrase;
else if (g_str_equal(key, "WiFi.EAP"))
return network->wifi.eap;
else if (g_str_equal(key, "WiFi.Identity"))
return network->wifi.identity;
+ else if (g_str_equal(key, "WiFi.AnonymousIdentity"))
+ return network->wifi.anonymous_identity;
else if (g_str_equal(key, "WiFi.AgentIdentity"))
return network->wifi.agent_identity;
else if (g_str_equal(key, "WiFi.CACertFile"))
return network->wifi.ca_cert_path;
+ else if (g_str_equal(key, "WiFi.SubjectMatch"))
+ return network->wifi.subject_match;
+ else if (g_str_equal(key, "WiFi.AltSubjectMatch"))
+ return network->wifi.altsubject_match;
+ else if (g_str_equal(key, "WiFi.DomainSuffixMatch"))
+ return network->wifi.domain_suffix_match;
+ else if (g_str_equal(key, "WiFi.DomainMatch"))
+ return network->wifi.domain_match;
else if (g_str_equal(key, "WiFi.ClientCertFile"))
return network->wifi.client_cert_path;
else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
int connman_network_set_bool(struct connman_network *network,
const char *key, bool value)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s value %d", network, key, value);
- #endif
-
if (g_strcmp0(key, "Roaming") == 0)
network->roaming = value;
else if (g_strcmp0(key, "WiFi.WPS") == 0)
network->wifi.wps = value;
else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
network->wifi.use_wps = value;
+#if defined TIZEN_EXT
+ else if (g_strcmp0(key, "DefaultInternet") == 0)
+ network->default_internet = value;
+ else if (g_strcmp0(key, "WiFi.HS20AP") == 0)
+ network->wifi.isHS20AP = value;
+#endif
return -EINVAL;
}
bool connman_network_get_bool(struct connman_network *network,
const char *key)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s", network, key);
- #endif
-
if (g_str_equal(key, "Roaming"))
return network->roaming;
else if (g_str_equal(key, "WiFi.WPS"))
return network->wifi.wps;
else if (g_str_equal(key, "WiFi.UseWPS"))
return network->wifi.use_wps;
+#if defined TIZEN_EXT
+ else if (g_str_equal(key, "DefaultInternet"))
+ return network->default_internet;
+ else if (g_str_equal(key, "WiFi.HS20AP"))
+ return network->wifi.isHS20AP;
+#endif
return false;
}
- #if defined TIZEN_EXT
- /**
- * connman_network_set_vsie_list:
- * @network: network structure
- * @vsie_list: GSList pointer
- *
- * Set vendor specific list pointer
- */
- void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list)
- {
- network->wifi.vsie_list = vsie_list;
- }
-
- /**
- * connman_network_get_vsie_list:
- * @network: network structure
- *
- * Get vendor specific list pointer
- */
- void *connman_network_get_vsie_list(struct connman_network *network)
- {
- return network->wifi.vsie_list;
- }
- #endif
-
/**
* connman_network_set_blob:
* @network: network structure
int connman_network_set_blob(struct connman_network *network,
const char *key, const void *data, unsigned int size)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s size %d", network, key, size);
- #endif
-
if (g_str_equal(key, "WiFi.SSID")) {
g_free(network->wifi.ssid);
network->wifi.ssid = g_try_malloc(size);
network->wifi.ssid_len = size;
} else
network->wifi.ssid_len = 0;
++#if defined TIZEN_EXT
++ } else if (g_str_equal(key, "WiFi.Vsie")){
++ g_free(network->wifi.wifi_vsie);
++ network->wifi.wifi_vsie = g_try_malloc(size);
++ if (network->wifi.wifi_vsie) {
++ memcpy(network->wifi.wifi_vsie, data, size);
++ network->wifi.wifi_vsie_len = size;
++ } else
++ network->wifi.wifi_vsie_len = 0;
++#endif
} else {
return -EINVAL;
}
const void *connman_network_get_blob(struct connman_network *network,
const char *key, unsigned int *size)
{
- #if !defined TIZEN_EXT
- DBG("network %p key %s", network, key);
- #endif
-
if (g_str_equal(key, "WiFi.SSID")) {
if (size)
*size = network->wifi.ssid_len;
return network->wifi.ssid;
}
++#if defined TIZEN_EXT
++ if (g_str_equal(key, "WiFi.Vsie")) {
++ if (size)
++ *size = network->wifi.wifi_vsie_len;
++
++ return network->wifi.wifi_vsie;
++ }
++#endif
++
return NULL;
}
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+ #include <sys/timex.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
+ #include <netdb.h>
#include <glib.h>
#define OFFSET_1900_1970 2208988800UL /* 1970 - 1900 in seconds */
- #define STEPTIME_MIN_OFFSET 0.128
+ #define STEPTIME_MIN_OFFSET 0.4
#define LOGTOD(a) ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
+ #define NSEC_PER_SEC ((uint64_t)1000000000ULL)
+ #ifndef ADJ_SETOFFSET
+ #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
+ #endif
#define NTP_SEND_TIMEOUT 2
#define NTP_SEND_RETRIES 3
static int transmit_fd = 0;
static char *timeserver = NULL;
- static struct sockaddr_in timeserver_addr;
+ static struct sockaddr_in6 timeserver_addr;
static gint poll_id = 0;
static gint timeout_id = 0;
static guint retries = 0;
- static void send_packet(int fd, const char *server, uint32_t timeout);
+ static void send_packet(int fd, struct sockaddr *server, uint32_t timeout);
static void next_server(void)
{
if (retries++ == NTP_SEND_RETRIES)
next_server();
else
- send_packet(transmit_fd, timeserver, timeout << 1);
+ send_packet(transmit_fd, (struct sockaddr *)×erver_addr, timeout << 1);
return FALSE;
}
- static void send_packet(int fd, const char *server, uint32_t timeout)
+ static void send_packet(int fd, struct sockaddr *server, uint32_t timeout)
{
struct ntp_msg msg;
- struct sockaddr_in addr;
struct timeval transmit_timeval;
ssize_t len;
+ void * addr;
+ int size;
+ char ipaddrstring[INET6_ADDRSTRLEN + 1];
/*
* At some point, we could specify the actual system precision with:
memset(&msg, 0, sizeof(msg));
msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
NTP_FLAG_MD_CLIENT);
- msg.poll = 4; // min
- msg.poll = 10; // max
+ msg.poll = 10;
msg.precision = NTP_PRECISION_S;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(123);
- addr.sin_addr.s_addr = inet_addr(server);
+ if (server->sa_family == AF_INET) {
+ size = sizeof(struct sockaddr_in);
+ addr = (void *)&(((struct sockaddr_in *)×erver_addr)->sin_addr);
+ } else if (server->sa_family == AF_INET6) {
+ size = sizeof(struct sockaddr_in6);
+ addr = (void *)×erver_addr.sin6_addr;
+ } else {
+ connman_error("Family is neither ipv4 nor ipv6");
+ return;
+ }
gettimeofday(&transmit_timeval, NULL);
clock_gettime(CLOCK_MONOTONIC, &mtx_time);
msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);
len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT,
- &addr, sizeof(addr));
+ server, size);
+
if (len < 0) {
connman_error("Time request for server %s failed (%d/%s)",
- server, errno, strerror(errno));
+ inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)),
+ errno, strerror(errno));
if (errno == ENETUNREACH)
__connman_timeserver_sync_next();
}
if (len != sizeof(msg)) {
- connman_error("Broken time request for server %s", server);
+ connman_error("Broken time request for server %s",
+ inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
return;
}
if (!timeserver || transmit_fd == 0)
return FALSE;
- send_packet(transmit_fd, timeserver, NTP_SEND_TIMEOUT);
+ send_packet(transmit_fd, (struct sockaddr *)×erver_addr, NTP_SEND_TIMEOUT);
return FALSE;
}
double m_delta, org, rec, xmt, dst;
double delay, offset;
static guint transmit_delay;
-
++#if !defined TIZEN_EXT
+ struct timex tmx = {};
-
++#endif
if (len < sizeof(*msg)) {
connman_error("Invalid response from time server");
return;
poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL);
- connman_info("ntp: time slew %+.6f s", offset);
-
+#if defined TIZEN_EXT
+ //send the dbus message to alram-manager
+ {
+#define TIME_BUS_NAME "org.tizen.alarm.manager"
+#define TIME_INTERFACE "org.tizen.alarm.manager"
+#define TIME_PATH "/org/tizen/alarm/manager"
+#define TIME_METHOD "alarm_set_time_with_propagation_delay"
+
+ struct timespec cur = {0};
+ struct timespec req = {0};
+ double dtime;
+
+ DBusConnection *connection = NULL;
+ DBusMessage *msg = NULL, *reply = NULL;
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ connection = connman_dbus_get_connection();
+ if(!connection){
+ DBG("dbus connection does not exist");
+ return;
+ }
+
+ clock_gettime(CLOCK_REALTIME, &cur);
+ dtime = offset + cur.tv_sec + 1.0e-9 * cur.tv_nsec;
+ cur.tv_sec = (long) dtime;
+ cur.tv_nsec = (dtime - cur.tv_sec) * 1000000000;
+
+ clock_gettime(CLOCK_REALTIME, &req);
+ msg = dbus_message_new_method_call(TIME_BUS_NAME, TIME_PATH,
+ TIME_INTERFACE, TIME_METHOD);
+ dbus_message_append_args(msg, DBUS_TYPE_UINT32, &(cur.tv_sec),
+ DBUS_TYPE_UINT32, &(cur.tv_nsec),
+ DBUS_TYPE_UINT32, &(req.tv_sec),
+ DBUS_TYPE_UINT32, &(req.tv_nsec), DBUS_TYPE_INVALID);
+ reply = dbus_connection_send_with_reply_and_block(connection, msg,
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
+ if(reply == NULL){
+ if(dbus_error_is_set(&error)){
+ DBG("%s", error.message);
+ dbus_error_free(&error);
+ }
+ else{
+ DBG("Failed to request set time");
+ }
+ dbus_connection_unref(connection);
+ dbus_message_unref(msg);
+ return;
+ }
+
+ dbus_message_unref(msg);
+ dbus_message_unref(reply);
+ dbus_connection_unref(connection);
+
+ DBG("%lu cur seconds, %lu cur nsecs, %lu req seconds, %lu req nsecs",
+ cur.tv_sec, cur.tv_nsec, req.tv_sec, req.tv_nsec);
+ DBG("setting time");
+ }
+#else
if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
- struct timeval adj;
-
- adj.tv_sec = (long) offset;
- adj.tv_usec = (offset - adj.tv_sec) * 1000000;
-
- DBG("adjusting time");
-
- if (adjtime(&adj, &adj) < 0) {
- connman_error("Failed to adjust time");
- return;
- }
-
- DBG("%lu seconds, %lu msecs", adj.tv_sec, adj.tv_usec);
+ tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
+ tmx.status = STA_PLL;
+ tmx.offset = offset * NSEC_PER_SEC;
+ tmx.constant = msg->poll - 4;
+ tmx.maxerror = 0;
+ tmx.esterror = 0;
+
+ connman_info("ntp: adjust (slew): %+.6f sec", offset);
} else {
- struct timeval cur;
- double dtime;
-
- gettimeofday(&cur, NULL);
- dtime = offset + cur.tv_sec + 1.0e-6 * cur.tv_usec;
- cur.tv_sec = (long) dtime;
- cur.tv_usec = (dtime - cur.tv_sec) * 1000000;
+ tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
+
+ /* ADJ_NANO uses nanoseconds in the microseconds field */
+ tmx.time.tv_sec = (long)offset;
+ tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
+ tmx.maxerror = 0;
+ tmx.esterror = 0;
+
+ /* the kernel expects -0.3s as {-1, 7000.000.000} */
+ if (tmx.time.tv_usec < 0) {
+ tmx.time.tv_sec -= 1;
+ tmx.time.tv_usec += NSEC_PER_SEC;
+ }
- DBG("setting time");
+ connman_info("ntp: adjust (jump): %+.6f sec", offset);
+ }
- if (settimeofday(&cur, NULL) < 0) {
- connman_error("Failed to set time");
- return;
- }
+ if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
+ tmx.status |= STA_INS;
+ else if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_DELSECOND)
+ tmx.status |= STA_DEL;
- DBG("%lu seconds, %lu msecs", cur.tv_sec, cur.tv_usec);
+ if (adjtimex(&tmx) < 0) {
+ connman_error("Failed to adjust time");
+ return;
}
- LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+
+ DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
++ LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+#endif
}
static gboolean received_data(GIOChannel *channel, GIOCondition condition,
gpointer user_data)
{
unsigned char buf[128];
- struct sockaddr_in sender_addr;
+ struct sockaddr_in6 sender_addr;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
char aux[128];
ssize_t len;
int fd;
+ int size;
+ void * addr_ptr;
+ void * src_ptr;
if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
connman_error("Problem with timer server channel");
if (len < 0)
return TRUE;
- if (timeserver_addr.sin_addr.s_addr != sender_addr.sin_addr.s_addr)
- /* only accept messages from the timeserver */
+ if (sender_addr.sin6_family == AF_INET) {
+ size = 4;
+ addr_ptr = &((struct sockaddr_in *)×erver_addr)->sin_addr;
+ src_ptr = &((struct sockaddr_in *)&sender_addr)->sin_addr;
+ } else if (sender_addr.sin6_family == AF_INET6) {
+ size = 16;
+ addr_ptr = &((struct sockaddr_in6 *)×erver_addr)->sin6_addr;
+ src_ptr = &((struct sockaddr_in6 *)&sender_addr)->sin6_addr;
+ } else {
+ connman_error("Not a valid family type");
+ return TRUE;
+ }
+
+ if(memcmp(addr_ptr, src_ptr, size) != 0)
return TRUE;
tv = NULL;
static void start_ntp(char *server)
{
GIOChannel *channel;
- struct sockaddr_in addr;
+ struct addrinfo hint;
+ struct addrinfo *info;
+ struct sockaddr * addr;
+ struct sockaddr_in * in4addr;
+ struct sockaddr_in6 in6addr;
+ int size;
+ int family;
int tos = IPTOS_LOWDELAY, timestamp = 1;
+ int ret;
if (!server)
return;
- DBG("server %s", server);
+ memset(&hint, 0, sizeof(hint));
+ hint.ai_family = AF_UNSPEC;
+ hint.ai_socktype = SOCK_DGRAM;
+ hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+ ret = getaddrinfo(server, NULL, &hint, &info);
- if (channel_watch > 0)
- goto send;
+ if (ret) {
+ connman_error("cannot get server info");
+ return;
+ }
- transmit_fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (transmit_fd < 0) {
- connman_error("Failed to open time server socket");
+ family = info->ai_family;
+
+ memcpy(×erver_addr, info->ai_addr, info->ai_addrlen);
+ freeaddrinfo(info);
+ memset(&in6addr, 0, sizeof(in6addr));
+
+ if (family == AF_INET) {
+ ((struct sockaddr_in *)×erver_addr)->sin_port = htons(123);
+ in4addr = (struct sockaddr_in *)&in6addr;
+ in4addr->sin_family = family;
+ addr = (struct sockaddr *)in4addr;
+ size = sizeof(struct sockaddr_in);
+ } else if (family == AF_INET6) {
+ timeserver_addr.sin6_port = htons(123);
+ in6addr.sin6_family = family;
+ addr = (struct sockaddr *)&in6addr;
+ size = sizeof(in6addr);
+ } else {
+ connman_error("Family is neither ipv4 nor ipv6");
return;
}
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ DBG("server %s family %d", server, family);
- if (bind(transmit_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (channel_watch > 0)
+ goto send;
+
+ transmit_fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+
+ if (transmit_fd <= 0) {
+ connman_error("Failed to open time server socket");
+ return;
+ }
+
+ if (bind(transmit_fd, (struct sockaddr *) addr, size) < 0) {
connman_error("Failed to bind time server socket");
close(transmit_fd);
return;
}
- if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
- connman_error("Failed to set type of service option");
- close(transmit_fd);
- return;
+ if (family == AF_INET) {
+ if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
+ connman_error("Failed to set type of service option");
+ close(transmit_fd);
+ return;
+ }
}
if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, ×tamp,
g_io_channel_unref(channel);
send:
- send_packet(transmit_fd, server, NTP_SEND_TIMEOUT);
+ send_packet(transmit_fd, (struct sockaddr*)×erver_addr, NTP_SEND_TIMEOUT);
}
int __connman_ntp_start(char *server)
g_free(timeserver);
timeserver = g_strdup(server);
- timeserver_addr.sin_addr.s_addr = inet_addr(server);
start_ntp(timeserver);
if (err < 0)
goto error;
- g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));
+ g_idle_add(dhcp_server_started, connman_peer_ref(peer));
return 0;
void connman_peer_set_iface_address(struct connman_peer *peer,
const unsigned char *iface_address)
{
- memset(peer->iface_address, 0, ETH_ALEN);
+ memset(peer->iface_address, 0, sizeof(peer->iface_address));
memcpy(peer->iface_address, iface_address, ETH_ALEN);
}
break;
case CONNMAN_PEER_STATE_READY:
reply_pending(peer, 0);
+ __connman_technology_set_connected(CONNMAN_SERVICE_TYPE_P2P, true);
break;
case CONNMAN_PEER_STATE_DISCONNECT:
if (peer->connection_master)
stop_dhcp_server(peer);
+ else
+ __connman_dhcp_stop(peer->ipconfig);
peer->connection_master = false;
peer->sub_device = NULL;
-
+ __connman_technology_set_connected(CONNMAN_SERVICE_TYPE_P2P, false);
break;
case CONNMAN_PEER_STATE_FAILURE:
if (manage_peer_error(peer) == 0)
if (service) {
DBG("Found one existing service %p", service);
- if (g_strcmp0(service->owner, owner))
- ret = -EBUSY;
-
if (service->pending)
ret = -EINPROGRESS;
else
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_DISCONNECT);
- if (err < 0) {
- if (err != -EINPROGRESS)
- return err;
+ if (err < 0)
+ return err;
- return -EINPROGRESS;
- }
+ if (provider->vpn_service)
+ provider_indicate_state(provider,
+ CONNMAN_SERVICE_STATE_IDLE);
return 0;
}
return 0;
}
- int __connman_provider_connect(struct connman_provider *provider)
+ int __connman_provider_connect(struct connman_provider *provider,
+ const char *dbus_sender)
{
int err;
DBG("provider %p", provider);
if (provider->driver && provider->driver->connect)
- err = provider->driver->connect(provider);
+ err = provider->driver->connect(provider, dbus_sender);
else
return -EOPNOTSUPP;
}
__connman_ipconfig_address_add(ipconfig);
+#if defined TIZEN_EXT
+ __connman_ipconfig_gateway_add(ipconfig, service);
+#else
__connman_ipconfig_gateway_add(ipconfig);
+#endif
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_READY);
return 0;
for (i = 0; nameservers[i]; i++)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(provider->vpn_service,
+ nameservers[i], false,
+ CONNMAN_IPCONFIG_TYPE_ALL);
+#else
__connman_service_nameserver_append(provider->vpn_service,
nameservers[i], false);
+#endif
return 0;
}
lookup->url = g_strdup(url);
lookup->service = connman_service_ref(service);
- lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
+ lookup->watch = g_idle_add(lookup_callback, lookup);
if (lookup->watch == 0) {
g_free(lookup->url);
g_free(lookup);
#include "connman.h"
-#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf"
-#define RESOLV_CONF_ETC "/etc/resolv.conf"
-
#define RESOLVER_FLAG_PUBLIC (1 << 0)
/*
* MAXDNSRCH/MAXNS entries are used.
*/
- for (count = 0, list = g_list_last(resolvfile_list);
+ for (count = 0, list = g_list_first(resolvfile_list);
list && (count < MAXDNSRCH);
- list = g_list_previous(list)) {
+ list = g_list_next(list)) {
struct resolvfile_entry *entry = list->data;
if (!entry->domain)
if (count)
g_string_append_printf(content, "\n");
- for (count = 0, list = g_list_last(resolvfile_list);
+ for (count = 0, list = g_list_first(resolvfile_list);
list && (count < MAXNS);
- list = g_list_previous(list)) {
+ list = g_list_next(list)) {
struct resolvfile_entry *entry = list->data;
if (!entry->server)
old_umask = umask(022);
- fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC,
+ fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
- connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" "
- "falling back to "RESOLV_CONF_ETC);
-
- fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
- if (fd < 0) {
- err = -errno;
- goto done;
- }
+ err = -errno;
+ goto done;
}
if (ftruncate(fd, 0) < 0) {
return resolvfile_export();
}
- static void append_fallback_nameservers(void)
+ void __connman_resolver_append_fallback_nameservers(void)
{
GSList *list;
g_slist_free(entries);
- append_fallback_nameservers();
+ __connman_resolver_append_fallback_nameservers();
}
static gboolean resolver_expire_cb(gpointer user_data)
struct connman_service *service;
service = __connman_service_lookup_from_index(entry->index);
if (service)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_remove(service,
+ entry->server, true,
+ CONNMAN_IPCONFIG_TYPE_ALL);
+#else
__connman_service_nameserver_remove(service,
entry->server, true);
+#endif
}
remove_entries(list);
if (!server && !domain)
return -EINVAL;
+#ifdef TIZEN_EXT
+ if (g_strcmp0(server, "0.0.0.0") == 0)
+ return -EINVAL;
+#endif
+
entry = g_try_new0(struct entry_data, 1);
if (!entry)
return -ENOMEM;
entry->timeout = g_timeout_add_seconds(interval,
resolver_refresh_cb, entry);
-
- /*
- * We update the service only for those nameservers
- * that are automagically added via netlink (lifetime > 0)
- */
- if (server && entry->index >= 0) {
- struct connman_service *service;
- service = __connman_service_lookup_from_index(entry->index);
- if (service)
- #if defined TIZEN_EXT
- __connman_service_nameserver_append(service,
- server, true,
- CONNMAN_IPCONFIG_TYPE_ALL);
- #else
- __connman_service_nameserver_append(service,
- server, true);
- #endif
- }
}
if (entry->index >= 0 && entry->server)
else
__connman_resolvfile_append(entry->index, domain, server);
+ /*
+ * We update the service only for those nameservers
+ * that are automagically added via netlink (lifetime > 0)
+ */
+ if (server && entry->index >= 0 && lifetime) {
+ struct connman_service *service;
+ service = __connman_service_lookup_from_index(entry->index);
+ if (service)
++#if defined TIZEN_EXT
++ __connman_service_nameserver_append(service,
++ server, true,
++ CONNMAN_IPCONFIG_TYPE_ALL);
++#else
+ __connman_service_nameserver_append(service,
+ server, true);
++#endif
+ }
+
return 0;
}
entry->server);
}
+ /*
+ * We want to re-add all search domains back to search
+ * domain lists as they just got removed for RDNSS IPv6-servers
+ * (above).
+ * Removal of search domains is not necessary
+ * as there can be only one instance of each search domain
+ * in the each dns-servers search domain list.
+ */
+
+ for (list = entry_list; list; list = list->next) {
+ struct entry_data *entry = list->data;
+
+ if (entry->index != index)
+ continue;
+
+ if (entry->server)
+ continue;
+
+ __connman_dnsproxy_append(entry->index, entry->domain,
+ NULL);
+ }
+
return 0;
}
DBG("dnsproxy %d", dnsproxy);
+ /* get autoip nameservers */
+ ns = __connman_inet_get_pnp_nameservers(NULL);
+ for (i = 0; ns && ns[i]; i += 1) {
+ DBG("pnp server %s", ns[i]);
+ append_resolver(i, NULL, ns[i], 86400, 0);
+ }
+ g_strfreev(ns);
+
if (!dnsproxy)
return 0;
return CONNMAN_SERVICE_TYPE_UNKNOWN;
}
+#if !defined TIZEN_EXT
static enum rfkill_type convert_service_type(enum connman_service_type type)
{
switch (type) {
return NUM_RFKILL_TYPES;
}
+#endif
static GIOStatus rfkill_process(GIOChannel *chan)
{
int __connman_rfkill_block(enum connman_service_type type, bool block)
{
+#if !defined TIZEN_EXT
uint8_t rfkill_type;
struct rfkill_event event;
ssize_t len;
int fd, err = 0;
+#endif
DBG("type %d block %d", type, block);
+#if defined TIZEN_EXT
+ DBG("try to set rfkill block %d, but it's not permitted", block);
+
+ return 0;
+#else
rfkill_type = convert_service_type(type);
if (rfkill_type == NUM_RFKILL_TYPES)
return -EINVAL;
close(fd);
return err;
+#endif
}
int __connman_rfkill_init(void)
DBG("");
- fd = open("/dev/rfkill", O_RDWR | O_CLOEXEC);
+ fd = open("/dev/rfkill", O_RDONLY | O_CLOEXEC);
if (fd < 0) {
connman_error("Failed to open RFKILL control device");
return -EIO;
#define ARPHDR_PHONET_PIPE (821)
#endif
+#if defined TIZEN_EXT
+#ifndef ARPHDR_RMNET
+#define ARPHDR_RMNET (530)
+#endif
+#endif
+
#define print(arg...) do { if (0) connman_info(arg); } while (0)
//#define print(arg...) connman_info(arg)
return false;
}
+#if !defined TIZEN_EXT
static bool wext_interface(char *ifname)
{
struct iwreq wrq;
return true;
}
+#endif
+
+#if defined TIZEN_EXT
+static bool __connman_rtnl_is_cellular_device(const char *name)
+{
+ char **pattern;
+ char **cellular_interfaces;
+
+ cellular_interfaces =
+ connman_setting_get_string_list(
+ "NetworkCellularInterfaceList");
+ if (!cellular_interfaces)
+ return false;
+
+ for (pattern = cellular_interfaces; *pattern; pattern++) {
+ if (g_str_has_prefix(name, *pattern)) {
+ DBG("Cellular interface: %s", name);
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
static void read_uevent(struct interface_data *interface)
{
name = connman_inet_ifname(interface->index);
+#if defined TIZEN_EXT
+ if (__connman_rtnl_is_cellular_device(name)) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
+ interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
+ return;
+ }
+#endif
+
if (ether_blacklisted(name)) {
interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
} else if (strcmp(line + 8, "vlan") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
-
+ } else if (strcmp(line + 8, "bond") == 0) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
+ interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
} else {
interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
if (found_devtype)
goto out;
+#if !defined TIZEN_EXT
+ /* TIZEN does not use old wext interface */
/* We haven't got a DEVTYPE, let's check if it's a wireless device */
if (wext_interface(name)) {
interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
connman_error("%s runs an unsupported 802.11 driver", name);
}
+#endif
out:
g_free(name);
if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
return;
+#if defined TIZEN_EXT
+ /* Do not accept Wi-Fi P2P interface */
+ if (g_strrstr(ifname, "p2p") != NULL) {
+ DBG("Newlink event for Wi-Fi P2P interface ignored");
+ return;
+ }
+#endif
+
snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
address.ether_addr_octet[0],
address.ether_addr_octet[1],
return;
}
+#ifdef TIZEN_EXT
+ if (TIZEN_TV_EXT && g_strcmp0(ident, "eeeeeeeeeeee") == 0) {
+ DBG("Newlink event with Dummy MAC. Ignored!");
+ return;
+ }
+#endif
+
switch (type) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
case ARPHDR_PHONET_PIPE:
case ARPHRD_PPP:
case ARPHRD_NONE:
+#if defined TIZEN_EXT
+/*
+ * Description: ARPHDR_RMNET for QC modem using QMI
+ */
+ case ARPHDR_RMNET:
+#endif
__connman_ipconfig_newlink(index, type, flags,
str, mtu, &stats);
break;
if (type == ARPHRD_ETHER)
read_uevent(interface);
- } else
+#if defined TIZEN_EXT
+ if (type == ARPHRD_PPP || type == ARPHDR_RMNET)
+ read_uevent(interface);
+
+ } else if (g_strcmp0(interface->ident, ident) != 0) {
+ /* If an original address is built-in physical device,
+ * it's hardly get an address at a initial creation
+ */
+ __connman_technology_remove_interface(interface->service_type,
+ interface->index, interface->ident);
+
+ g_free(interface->ident);
+ interface->ident = g_strdup(ident);
+
+ __connman_technology_add_interface(interface->service_type,
+ interface->index, interface->ident);
+
+ interface = NULL;
+#endif
+ } else if (type == ARPHRD_ETHER && interface->device_type == CONNMAN_DEVICE_TYPE_UNKNOWN)
+ read_uevent(interface);
+ else
interface = NULL;
for (list = rtnl_list; list; list = list->next) {
case ARPHDR_PHONET_PIPE:
case ARPHRD_PPP:
case ARPHRD_NONE:
+#if defined TIZEN_EXT
+ /*
+ * Description: SLP requires ARPHRD_PPP for PPP type device
+ * ARPHDR_RMNET for QC modem using QMI
+ */
+ case ARPHDR_RMNET:
+#endif
__connman_ipconfig_dellink(index, &stats);
break;
}
if (index < 0)
return;
+#if defined TIZEN_EXT
+ struct connman_service *service;
+ enum connman_service_state state;
+ enum connman_dnsconfig_method ipv6_dns_method;
+
+ service = __connman_service_lookup_from_index(index);
+ if (!service) {
+ DBG("Invalid service");
+ return;
+ }
+
+ DBG("service: %p index: %d\n", service, index);
+
+ if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
+ state = __connman_service_ipconfig_get_state(service, CONNMAN_IPCONFIG_TYPE_IPV6);
+ if (state != CONNMAN_SERVICE_STATE_ASSOCIATION &&
+ state != CONNMAN_SERVICE_STATE_CONFIGURATION &&
+ state != CONNMAN_SERVICE_STATE_READY &&
+ state != CONNMAN_SERVICE_STATE_ONLINE) {
+ DBG("Service state[%d] is not connecting/connected", state);
+ return;
+ }
+ }
+
+ ipv6_dns_method = connman_service_get_ipv6_dns_method(service);
+ if (ipv6_dns_method != CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ DBG("IPv6 DNS method is not Auto ignore RA!!! [DNS method: %d]", ipv6_dns_method);
+ return;
+ }
+#endif
+
for (opt = (void *)&msg[1];
msglen > 0;
msglen -= opt->nd_opt_len * 8,
if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
char buf[40];
++#if defined TIZEN_EXT
++ struct connman_service *service;
++ service = __connman_service_lookup_from_index(index);
++ DBG("service: %p\n",service);
++#endif
servers = rtnl_nd_opt_rdnss(opt, &lifetime,
- &nr_servers);
+ &nr_servers);
for (i = 0; i < nr_servers; i++) {
if (!inet_ntop(AF_INET6, servers + i, buf,
- sizeof(buf)))
+ sizeof(buf)))
continue;
+#if defined TIZEN_EXT
+ __connman_service_nameserver_remove(service,
+ buf, false,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ __connman_service_nameserver_append(service,
+ buf, false,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#endif
connman_resolver_append_lifetime(index,
- NULL, buf, lifetime);
+ NULL, buf, lifetime);
}
+
} else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
g_free(domains);
static void rtnl_message(void *buf, size_t len)
{
- DBG("buf %p len %zd", buf, len);
-
while (len > 0) {
struct nlmsghdr *hdr = buf;
struct nlmsgerr *err;
#include <gdbus.h>
#include <ctype.h>
#include <stdint.h>
+#include <pwd.h>
+#include <utmpx.h>
#include <connman/storage.h>
#include <connman/setting.h>
#define CONNECT_TIMEOUT 120
+#define USER_ROOT 0
+#define USER_NONE (uid_t)-1
+
+#if defined TIZEN_EXT
+#define WIFI_BSSID_STR_LEN 18
+#endif
+
static DBusConnection *connection = NULL;
static GList *service_list = NULL;
static struct connman_service *current_default = NULL;
static bool services_dirty = false;
+#if defined TIZEN_EXT
+static bool auto_connect_mode = TRUE;
+#endif
+
struct connman_stats {
bool valid;
bool enabled;
struct connman_stats stats_roaming;
};
+struct connman_service_user {
+ uid_t favorite_user;
+ uid_t current_user;
+};
+
struct connman_service {
int refcount;
char *identifier;
char *name;
char *passphrase;
bool roaming;
+ bool request_passphrase_input;
+ struct connman_service_user user;
struct connman_ipconfig *ipconfig_ipv4;
struct connman_ipconfig *ipconfig_ipv6;
struct connman_network *network;
char **nameservers;
char **nameservers_config;
char **nameservers_auto;
+ int nameservers_timeout;
char **domains;
char *hostname;
char *domainname;
/* 802.1x settings from the config files */
char *eap;
char *identity;
+ char *anonymous_identity;
char *agent_identity;
char *ca_cert_file;
+ char *subject_match;
+ char *altsubject_match;
+ char *domain_suffix_match;
+ char *domain_match;
char *client_cert_file;
char *private_key_file;
char *private_key_passphrase;
bool hidden_service;
char *config_file;
char *config_entry;
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ * It's only for PDP (cellular) bearer. Wi-Fi is managed
+ * by ConnMan automatically. Reference count can help to
+ * manage open/close connection requests by each application.
+ */
+ int user_pdn_connection_refcount;
+ bool storage_reload;
+ /*
+ * Description: In case of EAP security type,
+ * user can select the keymgmt type for roaming(802.11r).
+ * - FT, CCKM, OKC, ...
+ */
+ char *keymgmt_type;
+ int disconnect_reason;
+ int assoc_status_code;
+#endif
+#ifdef TIZEN_EXT
+ enum connman_dnsconfig_method dns_config_method_ipv4;
+ enum connman_dnsconfig_method dns_config_method_ipv6;
+#endif
};
static bool allow_property_changed(struct connman_service *service);
int index, enum connman_ipconfig_method method);
static struct connman_ipconfig *create_ip6config(struct connman_service *service,
int index);
-
+ static void dns_changed(struct connman_service *service);
struct find_data {
const char *path;
struct connman_service *service;
};
+#if defined TIZEN_EXT
+/*
+ * Public APIs to use user_pdn_connection_refcount
+ */
+void connman_service_user_pdn_connection_ref(struct connman_service *service)
+{
+ __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
+
+ DBG("User made PDN connection referenced: %d",
+ service->user_pdn_connection_refcount);
+}
+
+gboolean connman_service_user_pdn_connection_unref_and_test(
+ struct connman_service *service)
+{
+ __sync_synchronize();
+
+ DBG("User made PDN connection referenced: %d, which will be decreased",
+ service->user_pdn_connection_refcount);
+
+ if (service->user_pdn_connection_refcount < 1)
+ return TRUE;
+
+ if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+gboolean connman_service_is_no_ref_user_pdn_connection(
+ struct connman_service *cellular)
+{
+ if (cellular == NULL)
+ return TRUE;
+
+ __sync_synchronize();
+ if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ cellular->user_pdn_connection_refcount == 0)
+ return TRUE;
+
+ return FALSE;
+}
+#endif
+
static void compare_path(gpointer value, gpointer user_data)
{
struct connman_service *service = value;
if (!strcmp(str, "psk"))
return CONNMAN_SERVICE_SECURITY_PSK;
- if (!strcmp(str, "ieee8021x"))
+ if (!strcmp(str, "ieee8021x") || !strcmp(str, "8021x"))
return CONNMAN_SERVICE_SECURITY_8021X;
- if (!strcmp(str, "none"))
+ if (!strcmp(str, "none") || !strcmp(str, "open"))
return CONNMAN_SERVICE_SECURITY_NONE;
if (!strcmp(str, "wep"))
return CONNMAN_SERVICE_SECURITY_WEP;
+#if defined TIZEN_EXT
+ if (!strcmp(str, "rsn"))
+ return CONNMAN_SERVICE_SECURITY_RSN;
+#endif
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
}
return "wep";
case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
+#if defined TIZEN_EXT
+ return "psk";
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ return "rsn";
+#else
case CONNMAN_SERVICE_SECURITY_RSN:
return "psk";
+#endif
case CONNMAN_SERVICE_SECURITY_8021X:
return "ieee8021x";
}
return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
}
+#ifdef TIZEN_EXT
+static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method)
+{
+ switch (method) {
+ case CONNMAN_DNSCONFIG_METHOD_UNKNOWN:
+ return "unknown";
+ case CONNMAN_DNSCONFIG_METHOD_MANUAL:
+ return "manual";
+ case CONNMAN_DNSCONFIG_METHOD_DHCP:
+ return "dhcp";
+ }
+
+ return NULL;
+}
+
+static enum connman_dnsconfig_method __connman_dnsconfig_string2method(
+ const char *method)
+{
+ if (g_strcmp0(method, "manual") == 0)
+ return CONNMAN_DNSCONFIG_METHOD_MANUAL;
+ else if (g_strcmp0(method, "dhcp") == 0)
+ return CONNMAN_DNSCONFIG_METHOD_DHCP;
+ else
+ return CONNMAN_DNSCONFIG_METHOD_UNKNOWN;
+}
+#endif
+
+static bool
+connman_service_is_user_allowed(struct connman_service *service, uid_t uid)
+{
+ uid_t favorite_user = service->user.favorite_user;
+ uid_t current_user = uid;
+
+ DBG("Service favorite UID: %d, current UID: %d", favorite_user, current_user);
+ if (favorite_user == USER_NONE || current_user == USER_ROOT)
+ return true;
+
+ if (favorite_user != current_user || current_user == USER_NONE) {
+ DBG("Current user is not a favorite user to this service!");
+ return false;
+ }
+
+ return true;
+}
+
+#if !defined TIZEN_EXT
+static GList *connman_service_get_login_users()
+{
+ struct utmpx *utmp;
+ struct passwd *pwd;
+ GList *user_list = NULL;
+
+ setutxent();
+
+ while ((utmp = getutxent()) != NULL) {
+ DBG("User Name: %s", utmp->ut_user);
+
+ pwd = getpwnam(utmp->ut_user);
+ if (pwd) {
+ if (!g_list_find(user_list, GUINT_TO_POINTER(pwd->pw_uid)))
+ user_list = g_list_append(user_list,
+ GUINT_TO_POINTER(pwd->pw_uid));
+
+ DBG("User Name: %s, UID: %d", utmp->ut_user, pwd->pw_uid);
+ }
+ }
+
+ endutxent();
+
+ return user_list;
+}
+#endif
+
+static bool is_service_owner_user_login(struct connman_service *service)
+{
+#if defined TIZEN_EXT
+ return true;
+#else
+ GList *list, *user_list;
+ bool ret = false;
+
+ /* Here we only care about wifi service */
+ if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return true;
+
+ DBG("service favorite user id is: %d", service->user.favorite_user);
+
+ user_list = connman_service_get_login_users();
+ if (user_list == NULL) {
+ DBG("Can not get any logged in user info.");
+ return true;
+ }
+
+ for (list = user_list; list; list = list->next) {
+ uid_t uid = GPOINTER_TO_UINT(list->data);
+
+ DBG("login user id is %d", uid);
+
+ if (service->user.favorite_user == uid) {
+ ret = true;
+ break;
+ }
+ }
+
+ g_list_free(user_list);
+
+ return ret;
+#endif
+}
+
+ static void set_split_routing(struct connman_service *service, bool value)
+ {
+ if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ return;
+
+ service->do_split_routing = value;
+
+ if (service->do_split_routing)
+ service->order = 0;
+ else
+ service->order = 10;
+ }
+
int __connman_service_load_modifiable(struct connman_service *service)
{
GKeyFile *keyfile;
case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_VPN:
- service->do_split_routing = g_key_file_get_boolean(keyfile,
- service->identifier, "SplitRouting", NULL);
+ set_split_routing(service, g_key_file_get_boolean(keyfile,
+ service->identifier,
+ "SplitRouting", NULL));
+
/* fall through */
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_GADGET:
return 0;
}
+static int service_load_passphrase(struct connman_service *service)
+{
+ GKeyFile *keyfile;
+ gchar *str;
+
+ keyfile = connman_storage_load_service(service->identifier);
+ if (!keyfile)
+ return -EIO;
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Passphrase", NULL);
+ if (str)
+ service->passphrase = str;
+
+ g_key_file_free(keyfile);
+
+ return 0;
+}
+
static int service_load(struct connman_service *service)
{
GKeyFile *keyfile;
case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_VPN:
- service->do_split_routing = g_key_file_get_boolean(keyfile,
- service->identifier, "SplitRouting", NULL);
+ set_split_routing(service, g_key_file_get_boolean(keyfile,
+ service->identifier,
+ "SplitRouting", NULL));
+
autoconnect = g_key_file_get_boolean(keyfile,
service->identifier, "AutoConnect", &error);
if (!error)
service->nameservers_config = NULL;
}
+#ifdef TIZEN_EXT
+ char *dns_method;
+
+ dns_method = g_key_file_get_string(keyfile, service->identifier,
+ "Nameservers.IPv4method", NULL);
+ service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
+
+ dns_method = g_key_file_get_string(keyfile, service->identifier,
+ "Nameservers.IPv6method", NULL);
+ service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
+#endif
+
service->timeservers_config = g_key_file_get_string_list(keyfile,
service->identifier, "Timeservers", &length, NULL);
if (service->timeservers_config && length == 0) {
service->hidden_service = g_key_file_get_boolean(keyfile,
service->identifier, "Hidden", NULL);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "EAP", NULL);
+ if (str != NULL) {
+ g_free(service->eap);
+ service->eap = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Phase2", NULL);
+ if (str != NULL) {
+ g_free(service->phase2);
+ service->phase2 = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Identity", NULL);
+ if (str != NULL) {
+ g_free(service->identity);
+ service->identity = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "CACertFile", NULL);
+ if (str != NULL) {
+ g_free(service->ca_cert_file);
+ service->ca_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "ClientCertFile", NULL);
+ if (str != NULL) {
+ g_free(service->client_cert_file);
+ service->client_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "PrivateKeyFile", NULL);
+ if (str != NULL) {
+ g_free(service->private_key_file);
+ service->private_key_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "PrivateKeyPassphrase", NULL);
+ if (str != NULL) {
+ g_free(service->private_key_passphrase);
+ service->private_key_passphrase = str;
+ }
+ }
+#endif
+
+ if (g_key_file_has_key(keyfile, service->identifier, "UID", NULL))
+ service->user.favorite_user = g_key_file_get_integer(keyfile,
+ service->identifier, "UID", NULL);
done:
g_key_file_free(keyfile);
const unsigned char *ssid;
unsigned int ssid_len = 0;
+ if (service->user.favorite_user == USER_NONE)
+ g_key_file_remove_key(keyfile, service->identifier,
+ "UID", NULL);
+ else
+ g_key_file_set_integer(keyfile, service->identifier,
+ "UID", service->user.favorite_user);
+
ssid = connman_network_get_blob(service->network,
"WiFi.SSID", &ssid_len);
g_free(str);
}
- if (service->passphrase && strlen(service->passphrase) > 0)
- g_key_file_set_string(keyfile, service->identifier,
+ if (service->user.current_user == service->user.favorite_user) {
+ if (service->passphrase && strlen(service->passphrase) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
"Passphrase", service->passphrase);
- else
- g_key_file_remove_key(keyfile, service->identifier,
- "Passphrase", NULL);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Passphrase", NULL);
+ }
if (service->ipconfig_ipv4)
__connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
g_key_file_remove_key(keyfile, service->identifier,
"Nameservers", NULL);
+#if defined TIZEN_EXT
+ if(service->dns_config_method_ipv4 != 0) {
+ const char *method;
+ method = __connman_dnsconfig_method2string(
+ service->dns_config_method_ipv4);
+ g_key_file_set_string(keyfile, service->identifier,
+ "Nameservers.IPv4method", method);
+ } else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Nameservers.IPv4method", NULL);
+
+ if(service->dns_config_method_ipv6 != 0) {
+ const char *method;
+ method = __connman_dnsconfig_method2string(
+ service->dns_config_method_ipv6);
+ g_key_file_set_string(keyfile, service->identifier,
+ "Nameservers.IPv6method", method);
+ } else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Nameservers.IPv6method", NULL);
+#endif
+
if (service->timeservers_config) {
guint len = g_strv_length(service->timeservers_config);
g_key_file_set_string(keyfile, service->identifier,
"Config.ident", service->config_entry);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ if (service->eap != NULL && strlen(service->eap) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "EAP", service->eap);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "EAP", NULL);
+
+ if (service->phase2 != NULL && strlen(service->phase2) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Phase2", service->phase2);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Phase2", NULL);
+
+ if (service->identity != NULL && strlen(service->identity) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Identity", service->identity);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Identity", NULL);
+
+ if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "CACertFile", service->ca_cert_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "CACertFile", NULL);
+
+ if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "ClientCertFile", service->client_cert_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "ClientCertFile", NULL);
+
+ if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "PrivateKeyFile", service->private_key_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "PrivateKeyFile", NULL);
+
+ if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "PrivateKeyPassphrase", service->private_key_passphrase);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "PrivateKeyPassphrase", NULL);
+ }
+#endif
+
done:
__connman_storage_save_service(keyfile, service->identifier);
return result;
}
- static bool is_connecting_state(struct connman_service *service,
- enum connman_service_state state)
+ static bool is_connecting(enum connman_service_state state)
{
switch (state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_IDLE:
case CONNMAN_SERVICE_STATE_FAILURE:
- if (service->network)
- return connman_network_get_connecting(service->network);
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
return false;
}
- static bool is_connected_state(const struct connman_service *service,
- enum connman_service_state state)
+ static bool is_connected(enum connman_service_state state)
{
switch (state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
return false;
}
- static bool is_idle_state(const struct connman_service *service,
- enum connman_service_state state)
+ static bool is_idle(enum connman_service_state state)
{
switch (state) {
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ return true;
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_ASSOCIATION:
case CONNMAN_SERVICE_STATE_CONFIGURATION:
case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
break;
- case CONNMAN_SERVICE_STATE_IDLE:
- return true;
}
return false;
}
- static bool is_connecting(struct connman_service *service)
+ static int nameservers_changed_cb(void *user_data)
{
- return is_connecting_state(service, service->state);
+ struct connman_service *service = user_data;
+
+ DBG("service %p", service);
+
+ service->nameservers_timeout = 0;
+ if ((is_idle(service->state) && !service->nameservers) ||
+ is_connected(service->state))
+ dns_changed(service);
+
+ return FALSE;
}
- static bool is_connected(struct connman_service *service)
+ static void nameservers_changed(struct connman_service *service)
{
- return is_connected_state(service, service->state);
+ if (!service->nameservers_timeout)
+ service->nameservers_timeout = g_idle_add(nameservers_changed_cb,
+ service);
}
static bool nameserver_available(struct connman_service *service,
+ enum connman_ipconfig_type type,
const char *ns)
{
int family;
family = connman_inet_check_ipaddress(ns);
- if (family == AF_INET)
- return is_connected_state(service, service->state_ipv4);
+ if (family == AF_INET) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ return false;
- if (family == AF_INET6)
- return is_connected_state(service, service->state_ipv6);
+ return is_connected(service->state_ipv4);
+ }
+
+ if (family == AF_INET6) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ return false;
+
+ return is_connected(service->state_ipv6);
+ }
return false;
}
+ static int searchdomain_add_all(struct connman_service *service)
+ {
+ int index, i = 0;
+
+ if (!is_connected(service->state))
+ return -ENOTCONN;
+
+ index = __connman_service_get_index(service);
+ if (index < 0)
+ return -ENXIO;
+
+ if (service->domains) {
+ while (service->domains[i]) {
+ connman_resolver_append(index, service->domains[i],
+ NULL);
+ i++;
+ }
+
+ return 0;
+ }
+
+ if (service->domainname)
+ connman_resolver_append(index, service->domainname, NULL);
+
+ return 0;
+
+ }
+
+ static int searchdomain_remove_all(struct connman_service *service)
+ {
+ int index, i = 0;
+
+ if (!is_connected(service->state))
+ return -ENOTCONN;
+
+ index = __connman_service_get_index(service);
+ if (index < 0)
+ return -ENXIO;
+
+ while (service->domains && service->domains[i]) {
+ connman_resolver_remove(index, service->domains[i], NULL);
+ i++;
+ }
+
+ if (service->domainname)
+ connman_resolver_remove(index, service->domainname, NULL);
+
+ return 0;
+ }
+
static int nameserver_add(struct connman_service *service,
+ enum connman_ipconfig_type type,
const char *nameserver)
{
- int index;
+ int index, ret;
- if (!nameserver_available(service, nameserver))
+ if (!nameserver_available(service, type, nameserver))
return 0;
index = __connman_service_get_index(service);
if (index < 0)
return -ENXIO;
- return connman_resolver_append(index, NULL, nameserver);
+#if defined TIZEN_EXT
+ DBG("Resolver append nameserver: %s", nameserver);
+#endif
+ ret = connman_resolver_append(index, NULL, nameserver);
+ if (ret >= 0)
+ nameservers_changed(service);
+
+ return ret;
}
- #if defined TIZEN_EXT
static int nameserver_add_all(struct connman_service *service,
- enum connman_ipconfig_type type)
- #else
- static int nameserver_add_all(struct connman_service *service)
- #endif
+ enum connman_ipconfig_type type)
{
int i = 0;
if (service->nameservers_config) {
while (service->nameservers_config[i]) {
- nameserver_add(service,
+#if defined TIZEN_EXT
+ DBG("type %d add service->nameservers_config[%d]:%s",type,
+ i, service->nameservers_config[i]);
+ if(strncmp(service->nameservers_config[i], "::", 2) == 0) {
+ DBG("Invalid nameserver");
+ i++;
+ continue;
+ }
+
+ switch(type) {
+ case CONNMAN_IPCONFIG_TYPE_IPV4:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_IPV6:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_ALL:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers_config[i]);
+ }
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
- nameserver_add(service, service->nameservers_config[i]);
++ nameserver_add(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
+ DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
+ break;
+ default:
+ DBG("default case do nothing");
+ break;
+ }
+#else
+ nameserver_add(service, type,
+ service->nameservers_config[i]);
+#endif
i++;
}
- #if !defined TIZEN_EXT
- return 0;
- #endif
- }
-
- #if defined TIZEN_EXT
- i = 0;
- #endif
- if (service->nameservers) {
+ } else if (service->nameservers) {
while (service->nameservers[i]) {
- nameserver_add(service,
+#if defined TIZEN_EXT
+ DBG("type %d service->nameservers[%d]: %s",type,
+ i, service->nameservers[i]);
+
+ switch(type) {
+ case CONNMAN_IPCONFIG_TYPE_IPV4:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_IPV6:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_ALL:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
- nameserver_add(service,
++ nameserver_add(service, type,
+ service->nameservers[i]);
+ }
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
- nameserver_add(service, service->nameservers[i]);
++ nameserver_add(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
+ DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
+ break;
+ default:
+ DBG("default case do nothing");
+ break;
+ }
+#else
+ nameserver_add(service, type,
+ service->nameservers[i]);
+#endif
i++;
}
}
+ if (!i)
+ __connman_resolver_append_fallback_nameservers();
+
+ searchdomain_add_all(service);
+
return 0;
}
static int nameserver_remove(struct connman_service *service,
+ enum connman_ipconfig_type type,
const char *nameserver)
{
- int index;
+ int index, ret;
- if (!nameserver_available(service, nameserver))
+ if (!nameserver_available(service, type, nameserver))
return 0;
index = __connman_service_get_index(service);
if (index < 0)
return -ENXIO;
- return connman_resolver_remove(index, NULL, nameserver);
+#if defined TIZEN_EXT
+ DBG("Resolver remove nameserver: %s", nameserver);
+#endif
+ ret = connman_resolver_remove(index, NULL, nameserver);
+ if (ret >= 0)
+ nameservers_changed(service);
+
+ return ret;
}
- #if defined TIZEN_EXT
static int nameserver_remove_all(struct connman_service *service,
- enum connman_ipconfig_type type)
- #else
- static int nameserver_remove_all(struct connman_service *service)
- #endif
+ enum connman_ipconfig_type type)
{
+#if defined TIZEN_EXT
+ /**
+ * Skip this function if there is any connected profiles
+ * that use same interface
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ __connman_service_get_connected_count_of_iface(service) > 0)
+ return 0;
+#endif
int index, i = 0;
index = __connman_service_get_index(service);
return -ENXIO;
while (service->nameservers_config && service->nameservers_config[i]) {
-
+#if defined TIZEN_EXT
+ DBG("type %d Remove service->nameservers_config[%d]: %s",
+ type, i, service->nameservers_config[i]);
+ switch(type) {
+ case CONNMAN_IPCONFIG_TYPE_IPV4:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET &&
+ (service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP ||
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_IPV6:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET6 &&
+ (service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP ||
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_ALL:
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET &&
+ (service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP ||
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers_config[i]);
+ }
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET6 &&
+ (service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP ||
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers_config[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
+ DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
+ break;
+ default:
+ DBG("default case do nothing");
+ break;
+ }
+#else
- nameserver_remove(service, service->nameservers_config[i]);
+ nameserver_remove(service, type,
+ service->nameservers_config[i]);
+#endif
i++;
}
i = 0;
while (service->nameservers && service->nameservers[i]) {
- nameserver_remove(service,
+#if defined TIZEN_EXT
+ DBG("type %d Remove service->nameservers[%d]: %s",type, i,
+ service->nameservers[i]);
+ switch(type) {
+ case CONNMAN_IPCONFIG_TYPE_IPV4:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ (service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL ||
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_IPV6:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ (service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL ||
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_ALL:
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ (service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL ||
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP)) {
- nameserver_remove(service,
++ nameserver_remove(service, type,
+ service->nameservers[i]);
+ }
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ (service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL ||
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP)) {
- nameserver_remove(service, service->nameservers[i]);
++ nameserver_remove(service, type,
+ service->nameservers[i]);
+ }
+ break;
+ case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
+ DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
+ break;
+ default:
+ DBG("default case do nothing");
+ break;
+ }
+#else
+ nameserver_remove(service, type, service->nameservers[i]);
+#endif
i++;
}
- return 0;
- }
-
- static int searchdomain_add_all(struct connman_service *service)
- {
- int index, i = 0;
-
- if (!is_connected(service))
- return -ENOTCONN;
-
- index = __connman_service_get_index(service);
- if (index < 0)
- return -ENXIO;
-
- if (service->domains) {
- while (service->domains[i]) {
- connman_resolver_append(index, service->domains[i],
- NULL);
- i++;
- }
-
- return 0;
- }
-
- if (service->domainname)
- connman_resolver_append(index, service->domainname, NULL);
-
- return 0;
-
- }
-
- static int searchdomain_remove_all(struct connman_service *service)
- {
- int index, i = 0;
-
- if (!is_connected(service))
- return -ENOTCONN;
-
- index = __connman_service_get_index(service);
- if (index < 0)
- return -ENXIO;
-
- while (service->domains && service->domains[i]) {
- connman_resolver_remove(index, service->domains[i], NULL);
- i++;
- }
-
- if (service->domainname)
- connman_resolver_remove(index, service->domainname, NULL);
+ searchdomain_remove_all(service);
return 0;
}
* inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt()
* for details) and not through service.c
*/
+#if defined TIZEN_EXT
+int __connman_service_nameserver_append(struct connman_service *service,
+ const char *nameserver, bool is_auto,
+ enum connman_ipconfig_type type)
+#else
int __connman_service_nameserver_append(struct connman_service *service,
const char *nameserver, bool is_auto)
+#endif
{
char **nameservers;
int len, i;
- DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
+ DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
if (!nameserver)
return -EINVAL;
nameservers = service->nameservers;
for (i = 0; nameservers && nameservers[i]; i++)
+#if defined TIZEN_EXT
+ {
+ DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
+#endif
if (g_strcmp0(nameservers[i], nameserver) == 0)
return -EEXIST;
+#if defined TIZEN_EXT
+ }
+#endif
if (nameservers) {
len = g_strv_length(nameservers);
nameservers[len] = g_strdup(nameserver);
nameservers[len + 1] = NULL;
- service->dns_config_method_ipv4 ==
- CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
+#ifdef TIZEN_EXT
+ if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- service->dns_config_method_ipv6 ==
- CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
++ service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
+ service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
+
+ if(type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
++ service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
+ service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP;
+#endif
+
if (is_auto) {
service->nameservers_auto = nameservers;
} else {
service->nameservers = nameservers;
- #if defined TIZEN_EXT
- DBG("nameserver add: %s, type: %d", nameserver, type);
- #endif
- nameserver_add(service, nameserver);
+ nameserver_add(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver);
}
+ nameservers_changed(service);
+
+ searchdomain_add_all(service);
+
return 0;
}
+#if defined TIZEN_EXT
+int __connman_service_nameserver_remove(struct connman_service *service,
+ const char *nameserver, bool is_auto,
+ enum connman_ipconfig_type type)
+#else
int __connman_service_nameserver_remove(struct connman_service *service,
const char *nameserver, bool is_auto)
+#endif
{
char **servers, **nameservers;
bool found = false;
if (!nameservers)
return 0;
- for (i = 0; nameservers && nameservers[i]; i++)
+ for (i = 0; nameservers[i]; i++)
if (g_strcmp0(nameservers[i], nameserver) == 0) {
found = true;
break;
service->nameservers_auto = nameservers;
} else {
service->nameservers = nameservers;
- nameserver_remove(service, nameserver);
+#if defined TIZEN_EXT
+ DBG("nameserver remove ip_type: %d", type);
++ nameserver_remove(service, type,
++ nameserver);
++#else
+ nameserver_remove(service, CONNMAN_IPCONFIG_TYPE_ALL,
+ nameserver);
+#endif
}
return 0;
void __connman_service_nameserver_clear(struct connman_service *service)
{
- #if defined TIZEN_EXT
- DBG("nameserver remove all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
- #else
- nameserver_remove_all(service);
- #endif
g_strfreev(service->nameservers);
service->nameservers = NULL;
- #if defined TIZEN_EXT
- DBG("nameserver add all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
- #else
- nameserver_add_all(service);
- #endif
-
}
static void add_nameserver_route(int family, int index, char *nameserver,
nameserver_del_routes(index, service->nameservers, type);
}
+ static void address_updated(struct connman_service *service,
+ enum connman_ipconfig_type type)
+ {
+ if (is_connected(service->state) &&
+ service == __connman_service_get_default()) {
+ nameserver_remove_all(service, type);
+ nameserver_add_all(service, type);
+
+ __connman_timeserver_sync(service);
+ }
+ }
+
static struct connman_stats *stats_get(struct connman_service *service)
{
if (service->roaming)
g_timer_reset(service->stats_roaming.timer);
}
- is_connected(service) == TRUE) {
+#if defined TIZEN_EXT
+static gboolean __connman_service_is_internet_profile(
+ struct connman_service *cellular)
+{
+ const char internet_suffix[] = "_1";
+
+ DBG("Service path: %s", cellular->path);
+
+ if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean __connman_service_is_tethering_profile(
+ struct connman_service *cellular)
+{
+ const char tethering_suffix[] = "_5";
+
+ DBG("Service path: %s", cellular->path);
+
+ if (g_str_has_suffix(cellular->path, tethering_suffix) == TRUE)
+ return TRUE;
+
+ return FALSE;
+}
+
+struct connman_service *connman_service_get_default_connection(void)
+{
+ GList *list;
+ struct connman_service *service;
+ struct connman_service *default_service = NULL;
+
+ for (list = service_list; list; list = list->next) {
+ service = list->data;
+
+ DBG("service: %p %s %s %s", service, service->name,
+ state2string(service->state),
+ __connman_service_type2string(service->type));
+
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
- else if (is_connected(service) == TRUE &&
- is_connected(default_service) == FALSE)
++ is_connected(service->state) == TRUE) {
+ return service;
+ } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ __connman_service_is_internet_profile(service) == TRUE) {
+ if (default_service == NULL)
+ default_service = service;
- is_connected(service) == TRUE) {
++ else if (is_connected(service->state) == TRUE &&
++ is_connected(default_service->state) == FALSE)
+ default_service = service;
+ } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
- is_connected(service) == TRUE) {
++ is_connected(service->state) == TRUE) {
+ if (default_service == NULL)
+ default_service = service;
+ } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH &&
++ is_connected(service->state) == TRUE) {
+ if (default_service == NULL)
+ default_service = service;
+ }
+ }
+
+ return default_service;
+}
+#endif
+
struct connman_service *__connman_service_get_default(void)
{
struct connman_service *service;
service = service_list->data;
- if (!is_connected(service))
+ if (!is_connected(service->state))
return NULL;
return service;
current_default ? current_default->identifier : "");
DBG("new default %p %s", service, service ? service->identifier : "");
+#if defined TIZEN_EXT
+ current_default = service;
+
+ __connman_service_timeserver_changed(service, NULL);
+#else
__connman_service_timeserver_changed(current_default, NULL);
current_default = service;
+#endif
if (service) {
if (service->hostname &&
if (!str)
return;
+#if !defined TIZEN_EXT
if (!allow_property_changed(service))
return;
-
+#endif
+#if defined TIZEN_EXT
+ DBG(" %s, %s", str, service->path);
+#endif
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "State",
DBUS_TYPE_STRING, &str);
{
struct connman_service *service = user_data;
- if (!is_connected_state(service, service->state_ipv4))
+ if (!is_connected(service->state_ipv4))
return;
if (service->ipconfig_ipv4)
{
struct connman_service *service = user_data;
- if (!is_connected_state(service, service->state_ipv6))
+ if (!is_connected(service->state_ipv6))
return;
if (service->ipconfig_ipv6)
for (i = 0; servers[i]; i++) {
if (service)
- available = nameserver_available(service, servers[i]);
-
- DBG("servers[%d] %s available %d", i, servers[i], available);
+ available = nameserver_available(service,
+ CONNMAN_IPCONFIG_TYPE_ALL,
+ servers[i]);
if (available)
dbus_message_iter_append_basic(iter,
}
}
- available = nameserver_available(service, server);
+#if defined TIZEN_EXT
+static void append_nameserver_manual(DBusMessageIter *iter,
+ struct connman_service *service, const char *server)
+{
+ bool available = true;
+
+ if (service)
- available = nameserver_available(service, server);
++ available = nameserver_available(service,
++ CONNMAN_IPCONFIG_TYPE_ALL, server);
+
+ if (available)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &server);
+}
+
+static void append_nameserver_dhcp(DBusMessageIter *iter,
+ struct connman_service *service, const char *server)
+{
+ bool available = true;
+
+ if (service)
++ available = nameserver_available(service,
++ CONNMAN_IPCONFIG_TYPE_ALL, server);
+
+ if (available)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &server);
+}
+#endif
+
static void append_dns(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
+#if defined TIZEN_EXT
+ int i;
+#endif
- if (!is_connected(service))
+ if (!is_connected(service->state))
return;
+#ifdef TIZEN_EXT
+ const char *str;
+
+ str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
+ if(str != NULL) {
+ char *str1 = g_strdup_printf("ipv4.%s", str);
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str1);
+ g_free(str1);
+ }
+
+ str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
+ if(str != NULL) {
+ char *str1 = g_strdup_printf("ipv6.%s", str);
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str1);
+ g_free(str1);
+ }
+#endif
+
if (service->nameservers_config) {
+#if defined TIZEN_EXT
+ i = 0;
+ while (service->nameservers_config[i]) {
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ append_nameserver_manual(iter, service,
+ service->nameservers_config[i]);
+ }
+
+ if (connman_inet_check_ipaddress(
+ service->nameservers_config[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ append_nameserver_manual(iter, service,
+ service->nameservers_config[i]);
+ }
+ i++;
+ }
+ /* In case of mixed DNS Config Type one of IPv4/IPv6 can be
+ * dynamic while other is static so try to append the DNS
+ * Address which is dynamic also */
+ if (service->nameservers != NULL) {
+ i = 0;
+ while (service->nameservers[i]) {
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ append_nameserver_dhcp(iter, service,
+ service->nameservers[i]);
+ }
+
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ append_nameserver_dhcp(iter, service,
+ service->nameservers[i]);
+ }
+ i++;
+ }
+ }
+#else
append_nameservers(iter, service, service->nameservers_config);
+#endif
return;
} else {
if (service->nameservers)
+#if defined TIZEN_EXT
+ {
+ i = 0;
+ while (service->nameservers[i]) {
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET &&
+ service->dns_config_method_ipv4 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ append_nameserver_dhcp(iter, service,
+ service->nameservers[i]);
+ }
+
+ if (connman_inet_check_ipaddress(
+ service->nameservers[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 ==
+ CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ append_nameserver_dhcp(iter, service,
+ service->nameservers[i]);
+ }
+ i++;
+ }
+ }
+#else
append_nameservers(iter, service,
service->nameservers);
+#endif
if (service->nameservers_auto)
append_nameservers(iter, service,
{
struct connman_service *service = user_data;
+#ifdef TIZEN_EXT
+ /* Append DNS Config Type */
+ const char *str;
+ str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
+ if(str != NULL) {
+ char *str1 = g_strdup_printf("ipv4.%s", str);
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str1);
+ g_free(str1);
+ }
+
+ str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
+ if(str != NULL) {
+ char *str1 = g_strdup_printf("ipv6.%s", str);
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str1);
+ g_free(str1);
+ }
+#endif
+
if (!service->nameservers_config)
return;
+#if defined TIZEN_EXT
+ int i = 0;
+ while (service->nameservers_config[i]) {
+ if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET &&
+ service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
+ }
+
+ if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET6 &&
+ service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
+ }
+ i++;
+ }
+#else
append_nameservers(iter, NULL, service->nameservers_config);
+#endif
}
static void append_ts(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (!is_connected(service) &&
- !is_connecting(service))
+ if (!is_connected(service->state) &&
+ !is_connecting(service->state))
return;
if (service->domains)
const char *method = proxymethod2string(
CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
- if (!is_connected(service))
+ if (!is_connected(service->state))
return;
proxy = connman_service_get_proxy_method(service);
{
struct connman_service *service = user_data;
- if (!is_connected(service))
+ if (!is_connected(service->state))
return;
if (service->provider)
{
enum connman_ipconfig_type type;
+ type = __connman_ipconfig_get_config_type(ipconfig);
+
+ __connman_notifier_ipconfig_changed(service, ipconfig);
+
if (!allow_property_changed(service))
return;
- type = __connman_ipconfig_get_config_type(ipconfig);
-
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
connman_dbus_property_changed_dict(service->path,
CONNMAN_SERVICE_INTERFACE, "IPv4",
connman_dbus_property_changed_dict(service->path,
CONNMAN_SERVICE_INTERFACE, "IPv6",
append_ipv6, service);
-
- __connman_notifier_ipconfig_changed(service, ipconfig);
}
static void ipv4_configuration_changed(struct connman_service *service)
service);
}
+ void __connman_service_notify_ipv4_configuration(
+ struct connman_service *service)
+ {
+ if (!service)
+ return;
+
+ ipv4_configuration_changed(service);
+ }
+
static void ipv6_configuration_changed(struct connman_service *service)
{
if (!allow_property_changed(service))
if (!service)
return;
- if (!is_connected(service))
+ if (!is_connected(service->state))
return;
stats_update(service,
return 0;
}
+#if defined TIZEN_EXT
+static void append_wifi_ext_info(DBusMessageIter *dict,
+ struct connman_network *network)
+{
+ char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char *bssid_str = bssid_buff;
+ const void *ssid;
+ unsigned int ssid_len;
+ unsigned char *bssid;
+ unsigned int maxrate;
+ unsigned int keymgmt;
+ uint16_t frequency;
+ const char *enc_mode;
+ const char *str;
+ gboolean passpoint;
+
+ ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
+ bssid = connman_network_get_bssid(network);
+ maxrate = connman_network_get_maxrate(network);
+ frequency = connman_network_get_frequency(network);
+ enc_mode = connman_network_get_enc_mode(network);
+ passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
+ keymgmt = connman_network_get_keymgmt(network);
+
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5]);
+
+ connman_dbus_dict_append_fixed_array(dict, "SSID",
+ DBUS_TYPE_BYTE, &ssid, ssid_len);
+ connman_dbus_dict_append_basic(dict, "BSSID",
+ DBUS_TYPE_STRING, &bssid_str);
+ connman_dbus_dict_append_basic(dict, "MaxRate",
+ DBUS_TYPE_UINT32, &maxrate);
+ connman_dbus_dict_append_basic(dict, "Frequency",
+ DBUS_TYPE_UINT16, &frequency);
+ connman_dbus_dict_append_basic(dict, "EncryptionMode",
+ DBUS_TYPE_STRING, &enc_mode);
+ connman_dbus_dict_append_basic(dict, "Passpoint",
+ DBUS_TYPE_BOOLEAN, &passpoint);
+ connman_dbus_dict_append_basic(dict, "Keymgmt",
+ DBUS_TYPE_UINT32, &keymgmt);
+
+ str = connman_network_get_string(network, "WiFi.Security");
+ if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
+ str = connman_network_get_string(network, "WiFi.EAP");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "EAP",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.Phase2");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "Phase2",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.Identity");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "Identity",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.CACertFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "CACertFile",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network,
+ "WiFi.ClientCertFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "ClientCertFile",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network,
+ "WiFi.PrivateKeyFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "PrivateKeyFile",
+ DBUS_TYPE_STRING, &str);
+ }
+}
+#endif
+
static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
struct connman_service *service)
{
const char *str;
GSList *list;
-
- unsigned char *wifi_vsie;
+#if defined TIZEN_EXT
+ unsigned int frequency = 0U;
+ if (service && service->network) {
+ frequency = connman_network_get_frequency(service->network);
+ connman_dbus_dict_append_basic(dict, "Frequency",
+ DBUS_TYPE_UINT16, &frequency);
+ }
- GSList *vsie_list = NULL;
-
- if (service->network)
- vsie_list = (GSList *)connman_network_get_vsie_list(service->network);
-
- if (vsie_list) {
- DBG("ConnMan, service->path=%s No.of elements in list: %d", service->path, g_slist_length(vsie_list));
- GSList *list;
- for (list = vsie_list; list; list = list->next) {
- wifi_vsie = (unsigned char *)list->data;
- wifi_vsie_len = wifi_vsie[1] + 2;
-
- connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
- &wifi_vsie, wifi_vsie_len);
- }
++ const void *wifi_vsie;
+ unsigned int wifi_vsie_len;
++ wifi_vsie = connman_network_get_blob(service->network, "WiFi.Vsie", &wifi_vsie_len);
++ if(wifi_vsie_len > 0) {
++ DBG("ConnMan, service->path=%s vsie length=%d", service->path, wifi_vsie_len);
+ }
++ connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
++ &wifi_vsie, wifi_vsie_len);
+#endif
+
str = __connman_service_type2string(service->type);
if (str)
connman_dbus_dict_append_basic(dict, "Type",
connman_dbus_dict_append_basic(dict, "State",
DBUS_TYPE_STRING, &str);
+#ifdef TIZEN_EXT
+ str = state2string(service->state_ipv6);
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "StateIPv6",
+ DBUS_TYPE_STRING, &str);
+#endif
+
str = error2string(service->error);
if (str)
connman_dbus_dict_append_basic(dict, "Error",
append_ethernet, service);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+#if defined TIZEN_EXT
+ if (service->network != NULL)
+ append_wifi_ext_info(dict, service->network);
+
+ connman_dbus_dict_append_dict(dict, "Ethernet",
+ append_ethernet, service);
+
+ connman_dbus_dict_append_basic(dict, "DisconnectReason",
+ DBUS_TYPE_INT32, &service->disconnect_reason);
+
+ connman_dbus_dict_append_basic(dict, "AssocStatusCode",
+ DBUS_TYPE_INT32, &service->assoc_status_code);
+
+ break;
+#endif
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_GADGET:
return service->timeservers;
}
+#if defined TIZEN_EXT
+/*
+ * Description: Telephony plug-in requires manual PROXY setting function
+ */
+int connman_service_set_proxy(struct connman_service *service,
+ const char *proxy, gboolean active)
+{
+ char **proxies_array = NULL;
+
+ if (service == NULL)
+ return -EINVAL;
+
+ switch (service->type) {
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ g_strfreev(service->proxies);
+ service->proxies = NULL;
+
+ if (proxy != NULL)
+ proxies_array = g_strsplit(proxy, " ", 0);
+
+ service->proxies = proxies_array;
+
+ if (proxy == NULL) {
+ service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
+ DBG("proxy changed (%d)", active);
+ } else {
+ service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
+ DBG("proxy chagned %s (%d)", proxy, active);
+ }
+
+ if (active == TRUE) {
+ proxy_changed(service);
+
+ __connman_notifier_proxy_changed(service);
+ }
+
+ return 0;
+}
+#endif
+
void connman_service_set_proxy_method(struct connman_service *service,
enum connman_service_proxy_method method)
{
return NULL;
}
+#if defined TIZEN_EXT
+int connman_service_get_ipv6_dns_method(struct connman_service *service)
+{
+ if (!service) {
+ DBG("Service is NULL");
+ return -1;
+ }
+
+ return service->dns_config_method_ipv6;
+}
+#endif
+
void __connman_service_set_timeservers(struct connman_service *service,
char **timeservers)
{
proxy_changed(service);
}
+#if defined TIZEN_EXT
+void __connman_service_set_proxy(struct connman_service *service,
+ const char *proxies)
+{
+ char **proxies_array = NULL;
+
+ g_strfreev(service->proxies);
+ service->proxies = NULL;
+
+ if (proxies != NULL)
+ proxies_array = g_strsplit(proxies, " ", 0);
+
+ service->proxies = proxies_array;
+}
+#endif
+
void __connman_service_set_identity(struct connman_service *service,
const char *identity)
{
service->identity);
}
+ void __connman_service_set_anonymous_identity(struct connman_service *service,
+ const char *anonymous_identity)
+ {
+ if (service->immutable || service->hidden)
+ return;
+
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = g_strdup(anonymous_identity);
+
+ if (service->network)
+ connman_network_set_string(service->network,
+ "WiFi.AnonymousIdentity",
+ service->anonymous_identity);
+ }
+
+ void __connman_service_set_subject_match(struct connman_service *service,
+ const char *subject_match)
+ {
+ if (service->immutable || service->hidden)
+ return;
+
+ g_free(service->subject_match);
+ service->subject_match = g_strdup(subject_match);
+
+ if (service->network)
+ connman_network_set_string(service->network,
+ "WiFi.SubjectMatch",
+ service->subject_match);
+ }
+
+ void __connman_service_set_altsubject_match(struct connman_service *service,
+ const char *altsubject_match)
+ {
+ if (service->immutable || service->hidden)
+ return;
+
+ g_free(service->altsubject_match);
+ service->altsubject_match = g_strdup(altsubject_match);
+
+ if (service->network)
+ connman_network_set_string(service->network,
+ "WiFi.AltSubjectMatch",
+ service->altsubject_match);
+ }
+
+ void __connman_service_set_domain_suffix_match(struct connman_service *service,
+ const char *domain_suffix_match)
+ {
+ if (service->immutable || service->hidden)
+ return;
+
+ g_free(service->domain_suffix_match);
+ service->domain_suffix_match = g_strdup(domain_suffix_match);
+
+ if (service->network)
+ connman_network_set_string(service->network,
+ "WiFi.DomainSuffixMatch",
+ service->domain_suffix_match);
+ }
+
+ void __connman_service_set_domain_match(struct connman_service *service,
+ const char *domain_match)
+ {
+ if (service->immutable || service->hidden)
+ return;
+
+ g_free(service->domain_match);
+ service->domain_match = g_strdup(domain_match);
+
+ if (service->network)
+ connman_network_set_string(service->network,
+ "WiFi.DomainMatch",
+ service->domain_match);
+ }
+
void __connman_service_set_agent_identity(struct connman_service *service,
const char *agent_identity)
{
service->agent_identity);
}
- static int check_passphrase(enum connman_service_security security,
+ int __connman_service_check_passphrase(enum connman_service_security security,
const char *passphrase)
{
guint i;
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
case CONNMAN_SERVICE_SECURITY_WPA:
+#if !defined TIZEN_EXT
case CONNMAN_SERVICE_SECURITY_RSN:
+#endif
DBG("service security '%s' (%d) not handled",
security2string(security), security);
return -EOPNOTSUPP;
case CONNMAN_SERVICE_SECURITY_PSK:
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_SECURITY_RSN:
+#endif
/* A raw key is always 64 bytes length,
* its content is in hex representation.
* A PSK key must be between [8..63].
if (service->immutable &&
service->security != CONNMAN_SERVICE_SECURITY_8021X)
return -EINVAL;
-
+#if defined TIZEN_EXT
+ /* The encrypted passphrase is used here
+ * and validation is done by net-config before being encrypted.
+ */
+ if (service->security != CONNMAN_SERVICE_SECURITY_PSK &&
+ service->security != CONNMAN_SERVICE_SECURITY_RSN &&
+ service->security != CONNMAN_SERVICE_SECURITY_WEP)
+#endif
- err = check_passphrase(service->security, passphrase);
+ err = __connman_service_check_passphrase(service->security, passphrase);
if (err < 0)
return err;
DBusMessage *reply;
DBusMessageIter array, dict;
- DBG("service %p", service);
-
reply = dbus_message_new_method_return(msg);
if (!reply)
return NULL;
return reply;
}
+ static char **remove_empty_strings(char **strv)
+ {
+ int index = 0;
+ char **iter = strv;
+
+ while (*iter) {
+ if (**iter)
+ strv[index++] = *iter;
+ else
+ g_free(*iter);
+ iter++;
+ }
+
+ strv[index] = NULL;
+ return strv;
+ }
+
static int update_proxy_configuration(struct connman_service *service,
DBusMessageIter *array)
{
if (servers_str) {
g_strfreev(service->proxies);
- if (servers_str->len > 0)
- service->proxies = g_strsplit_set(
+ if (servers_str->len > 0) {
+ char **proxies = g_strsplit_set(
servers_str->str, " ", 0);
- else
+ proxies = remove_empty_strings(proxies);
+ service->proxies = proxies;
+ } else
service->proxies = NULL;
}
if (excludes_str) {
g_strfreev(service->excludes);
- if (excludes_str->len > 0)
- service->excludes = g_strsplit_set(
+ if (excludes_str->len > 0) {
+ char **excludes = g_strsplit_set(
excludes_str->str, " ", 0);
- else
+ excludes = remove_empty_strings(excludes);
+ service->excludes = excludes;
+ } else
service->excludes = NULL;
}
g_free(service->pac);
if (url && strlen(url) > 0)
- service->pac = g_strdup(url);
+ service->pac = g_strstrip(g_strdup(url));
else
service->pac = NULL;
new_method = __connman_ipconfig_get_method(new_ipconfig);
}
- if (is_connecting_state(service, state) ||
- is_connected_state(service, state))
+ if (is_connecting(state) || is_connected(state))
__connman_network_clear_ipconfig(service->network, ipconfig);
__connman_ipconfig_unref(ipconfig);
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
service->ipconfig_ipv6 = new_ipconfig;
- if (is_connecting_state(service, state) ||
- is_connected_state(service, state))
+ if (is_connecting(state) || is_connected(state))
__connman_ipconfig_enable(new_ipconfig);
if (new_state && new_method != old_method) {
else
*new_state = service->state_ipv6;
+ settings_changed(service, new_ipconfig);
+ address_updated(service, new_method);
+
__connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
return __connman_error_invalid_arguments(msg);
- if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service)) {
++ if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service->state)) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (!connman_service_is_user_allowed(service, uid)) {
+ DBG("Not allow this user to operate this wifi service now!");
+ return __connman_error_permission_denied(msg);
+ }
+ }
+
dbus_message_iter_get_basic(&iter, &name);
dbus_message_iter_next(&iter);
GString *str;
int index;
const char *gw;
+#if defined TIZEN_EXT
+ enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
+ DBG("%s", name);
+#endif
if (__connman_provider_is_immutable(service->provider) ||
service->immutable)
gw = __connman_ipconfig_get_gateway_from_index(index,
CONNMAN_IPCONFIG_TYPE_ALL);
++#if !defined TIZEN_EXT
if (gw && strlen(gw))
__connman_service_nameserver_del_routes(service,
CONNMAN_IPCONFIG_TYPE_ALL);
--
++#endif
dbus_message_iter_recurse(&value, &entry);
+#if defined TIZEN_EXT
+ /* IPv4/IPv6 Last DNS config method */
+ int last_dns_ipv4 = service->dns_config_method_ipv4;
+ int last_dns_ipv6 = service->dns_config_method_ipv6;
+ DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
+#endif
+
while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
const char *val;
dbus_message_iter_get_basic(&entry, &val);
dbus_message_iter_next(&entry);
+#ifdef TIZEN_EXT
+ /* First unpack the DNS Config Method */
+ DBG("DNS Config Method: %s", val);
+ if((g_strcmp0(val, "ipv4.manual") == 0)) {
+ service->dns_config_method_ipv4 =
+ CONNMAN_DNSCONFIG_METHOD_MANUAL;
+
+ if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
+ ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
+ else
+ ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
+ }
+ continue;
+ } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
+ service->dns_config_method_ipv4 =
+ CONNMAN_DNSCONFIG_METHOD_DHCP;
+ if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
+ ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
- if (connman_inet_check_ipaddress(val) > 0) {
- if (str->len > 0)
- g_string_append_printf(str, " %s", val);
- else
- g_string_append(str, val);
- }
+ continue;
+ } else if(g_strcmp0(val, "ipv6.manual") == 0) {
+ service->dns_config_method_ipv6 =
+ CONNMAN_DNSCONFIG_METHOD_MANUAL;
+ if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
+ if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
+ ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
+ else
+ ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
+ }
+ continue;
+ } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
+ service->dns_config_method_ipv6 =
+ CONNMAN_DNSCONFIG_METHOD_DHCP;
+ if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
+ ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
+
+ continue;
+ }
+#endif
+ if (!val[0])
+ continue;
+
+ if (str->len > 0)
+ g_string_append_printf(str, " %s", val);
+ else
+ g_string_append(str, val);
}
- nameserver_remove_all(service);
+#if defined TIZEN_EXT
+ if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
+ service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
+ DBG("Both IPv4 and IPv6 DNS Method DHCP");
+ ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
+ }
+ if (gw && strlen(gw))
+ __connman_service_nameserver_del_routes(service,
+ ip_type);
+
+ DBG("%s ip_type: %d nameserver remove all", name, ip_type);
+ nameserver_remove_all(service, ip_type);
+#else
+ nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
+#endif
g_strfreev(service->nameservers_config);
if (str->len > 0) {
- service->nameservers_config =
- g_strsplit_set(str->str, " ", 0);
+ char **nameservers, **iter;
+
+ nameservers = g_strsplit_set(str->str, " ", 0);
+
+ for (iter = nameservers; *iter; iter++)
+ if (connman_inet_check_ipaddress(*iter) <= 0)
+ *iter[0] = '\0';
+
+ nameservers = remove_empty_strings(nameservers);
+ service->nameservers_config = nameservers;
} else {
service->nameservers_config = NULL;
}
if (gw && strlen(gw))
__connman_service_nameserver_add_routes(service, gw);
- nameserver_add_all(service);
+#if defined TIZEN_EXT
+ DBG("%s ip_type: %d nameserver add all", name, ip_type);
+ nameserver_add_all(service, ip_type);
+#else
+ nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
+#endif
dns_configuration_changed(service);
if (__connman_service_is_connected_state(service,
service_save(service);
} else if (g_str_equal(name, "Timeservers.Configuration")) {
DBusMessageIter entry;
- GSList *list = NULL;
- int count = 0;
+ GString *str;
if (service->immutable)
return __connman_error_not_supported(msg);
if (type != DBUS_TYPE_ARRAY)
return __connman_error_invalid_arguments(msg);
+ str = g_string_new(NULL);
+ if (!str)
+ return __connman_error_invalid_arguments(msg);
+
dbus_message_iter_recurse(&value, &entry);
while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
const char *val;
- GSList *new_head;
-
dbus_message_iter_get_basic(&entry, &val);
+ dbus_message_iter_next(&entry);
- new_head = __connman_timeserver_add_list(list, val);
- if (list != new_head) {
- count++;
- list = new_head;
- }
+ if (!val[0])
+ continue;
- dbus_message_iter_next(&entry);
+ if (str->len > 0)
+ g_string_append_printf(str, " %s", val);
+ else
+ g_string_append(str, val);
}
g_strfreev(service->timeservers_config);
service->timeservers_config = NULL;
- if (list) {
- service->timeservers_config = g_new0(char *, count+1);
+ if (str->len > 0) {
+ char **timeservers = g_strsplit_set(str->str, " ", 0);
+ timeservers = remove_empty_strings(timeservers);
+ service->timeservers_config = timeservers;
+ } else
+ service->timeservers = NULL;
- while (list) {
- count--;
- service->timeservers_config[count] = list->data;
- list = g_slist_delete_link(list, list);
- };
- }
+ g_string_free(str, TRUE);
service_save(service);
timeservers_configuration_changed(service);
const char *val;
dbus_message_iter_get_basic(&entry, &val);
dbus_message_iter_next(&entry);
+
+ if (!val[0])
+ continue;
+
if (str->len > 0)
g_string_append_printf(str, " %s", val);
else
searchdomain_remove_all(service);
g_strfreev(service->domains);
- if (str->len > 0)
- service->domains = g_strsplit_set(str->str, " ", 0);
- else
+ if (str->len > 0) {
+ char **domains = g_strsplit_set(str->str, " ", 0);
+ domains = remove_empty_strings(domains);
+ service->domains = domains;
+ } else
service->domains = NULL;
g_string_free(str, TRUE);
&state);
if (err < 0) {
- if (is_connected_state(service, state) ||
- is_connecting_state(service, state)) {
+ if (is_connected(state) || is_connecting(state)) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
__connman_network_enable_ipconfig(service->network,
service->ipconfig_ipv4);
else
ipv6_configuration_changed(service);
- if (is_connecting(service) || is_connected(service)) {
+ if (is_connecting(service->state) ||
+ is_connected(service->state)) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
__connman_network_enable_ipconfig(service->network,
service->ipconfig_ipv4);
if (!service->path)
return;
+#if !defined TIZEN_EXT
if (!allow_property_changed(service))
return;
+#endif
str = error2string(service->error);
DBUS_TYPE_STRING, &str);
}
+ static void remove_timeout(struct connman_service *service)
+ {
+ if (service->timeout > 0) {
+ g_source_remove(service->timeout);
+ service->timeout = 0;
+ }
+ }
+
+ static void reply_pending(struct connman_service *service, int error)
+ {
+ remove_timeout(service);
+
+ if (service->pending) {
+ connman_dbus_reply_pending(service->pending, error, NULL);
+ service->pending = NULL;
+ }
+
+ if (service->provider_pending) {
+ connman_dbus_reply_pending(service->provider_pending,
+ error, service->path);
+ service->provider_pending = NULL;
+ }
+ }
+
+ static void service_complete(struct connman_service *service)
+ {
+ reply_pending(service, EIO);
+
+ if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
+ __connman_service_auto_connect(service->connect_reason);
+
+ g_get_current_time(&service->modified);
+ service_save(service);
+ }
+
+static void set_idle(struct connman_service *service)
+{
+ service->state = service->state_ipv4 = service->state_ipv6 =
+ CONNMAN_SERVICE_STATE_IDLE;
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
+ state_changed(service);
+}
+
static DBusMessage *clear_property(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
if (g_str_equal(name, "Error")) {
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- g_get_current_time(&service->modified);
- service_save(service);
+ __connman_service_clear_error(service);
+ service_complete(service);
} else
return __connman_error_invalid_property(msg);
}
static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
+ static int always_connect[MAX_CONNMAN_SERVICE_TYPES] = {};
static int active_count = 0;
void __connman_service_set_active_session(bool enable, GSList *list)
else
active_count--;
- while (list != NULL) {
+ while (list) {
enum connman_service_type type = GPOINTER_TO_INT(list->data);
switch (type) {
for (list = service_list; list; list = list->next) {
struct connman_service *service = list->data;
- if (!is_connected(service))
+ if (!is_connected(service->state))
break;
if (service->connect_reason ==
CONNMAN_SERVICE_CONNECT_REASON_USER) {
DBG("service %p name %s is user connected",
service, service->name);
+#if defined TIZEN_EXT
+ /* We can connect to a favorite service like
+ * wifi even we have a userconnect for cellular
+ * because we have refount for cellular service
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ break;
+
+ if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
+ break;
+#endif
return NULL;
}
}
return tech_data.preferred_list;
}
+ static void set_always_connecting_technologies()
+ {
+ unsigned int *always_connected_techs =
+ connman_setting_get_uint_list("AlwaysConnectedTechnologies");
+ int i;
+ for (i = 0; always_connected_techs && always_connected_techs[i]; i++)
+ always_connect[always_connected_techs[i]] = 1;
+ }
+
+ static bool autoconnect_no_session_active(struct connman_service *service)
+ {
+ /*
+ * Test active_count to see if there are no sessions set up and
+ * stop autoconnecting, but continue connecting if the service
+ * belongs to a technology which should always autoconnect.
+ */
+ if (!active_count && !always_connect[service->type])
+ return true;
+
+ return false;
+ }
+
+ static bool autoconnect_already_connecting(struct connman_service *service,
+ bool autoconnecting)
+ {
+ /*
+ * If another service is already connecting and this service type has
+ * not been marked as always connecting, stop the connecting procedure.
+ */
+ if (autoconnecting &&
+ !active_sessions[service->type] &&
+ !always_connect[service->type])
+ return true;
+
+ return false;
+ }
+
static bool auto_connect_service(GList *services,
enum connman_service_connect_reason reason,
bool preferred)
continue;
}
- if (is_connecting(service) == TRUE || is_connected(service) == TRUE)
+#if defined TIZEN_EXT
+ DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
+ service, service->name,
+ state2string(service->state),
+ __connman_service_type2string(service->type),
+ service->favorite, is_ignore(service),
+ service->hidden, service->hidden_service);
+
+ /* Tizen takes Wi-Fi as the highest priority into consideration. */
+ if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
++ if (is_connecting(service->state) == TRUE || is_connected(service->state) == TRUE)
+ continue;
+#endif
+
if (service->pending ||
- is_connecting(service) ||
- is_connected(service)) {
- if (!active_count)
- return true;
+ is_connecting(service->state) ||
+ is_connected(service->state)) {
+ if (autoconnect_no_session_active(service))
+ return true;
ignore[service->type] = true;
autoconnecting = true;
if (preferred)
continue;
+#if defined TIZEN_EXT
+ DBG("Service is not favorite, autoconnecting %d",
+ autoconnecting);
+#endif
return autoconnecting;
}
+#if defined TIZEN_EXT
+ DBG("service %p identifier %s roaming %d ignore %d "
+ "ipconfig_usable %d autoconnect %d state %d",
+ service,
+ service->identifier, service->roaming,
+ service->ignore, is_ipconfig_usable(service),
+ service->autoconnect, service->state);
+#endif
if (is_ignore(service) || service->state !=
CONNMAN_SERVICE_STATE_IDLE)
continue;
- if (autoconnecting && !active_sessions[service->type]) {
+ if (autoconnect_already_connecting(service, autoconnecting)) {
DBG("service %p type %s has no users", service,
__connman_service_type2string(service->type));
continue;
}
+ if (!is_service_owner_user_login(service)) {
+ DBG("favorite user not login, wifi auto connect denied");
+ continue;
+ }
+
DBG("service %p %s %s", service, service->name,
(preferred) ? "preferred" : reason2string(reason));
__connman_service_connect(service, reason);
- if (!active_count)
+ if (autoconnect_no_session_active(service))
return true;
ignore[service->type] = true;
return FALSE;
}
+#if defined TIZEN_EXT
+bool __connman_service_get_auto_connect_mode(void)
+{
+ return auto_connect_mode;
+}
+
+void __connman_service_set_auto_connect_mode(bool enable)
+{
+ DBG("set auto_connect_mode = %d", enable);
+
+ if (auto_connect_mode != enable)
+ auto_connect_mode = enable;
+}
+#endif
+
void __connman_service_auto_connect(enum connman_service_connect_reason reason)
{
DBG("");
if (autoconnect_timeout != 0)
return;
+#if defined TIZEN_EXT
+ if (auto_connect_mode == FALSE) {
+ DBG("Currently, not auto connection mode");
+ return;
+ }
+#endif
+
if (!__connman_session_policy_autoconnect(reason))
return;
- autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect,
+#if defined TIZEN_EXT
+ /* Adding Timeout of 500ms before trying to auto connect.
+ * This is done because of below scenario
+ * 1. Device is connected to AP1
+ * 2. WPS Connection request is initiated for AP2
+ * 3. Immediately WPS Connection is Cancelled
+ * When WPS Connection Connection is initiated for AP2 then
+ * sometimes there is a scenario where connman gets in ASSOCIATED
+ * state with AP1 due to autoconnect and subsequently the connection
+ * initiated by AP1 fails and connman service for AP1 comes in
+ * FAILURE state due to this when connection with AP2 is cancelled
+ * then autoconnect with AP1 doesn't works because its autoconnection
+ * is ignored as its last state was FAILURE rather than IDLE */
+ autoconnect_timeout = g_timeout_add(500, run_auto_connect,
+#else
+ autoconnect_timeout = g_idle_add(run_auto_connect,
+#endif
GUINT_TO_POINTER(reason));
}
if (service->type != CONNMAN_SERVICE_TYPE_VPN)
continue;
- if (is_connected(service) || is_connecting(service)) {
+ if (is_connected(service->state) ||
+ is_connecting(service->state)) {
if (!service->do_split_routing)
need_split = true;
continue;
return;
vpn_autoconnect_timeout =
- g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
- }
-
- static void remove_timeout(struct connman_service *service)
- {
- if (service->timeout > 0) {
- g_source_remove(service->timeout);
- service->timeout = 0;
- }
- }
-
- static void reply_pending(struct connman_service *service, int error)
- {
- remove_timeout(service);
-
- if (service->pending) {
- connman_dbus_reply_pending(service->pending, error, NULL);
- service->pending = NULL;
- }
-
- if (service->provider_pending) {
- connman_dbus_reply_pending(service->provider_pending,
- error, service->path);
- service->provider_pending = NULL;
- }
+ g_idle_add(run_vpn_auto_connect, NULL);
}
bool
else if (service->provider)
connman_provider_disconnect(service->provider);
- __connman_ipconfig_disable(service->ipconfig_ipv4);
- __connman_ipconfig_disable(service->ipconfig_ipv6);
-
__connman_stats_service_unregister(service);
if (service->pending) {
DBusMessage *msg, void *user_data)
{
struct connman_service *service = user_data;
+#if defined TIZEN_EXT
+ int err = 0;
+#else
int index, err = 0;
GList *list;
+#endif
DBG("service %p", service);
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ connman_service_user_pdn_connection_ref(service);
+
+ /*Reset the Disconnect Reason while issue connect request*/
+ service->disconnect_reason = 0;
+
+ /*Reset the association status code while issue connect request*/
+ service->assoc_status_code = 0;
+#endif
+
if (service->pending)
return __connman_error_in_progress(msg);
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
+ DBG("Not allow this user to connect this wifi service now!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (uid != USER_ROOT && uid != service->user.favorite_user)
+ service->request_passphrase_input = true;
+
+ service->user.current_user = uid;
+
+ if (!service->passphrase && uid == service->user.favorite_user) {
+ DBG("Now load this favorite user's passphrase.");
+ service_load_passphrase(service);
+ }
+ }
+
+#if !defined TIZEN_EXT
index = __connman_service_get_index(service);
for (list = service_list; list; list = list->next) {
struct connman_service *temp = list->data;
- if (!is_connecting(temp) && !is_connected(temp))
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ break;
+#endif
+ if (!is_connecting(temp->state) && !is_connected(temp->state))
break;
if (service == temp)
}
if (err == -EINPROGRESS)
return __connman_error_operation_timeout(msg);
+#endif
service->ignore = false;
DBG("service %p", service);
- if (is_connected(service) == TRUE &&
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
+ if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
+ return __connman_error_failed(msg, EISCONN);
+
++ if (is_connected(service->state) == TRUE &&
+ service == connman_service_get_default_connection())
+ return __connman_error_failed(msg, EISCONN);
+ }
+#endif
+
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (!connman_service_is_user_allowed(service, uid)) {
+ DBG("Not allow this user to disconnect this wifi service now!");
+ return __connman_error_permission_denied(msg);
+ }
+ }
+
service->ignore = true;
err = __connman_service_disconnect(service);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+#if defined TIZEN_EXT
+static void __connman_service_cleanup_network_8021x(struct connman_service *service)
+{
+ if (service == NULL)
+ return;
+
+ DBG("service %p ", service);
+
+ connman_network_set_string(service->network, "WiFi.EAP", NULL);
+ connman_network_set_string(service->network, "WiFi.Identity", NULL);
+ connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
+ connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
+ connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
+ connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
+ connman_network_set_string(service->network, "WiFi.Phase2", NULL);
+}
+#endif
+
bool __connman_service_remove(struct connman_service *service)
{
if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
__connman_provider_is_immutable(service->provider))
return false;
- if (!service->favorite && service->state !=
- CONNMAN_SERVICE_STATE_FAILURE)
+#if !defined TIZEN_EXT
+ if (!service->favorite && !is_idle(service->state))
return false;
+#endif
__connman_service_disconnect(service);
g_free(service->identity);
service->identity = NULL;
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = NULL;
+
+ g_free(service->subject_match);
+ service->subject_match = NULL;
+
+ g_free(service->altsubject_match);
+ service->altsubject_match = NULL;
+
+ g_free(service->domain_suffix_match);
+ service->domain_suffix_match = NULL;
+
+ g_free(service->domain_match);
+ service->domain_match = NULL;
+
g_free(service->agent_identity);
service->agent_identity = NULL;
g_free(service->eap);
service->eap = NULL;
+#if defined TIZEN_EXT
+ g_free(service->ca_cert_file);
+ service->ca_cert_file = NULL;
+
+ g_free(service->client_cert_file);
+ service->client_cert_file = NULL;
+
+ g_free(service->private_key_file);
+ service->private_key_file = NULL;
+
+ g_free(service->private_key_passphrase);
+ service->private_key_passphrase = NULL;
+
+ g_free(service->phase2);
+ service->phase2 = NULL;
+
+ __connman_service_cleanup_network_8021x(service);
+
+ __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
+ __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
+ connman_service_set_proxy(service, NULL, false);
+
+ __connman_service_nameserver_clear(service);
+
+ g_strfreev(service->nameservers_config);
+ service->nameservers_config = NULL;
+
+#endif
+
+#if defined TIZEN_EXT
+ if (service->security != CONNMAN_SERVICE_SECURITY_8021X)
+#endif
+ set_idle(service);
+
service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
+ service->user.favorite_user = USER_NONE;
+
__connman_service_set_favorite(service, false);
__connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
+#if defined TIZEN_EXT
+ /* Reset IP Method and DNS Method to DHCP */
+ __connman_ipconfig_set_method(service->ipconfig_ipv4,
+ CONNMAN_IPCONFIG_METHOD_DHCP);
+ service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
+ g_strfreev(service->nameservers_config);
+ service->nameservers_config = NULL;
+#endif
+
+#if defined TIZEN_EXT
+ __connman_storage_remove_service(service->identifier);
+#else
service_save(service);
+#endif
return true;
}
DBG("service %p", service);
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+#if !defined TIZEN_EXT
+ if (!connman_service_is_user_allowed(service, uid)) {
+ DBG("Not allow this user to remove this wifi service now!");
+ return __connman_error_permission_denied(msg);
+ }
+#endif
+ }
+
if (!__connman_service_remove(service))
return __connman_error_not_supported(msg);
return __connman_error_invalid_service(msg);
}
- target->do_split_routing = true;
+ set_split_routing(target, true);
} else
- target->do_split_routing = false;
+ set_split_routing(target, false);
- service->do_split_routing = false;
+ set_split_routing(service, false);
target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+static DBusMessage *get_user_favorite(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ DBusMessage *reply;
+ uid_t uid = USER_NONE;
+ dbus_bool_t user_favorite = false;
+ struct connman_service *service = user_data;
+
+ connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid);
+ if (uid == USER_ROOT)
+ user_favorite = service->favorite;
+ else if (uid != USER_NONE && uid == service->user.favorite_user) {
+ DBG("The service is favorite to this user!");
+ user_favorite = true;
+ }
+
+ reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN,
+ &user_favorite, DBUS_TYPE_INVALID);
+ return reply;
+}
+
static struct _services_notify {
int id;
GHashTable *add;
DBusMessageIter *iter = user_data;
if (!service || !service->path) {
+#if !defined TIZEN_EXT
DBG("service %p or path is NULL", service);
+#endif
return;
}
if (g_hash_table_lookup(services_notify->add, service->path)) {
+#if !defined TIZEN_EXT
DBG("new %s", service->path);
+#endif
append_struct(service, iter);
g_hash_table_remove(services_notify->add, service->path);
} else {
+#if !defined TIZEN_EXT
DBG("changed %s", service->path);
+#endif
append_struct_service(iter, NULL, service);
}
static bool allow_property_changed(struct connman_service *service)
{
+#if defined TIZEN_EXT
+ if (service->path == NULL)
+ return FALSE;
+#endif
if (g_hash_table_lookup_extended(services_notify->add, service->path,
- NULL, NULL)) {
- DBG("no property updates for service %p", service);
+ NULL, NULL))
return false;
- }
return true;
}
GDBUS_ARGS({ "service", "o" }), NULL,
move_after) },
{ GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
+ { GDBUS_METHOD("GetUserFavorite",
+ NULL, GDBUS_ARGS({ "value", "v" }),
+ get_user_favorite) },
{ },
};
reply_pending(service, ENOENT);
+ if (service->nameservers_timeout) {
+ g_source_remove(service->nameservers_timeout);
+ dns_changed(service);
+ }
+
__connman_notifier_service_remove(service);
service_schedule_removed(service);
g_free(service->identifier);
g_free(service->eap);
g_free(service->identity);
+ g_free(service->anonymous_identity);
g_free(service->agent_identity);
g_free(service->ca_cert_file);
+ g_free(service->subject_match);
+ g_free(service->altsubject_match);
+ g_free(service->domain_suffix_match);
+ g_free(service->domain_match);
g_free(service->client_cert_file);
g_free(service->private_key_file);
g_free(service->private_key_passphrase);
service->ignore = false;
+ service->user.favorite_user = USER_NONE;
+ service->user.current_user = USER_NONE;
+
+ service->request_passphrase_input = false;
+
service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
service->order = 0;
service->provider = NULL;
service->wps = false;
+#if defined TIZEN_EXT
+ service->storage_reload = false;
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ service->user_pdn_connection_refcount = 0;
+ __sync_synchronize();
+#endif
}
/**
state_a = service_a->state;
state_b = service_b->state;
- a_connected = is_connected(service_a);
- b_connected = is_connected(service_b);
+ a_connected = is_connected(state_a);
+ b_connected = is_connected(state_b);
if (a_connected && b_connected) {
if (service_a->order > service_b->order)
if (b_connected)
return 1;
- if (is_connecting(service_a))
+ if (is_connecting(state_a))
return -1;
- if (is_connecting(service_b))
+ if (is_connecting(state_b))
return 1;
}
return 1;
if (service_a->type != service_b->type) {
+ unsigned int *tech_array;
+ int i;
+
+ tech_array = connman_setting_get_uint_list(
+ "PreferredTechnologies");
+ if (tech_array) {
+ for (i = 0; tech_array[i]; i++) {
+ if (tech_array[i] == service_a->type)
+ return -1;
+
+ if (tech_array[i] == service_b->type)
+ return 1;
+ }
+ }
if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
return -1;
}
}
+ int __connman_service_compare(const struct connman_service *a,
+ const struct connman_service *b)
+ {
+ return service_compare(a, b);
+ }
+
/**
* connman_service_get_type:
* @service: service structure
}
/**
- if (is_connected(service)) {
+ * __connman_service_is_user_allowed:
+ * @type: service type
+ * @uid: user id
+ *
+ * Check a user is allowed to operate a type of service
+ */
+bool __connman_service_is_user_allowed(enum connman_service_type type,
+ uid_t uid)
+{
+ GList *list;
+ uid_t owner_user = USER_NONE;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+
+ if (service->type != type)
+ continue;
+
++ if (is_connected(service->state)) {
+ owner_user = service->user.favorite_user;
+ break;
+ }
+ }
+
+ if (uid == USER_NONE ||
+ (uid != USER_ROOT &&
+ owner_user != USER_NONE &&
+ owner_user != uid))
+ return false;
+
+ return true;
+}
+
+/**
* connman_service_get_network:
* @service: service structure
*
case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
break;
case CONNMAN_IPCONFIG_TYPE_IPV4:
- return is_connected_state(service, service->state_ipv4);
+ return is_connected(service->state_ipv4);
case CONNMAN_IPCONFIG_TYPE_IPV6:
- return is_connected_state(service, service->state_ipv6);
+ return is_connected(service->state_ipv6);
case CONNMAN_IPCONFIG_TYPE_ALL:
- return is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4) &&
- is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6);
+ return is_connected(service->state_ipv4) &&
+ is_connected(service->state_ipv6);
}
return false;
services_dirty = true;
}
- if (is_connected(service2) && index2 > 0 && index1 == index2)
+#if defined TIZEN_EXT
+/**
+ * Returns profile count if there is any connected profiles
+ * that use same interface
+ */
+int __connman_service_get_connected_count_of_iface(
+ struct connman_service *service)
+{
+ GList *list;
+ int count = 0;
+ int index1 = 0;
+ int index2 = 0;
+
+ DBG("");
+
+ index1 = __connman_service_get_index(service);
+
+ if (index1 <= 0)
+ return 0;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service2 = list->data;
+
+ if (service == service2)
+ continue;
+
+ index2 = __connman_service_get_index(service2);
+
++ if (is_connected(service2->state) && index2 > 0 && index1 == index2)
+ count++;
+
+ index2 = 0;
+ }
+
+ DBG("Interface index %d, count %d", index1, count);
+
+ return count;
+}
+
+void __connman_service_set_storage_reload(struct connman_service *service,
+ bool storage_reload)
+{
+ if (service != NULL)
+ service->storage_reload = storage_reload;
+}
+#endif
+
/**
* __connman_service_set_favorite_delayed:
* @service: service structure
bool favorite,
bool delay_ordering)
{
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return -EIO;
+#endif
if (service->hidden)
return -EOPNOTSUPP;
} else if (g_str_equal(key, "Identity")) {
g_free(service->identity);
service->identity = g_strdup(value);
+ } else if (g_str_equal(key, "AnonymousIdentity")) {
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = g_strdup(value);
} else if (g_str_equal(key, "CACertFile")) {
g_free(service->ca_cert_file);
service->ca_cert_file = g_strdup(value);
+ } else if (g_str_equal(key, "SubjectMatch")) {
+ g_free(service->subject_match);
+ service->subject_match = g_strdup(value);
+ } else if (g_str_equal(key, "AltSubjectMatch")) {
+ g_free(service->altsubject_match);
+ service->altsubject_match = g_strdup(value);
+ } else if (g_str_equal(key, "DomainSuffixMatch")) {
+ g_free(service->domain_suffix_match);
+ service->domain_suffix_match = g_strdup(value);
+ } else if (g_str_equal(key, "DomainMatch")) {
+ g_free(service->domain_match);
+ service->domain_match = g_strdup(value);
} else if (g_str_equal(key, "ClientCertFile")) {
g_free(service->client_cert_file);
service->client_cert_file = g_strdup(value);
searchdomain_add_all(service);
}
- static void service_complete(struct connman_service *service)
- {
- reply_pending(service, EIO);
-
- if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
- __connman_service_auto_connect(service->connect_reason);
-
- g_get_current_time(&service->modified);
- service_save(service);
- }
-
static void report_error_cb(void *user_context, bool retry,
void *user_data)
{
/* It is not relevant to stay on Failure state
* when failing is due to wrong user input */
__connman_service_clear_error(service);
+#if defined TIZEN_EXT
+ /* Reseting the state back in case of failure state */
+ service->state_ipv4 = service->state_ipv6 =
+ CONNMAN_SERVICE_STATE_IDLE;
+ if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
+#endif
service_complete(service);
__connman_connection_update_gateway();
}
if (service->hidden)
__connman_service_return_error(service,
- ECANCELED, user_data);
+ ECONNABORTED,
+ user_data);
goto done;
} else {
if (service->hidden)
for (list = service_list; list; list = list->next) {
up_service = list->data;
- if (!is_connected(up_service))
+ if (!is_connected(up_service->state))
continue;
if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
return -EALREADY;
}
- if (is_connected(service) == TRUE || is_connecting(service) == TRUE) {
+#if defined TIZEN_EXT
+static gboolean __connman_service_can_drop(struct connman_service *service)
+{
- } else if (is_connected(current) == TRUE || is_connecting(current) == TRUE)
++ if (is_connected(service->state) == TRUE || is_connecting(service->state) == TRUE) {
+ if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
+ return TRUE;
+ else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static struct connman_device *default_connecting_device = NULL;
+
+static void __connman_service_disconnect_default(struct connman_service *service)
+{
+ struct connman_device *default_device = NULL;
+
+ if (default_connecting_device == NULL)
+ return;
+
+ default_device = connman_network_get_device(
+ __connman_service_get_network(service));
+
+ DBG("Disconnecting service %p %s", service, service->path);
+ DBG("Disconnecting device %p %p %s",
+ default_connecting_device,
+ default_device,
+ connman_device_get_string(default_device, "Name"));
+
+ if (default_connecting_device == default_device)
+ default_connecting_device = NULL;
+}
+
+static void __connman_service_connect_default(struct connman_service *current)
+{
+ int err;
+ GList *list;
+ bool default_internet;
+ struct connman_service *service;
+ struct connman_service *default_service = NULL;
+ struct connman_device *default_device = NULL;
+
+ if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
+ switch (current->state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ return;
+ default:
+ break;
+ }
+
+ if (default_connecting_device &&
+ __connman_service_is_internet_profile(current) == TRUE) {
+ if (current->network == NULL)
+ return;
+
+ default_device = connman_network_get_device(current->network);
+ if (default_connecting_device == default_device) {
+ DBG("Cellular service[%s] %p %s",
+ state2string(current->state), current, current->path);
+ DBG("Cellular device %p %p %s",
+ default_connecting_device, default_device,
+ connman_device_get_string(default_device, "Name"));
+
+ default_connecting_device = NULL;
+ }
+ }
+
+ return;
- if (is_connected(default_service) == TRUE ||
- is_connecting(default_service) == TRUE)
++ } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE)
+ return;
+
+ /* Always-on: keep default cellular connection as possible */
+ for (list = service_list; list; list = list->next) {
+ service = list->data;
+
+ if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
+ __connman_service_is_internet_profile(service) != TRUE ||
+ service->network == NULL) {
+ continue;
+ }
+
+ default_internet =
+ connman_network_get_bool(service->network, "DefaultInternet");
+
+ DBG("service: %p %s %s %s (default: %d)", service, service->name,
+ __connman_service_type2string(service->type),
+ state2string(service->state), default_internet);
+
+ if (default_internet) {
+ default_service = service;
++ if (is_connected(default_service->state) == TRUE ||
++ is_connecting(default_service->state) == TRUE)
+ return;
+
+ default_device = connman_network_get_device(default_service->network);
+ if (default_connecting_device == default_device) {
+ DBG("Device is connecting (%p)", default_connecting_device);
+ return;
+ }
+
+ default_connecting_device = default_device;
+ default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
+
+ err = __connman_network_connect(default_service->network);
+ DBG("Connecting default service %p %s [%d]",
+ default_service, default_service->path, err);
+ DBG("Connecting device %p %s", default_connecting_device,
+ connman_device_get_string(default_connecting_device, "Name"));
+ if (err < 0 && err != -EINPROGRESS) {
+ default_connecting_device = NULL;
+ } else
+ break;
+ }
+ }
+}
+#endif
+
static void single_connected_tech(struct connman_service *allowed)
{
struct connman_service *service;
DBG("keeping %p %s", allowed, allowed->path);
+#if defined TIZEN_EXT
+ if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return;
+#endif
+
for (iter = service_list; iter; iter = iter->next) {
service = iter->data;
- if (!is_connected(service))
+#if defined TIZEN_EXT
+ if (service != allowed && service->type != allowed->type &&
+ __connman_service_can_drop(service) == TRUE)
+#else
+ if (!is_connected(service->state))
break;
if (service == allowed)
continue;
-
+#endif
services = g_slist_prepend(services, service);
}
service = list->data;
DBG("disconnecting %p %s", service, service->path);
+#if defined TIZEN_EXT
+ __connman_service_disconnect_default(service);
+#endif
__connman_service_disconnect(service);
}
g_slist_free(services);
}
- if (is_connected(service) == FALSE)
+#if defined TIZEN_EXT
+static void set_priority_connected_service(void)
+{
+ struct connman_service *service;
+ GList *list;
+
+ for (list = service_list; list; list = list->next) {
+ service = list->data;
+
++ if (is_connected(service->state) == FALSE)
+ service->order = 5;
+ else
+ service->order = 6;
+ }
+}
+#endif
+
static const char *get_dbus_sender(struct connman_service *service)
{
if (!service->pending)
if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
__connman_notifier_leave_online(service->type);
- if (is_connected_state(service, old_state) &&
- !is_connected_state(service, new_state))
+ if (is_connected(old_state) && !is_connected(new_state))
searchdomain_remove_all(service);
service->state = new_state;
state_changed(service);
+ if (!is_connected(old_state) && is_connected(new_state))
+ searchdomain_add_all(service);
+
switch(new_state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
reply_pending(service, 0);
- g_get_current_time(&service->modified);
- service_save(service);
-
- searchdomain_add_all(service);
- dns_changed(service);
- domain_changed(service);
- proxy_changed(service);
-
- if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
- __connman_notifier_connect(service->type);
-
if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
connman_network_get_bool(service->network,
"WiFi.UseWPS")) {
"WiFi.UseWPS", false);
}
+ g_get_current_time(&service->modified);
+ service_save(service);
+
+ domain_changed(service);
+ proxy_changed(service);
+
+ if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
+ __connman_notifier_connect(service->type);
+
method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
if (method == CONNMAN_IPCONFIG_METHOD_OFF)
__connman_ipconfig_disable_ipv6(
else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
vpn_auto_connect();
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
+ set_priority_connected_service();
+#endif
+
break;
case CONNMAN_SERVICE_STATE_ONLINE:
reply_pending(service, ECONNABORTED);
def_service = __connman_service_get_default();
+ service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
+ service->assoc_status_code = connman_network_get_assoc_status_code(service->network);
if (!__connman_notifier_is_connected() &&
def_service &&
__connman_wpad_stop(service);
- dns_changed(service);
+#if defined TIZEN_EXT
+ /**
+ * Skip the functions if there is any connected profiles
+ * that use same interface
+ */
+ if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
+ __connman_service_get_connected_count_of_iface(
+ service) <= 0) {
+#endif
domain_changed(service);
proxy_changed(service);
+#if defined TIZEN_EXT
+ }
+#endif
/*
* Previous services which are connected and which states
break;
case CONNMAN_SERVICE_STATE_FAILURE:
-
+#if defined TIZEN_EXT
-
- service->assoc_status_code = connman_network_get_assoc_status_code(service->network);
-
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
+ service->order = 5;
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+#endif
if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
connman_agent_report_error(service, service->path,
error2string(service->error),
service_list_sort();
+#if defined TIZEN_EXT
+ __connman_service_connect_default(service);
+#endif
+
__connman_connection_update_gateway();
if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
default_changed();
}
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
+ (new_state == CONNMAN_SERVICE_STATE_READY ||
+ new_state == CONNMAN_SERVICE_STATE_ONLINE)) {
+ if (service->user.favorite_user != service->user.current_user) {
+ DBG("Now set service favorite user id from %d to %d",
+ service->user.favorite_user, service->user.current_user);
+
+ service->user.favorite_user = service->user.current_user;
+
+ service_save(service);
+ }
+ }
+
return 0;
}
set_error(service, error);
+/* default internet service: fix not cleared if pdp activation*/
+#if defined TIZEN_EXT
+ /*
+ * If connection failed for default service(DefaultInternet),
+ * default_connecting_device should be cleared.
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED)
+ __connman_service_disconnect_default(service);
+
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) {
+ g_free(service->passphrase);
+ service->passphrase = NULL;
+ }
+#endif
+
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_FAILURE,
CONNMAN_IPCONFIG_TYPE_IPV4);
{
DBG("service %p state %s", service, state2string(service->state));
- if (!is_connected(service)) {
+ if (!is_connected(service->state)) {
/*
* If service is not yet fully connected, then we must not
* change the default yet. The default gw will be changed
__connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
}
+#if defined TIZEN_EXT
+void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
+
+ DBG("check the proxy and start wispr");
+ check_proxy_setup(service);
+ return;
+}
+#endif
+
/*
* How many networks are connected at the same time. If more than 1,
* then set the rp_filter setting properly (loose mode routing) so that network
if (!ipconfig)
return -EINVAL;
+ method = __connman_ipconfig_get_method(ipconfig);
+
+ switch (method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ if (new_state != CONNMAN_SERVICE_STATE_IDLE)
+ connman_warn("ipconfig state %d ipconfig method %d",
+ new_state, method);
+
+ new_state = CONNMAN_SERVICE_STATE_IDLE;
+ break;
+
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ break;
+
+ }
+
/* Any change? */
if (old_state == new_state)
return -EALREADY;
+#if defined TIZEN_EXT
+ __sync_synchronize();
+ if (service->user_pdn_connection_refcount > 0 &&
+ service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
+ new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
+ new_state == CONNMAN_SERVICE_STATE_IDLE) {
+ service->user_pdn_connection_refcount = 0;
+ __sync_synchronize();
+ }
+#endif
+
DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
service, service ? service->identifier : NULL,
old_state, state2string(old_state),
switch (new_state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
case CONNMAN_SERVICE_STATE_ASSOCIATION:
break;
case CONNMAN_SERVICE_STATE_CONFIGURATION:
- __connman_ipconfig_enable(ipconfig);
break;
case CONNMAN_SERVICE_STATE_READY:
- if (connman_setting_get_bool("EnableOnlineCheck"))
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ __connman_service_is_internet_profile(service) != TRUE) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ service_rp_filter(service, TRUE);
+
+ break;
+ }
+#endif
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
++ if (connman_setting_get_bool("EnableOnlineCheck")) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+#if !defined TIZEN_EXT
- check_proxy_setup(service);
+ check_proxy_setup(service);
+#endif
+ } else {
+ service->online_check_count = 1;
+ __connman_wispr_start(service, type);
+ }
- else
++ } else
+ connman_info("Online check disabled. "
+ "Default service remains in READY state.");
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
service_rp_filter(service, true);
- } else {
- service->online_check_count = 1;
- __connman_wispr_start(service, type);
- }
break;
case CONNMAN_SERVICE_STATE_ONLINE:
break;
service_rp_filter(service, false);
break;
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- }
- /* Keep that state, but if the ipconfig method is OFF, then we set
- the state to IDLE so that it will not affect the combined state
- in the future.
- */
- method = __connman_ipconfig_get_method(ipconfig);
- switch (method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- new_state = CONNMAN_SERVICE_STATE_IDLE;
- break;
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ __connman_ipconfig_disable(ipconfig);
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
break;
-
}
- if (is_connected_state(service, old_state) &&
- !is_connected_state(service, new_state))
- #if defined TIZEN_EXT
- {
- DBG("nameserver remove all, type: %d", type);
+ if (is_connected(old_state) && !is_connected(new_state))
nameserver_remove_all(service, type);
- #else
- nameserver_remove_all(service);
- #endif
- #if defined TIZEN_EXT
- }
- #endif
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
service->state_ipv4 = new_state;
else
service->state_ipv6 = new_state;
- if (!is_connected_state(service, old_state) &&
- is_connected_state(service, new_state))
- #if defined TIZEN_EXT
- {
- DBG("nameserver add all, type: %d", type);
+ if (!is_connected(old_state) && is_connected(new_state))
nameserver_add_all(service, type);
- #else
- nameserver_add_all(service);
- #endif
- #if defined TIZEN_EXT
- }
- #endif
+
+ __connman_timeserver_sync(service);
+#if defined TIZEN_EXT
+ int ret = service_indicate_state(service);
+ /*Sent the Ready changed signal again in case IPv4 IP set
+ after IPv6 IP set*/
+
+ if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
+ && new_state == CONNMAN_SERVICE_STATE_READY) {
+ DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
+ state_changed(service);
+ }
+
+ return ret;
+#endif
return service_indicate_state(service);
}
connman_network_set_string(service->network, "WiFi.Identity",
service->identity);
+ if (service->anonymous_identity)
+ connman_network_set_string(service->network,
+ "WiFi.AnonymousIdentity",
+ service->anonymous_identity);
+
if (service->ca_cert_file)
connman_network_set_string(service->network, "WiFi.CACertFile",
service->ca_cert_file);
+ if (service->subject_match)
+ connman_network_set_string(service->network, "WiFi.SubjectMatch",
+ service->subject_match);
+
+ if (service->altsubject_match)
+ connman_network_set_string(service->network, "WiFi.AltSubjectMatch",
+ service->altsubject_match);
+
+ if (service->domain_suffix_match)
+ connman_network_set_string(service->network, "WiFi.DomainSuffixMatch",
+ service->domain_suffix_match);
+
+ if (service->domain_match)
+ connman_network_set_string(service->network, "WiFi.DomainMatch",
+ service->domain_match);
+
if (service->client_cert_file)
connman_network_set_string(service->network,
"WiFi.ClientCertFile",
if (service->hidden)
return -EPERM;
- if (!is_connecting(temp) && !is_connected(temp))
+#if defined TIZEN_EXT
+ GList *list;
+ int index;
+
+ index = __connman_service_get_index(service);
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *temp = list->data;
+
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ break;
+
++ if (!is_connecting(temp->state) && !is_connected(temp->state))
+ break;
+
+ if (service == temp)
+ continue;
+
+ if (service->type != temp->type)
+ continue;
+
+ if (__connman_service_get_index(temp) == index &&
+ __connman_service_disconnect(temp) == -EINPROGRESS)
+ return -EINPROGRESS;
+ }
+#endif
+
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
return -ENOKEY;
- if (!service->passphrase) {
+ if (service->request_passphrase_input) {
+ DBG("Now try to connect other user's favorite service");
+ service->request_passphrase_input = false;
+ return -ENOKEY;
+ } else if (!service->passphrase) {
if (!service->network)
return -EOPNOTSUPP;
if (!service->eap)
return -EINVAL;
+#if defined TIZEN_EXT
+ /*
+ * never request credentials if using EAP-TLS, EAP-SIM
+ * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
+ * need to be fully provisioned)
+ */
+ DBG("service eap: %s", service->eap);
+ if (g_str_equal(service->eap, "tls") ||
+ g_str_equal(service->eap, "sim") ||
+ g_str_equal(service->eap, "aka"))
+ break;
+#else
/*
* never request credentials if using EAP-TLS
* (EAP-TLS networks need to be fully provisioned)
*/
if (g_str_equal(service->eap, "tls"))
break;
-
+#endif
/*
* Return -ENOKEY if either identity or passphrase is
* missing. Agent provided credentials can be used as
&service->stats_roaming.data);
}
- if (service->ipconfig_ipv4)
- __connman_ipconfig_enable(service->ipconfig_ipv4);
- if (service->ipconfig_ipv6)
- __connman_ipconfig_enable(service->ipconfig_ipv6);
-
err = __connman_network_connect(service->network);
} else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
service->provider)
- err = __connman_provider_connect(service->provider);
+ err = __connman_provider_connect(service->provider,
+ get_dbus_sender(service));
else
return -EOPNOTSUPP;
if (err < 0) {
if (err != -EINPROGRESS) {
- __connman_ipconfig_disable(service->ipconfig_ipv4);
- __connman_ipconfig_disable(service->ipconfig_ipv6);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_FAILURE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_FAILURE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
__connman_stats_service_unregister(service);
}
}
reason2string(service->connect_reason),
reason2string(reason));
- if (is_connected(service))
+ if (is_connected(service->state))
return -EISCONN;
- if (is_connecting(service))
+ if (is_connecting(service->state))
return -EALREADY;
switch (service->type) {
err = service_connect(service);
+ DBG("service %p err %d", service, err);
+
service->connect_reason = reason;
-
if (err >= 0)
return 0;
if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
if (err == -ENOKEY || err == -EPERM) {
DBusMessage *pending = NULL;
+ const char *dbus_sender = get_dbus_sender(service);
/*
* We steal the reply here. The idea is that the
err = __connman_agent_request_passphrase_input(service,
request_input_cb,
- get_dbus_sender(service),
+ dbus_sender,
pending);
if (service->hidden && err != -EINPROGRESS)
service->pending = pending;
__connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
NULL);
+#if defined TIZEN_EXT
+ /**
+ * Skip the functions If there is any connected profiles
+ * that use same interface
+ */
+ if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
+ __connman_service_get_connected_count_of_iface(service) <= 0) {
+#endif
__connman_ipconfig_address_remove(service->ipconfig_ipv4);
settings_changed(service, service->ipconfig_ipv4);
__connman_ipconfig_disable(service->ipconfig_ipv4);
__connman_ipconfig_disable(service->ipconfig_ipv6);
+#if defined TIZEN_EXT
+ }
+#endif
__connman_stats_service_unregister(service);
for (iter = service_list; iter; iter = iter->next) {
service = iter->data;
- if (!is_connected(service))
+ if (!is_connected(service->state))
break;
services = g_slist_prepend(services, service);
return g_hash_table_lookup(service_hash, identifier);
}
+ struct connman_service *connman_service_lookup_from_identifier(const char* identifier)
+ {
+ return lookup_by_identifier(identifier);
+ }
+
struct provision_user_data {
const char *ident;
int ret;
DBG("%s lower down", ifname);
- if (!is_idle_state(service, service->state_ipv4))
- __connman_ipconfig_disable(service->ipconfig_ipv4);
-
- if (!is_idle_state(service, service->state_ipv6))
- __connman_ipconfig_disable(service->ipconfig_ipv6);
-
stats_stop(service);
service_save(service);
}
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
+#if defined TIZEN_EXT
+ int err;
+#endif
DBG("%s ip bound", ifname);
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
method == CONNMAN_IPCONFIG_METHOD_AUTO)
- if(err == 0)
- __connman_connection_gateway_activate(service,
- CONNMAN_IPCONFIG_TYPE_IPV6);
+#if defined TIZEN_EXT
+ {
+ err = __connman_ipconfig_gateway_add(ipconfig, service);
+
++ if(err < 0)
++ DBG("Failed to add gateway");
+ }
+#else
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_READY,
CONNMAN_IPCONFIG_TYPE_IPV6);
+#endif
settings_changed(service, ipconfig);
+ address_updated(service, type);
}
static void service_ip_release(struct connman_ipconfig *ipconfig,
if (!service->favorite)
return 0;
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
+ service->do_split_routing == FALSE)
+ order = 10;
+ else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ if (service->order < 5)
+ order = 5;
+ } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
+ order = 4;
+ else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
+ order = 3;
+ else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ __connman_service_is_internet_profile(service) == TRUE)
+ order = 1;
+ else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ __connman_service_is_tethering_profile(service) == TRUE)
+ order = 0;
+ else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ order = 0;
+ else
+ order = 2;
+#else
if (service == service_list->data)
order = 1;
service->order = 10;
order = 10;
}
-
+#endif
DBG("service %p name %s order %d split %d", service, service->name,
order, service->do_split_routing);
return order;
}
- void __connman_service_update_ordering(void)
- {
- if (service_list && service_list->next)
- service_list = g_list_sort(service_list, service_compare);
- }
-
static enum connman_service_type convert_network_type(struct connman_network *network)
{
enum connman_network_type type = connman_network_get_type(network);
return CONNMAN_SERVICE_SECURITY_WPA;
else if (g_str_equal(security, "rsn"))
return CONNMAN_SERVICE_SECURITY_RSN;
+#if defined TIZEN_EXT
+ else if (g_str_equal(security, "ft_psk") == TRUE)
+ return CONNMAN_SERVICE_SECURITY_PSK;
+ else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
+ return CONNMAN_SERVICE_SECURITY_8021X;
+#endif
else
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
}
- return check_passphrase(security, passphrase);
+#if defined TIZEN_EXT
+int check_passphrase_ext(struct connman_network *network,
+ const char *passphrase)
+{
+ const char *str;
+ enum connman_service_security security;
+
+ str = connman_network_get_string(network, "WiFi.Security");
+ security = convert_wifi_security(str);
+
++ return __connman_service_check_passphrase(security, passphrase);
+}
+#endif
+
static void update_from_network(struct connman_service *service,
struct connman_network *network)
{
DBG("service %p network %p", service, network);
- if (is_connected(service))
+ if (is_connected(service->state))
return;
- if (is_connecting(service))
+ if (is_connecting(service->state))
return;
str = connman_network_get_string(network, "Name");
service->ipconfig_ipv6 = create_ip6config(service, index);
service_register(service);
+ service_schedule_added(service);
if (service->favorite) {
device = connman_network_get_device(service->network);
break;
}
}
+
+#if defined TIZEN_EXT
+ /* TIZEN synchronizes below information when the service creates */
+ if (service->eap != NULL)
+ connman_network_set_string(service->network, "WiFi.EAP",
+ service->eap);
+ if (service->identity != NULL)
+ connman_network_set_string(service->network, "WiFi.Identity",
+ service->identity);
+ if (service->phase2 != NULL)
+ connman_network_set_string(service->network, "WiFi.Phase2",
+ service->phase2);
+#endif
}
__connman_notifier_service_add(service, service->name);
- service_schedule_added(service);
return service;
}
if (!service->network)
return;
+#if defined TIZEN_EXT
+ if (service->storage_reload) {
+ service_load(service);
+ __connman_service_set_storage_reload(service, false);
+ }
+#endif
+
name = connman_network_get_string(service->network, "Name");
if (g_strcmp0(service->name, name) != 0) {
g_free(service->name);
return err;
}
+ set_always_connecting_technologies();
+
connection = connman_dbus_get_connection();
service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
if (services_notify->id != 0) {
g_source_remove(services_notify->id);
service_send_changed(NULL);
- g_hash_table_destroy(services_notify->remove);
- g_hash_table_destroy(services_notify->add);
}
+
+ g_hash_table_destroy(services_notify->remove);
+ g_hash_table_destroy(services_notify->add);
g_free(services_notify);
dbus_connection_unref(connection);
static GHashTable *service_hash;
static struct connman_session *ecall_session;
static uint32_t session_mark = 256;
- static struct firewall_context *global_firewall = NULL;
-
- enum connman_session_state {
- CONNMAN_SESSION_STATE_DISCONNECTED = 0,
- CONNMAN_SESSION_STATE_CONNECTED = 1,
- CONNMAN_SESSION_STATE_ONLINE = 2,
- };
struct session_info {
struct connman_session_config config;
struct connman_service *service_last;
struct connman_session_config *policy_config;
GSList *user_allowed_bearers;
+ char *user_allowed_interface;
bool ecall;
int index;
char *gateway;
bool policy_routing;
+ bool snat_enabled;
};
struct connman_service_info {
GSList *sessions;
};
+ struct fw_snat {
+ GSList *sessions;
+ int id;
+ int index;
+ struct firewall_context *fw;
+ };
+
+ GSList *fw_snat_list;
+
static struct connman_session_policy *policy;
static void session_activate(struct connman_session *session);
static void session_deactivate(struct connman_session *session);
return "";
}
- static int init_firewall(void)
+ static struct fw_snat *fw_snat_lookup(int index)
{
- struct firewall_context *fw;
- int err;
+ struct fw_snat *fw_snat;
+ GSList *list;
- if (global_firewall)
- return 0;
+ for (list = fw_snat_list; list; list = list->next) {
+ fw_snat = list->data;
- fw = __connman_firewall_create();
+ if (fw_snat->index == index)
+ return fw_snat;
+ }
+ return NULL;
+ }
- err = __connman_firewall_add_rule(fw, "mangle", "INPUT",
- "-j CONNMARK --restore-mark");
- if (err < 0)
- goto err;
+ static int fw_snat_create(struct connman_session *session,
+ int index, const char *ifname, const char *addr)
+ {
+ struct fw_snat *fw_snat;
+ int err;
- err = __connman_firewall_add_rule(fw, "mangle", "POSTROUTING",
- "-j CONNMARK --save-mark");
- if (err < 0)
- goto err;
+ fw_snat = g_new0(struct fw_snat, 1);
- err = __connman_firewall_enable(fw);
- if (err < 0)
+ fw_snat->fw = __connman_firewall_create();
+ fw_snat->index = index;
+
+ fw_snat->id = __connman_firewall_enable_snat(fw_snat->fw,
+ index, ifname, addr);
+ if (fw_snat->id < 0) {
+ err = fw_snat->id;
goto err;
+ }
- global_firewall = fw;
+ fw_snat_list = g_slist_prepend(fw_snat_list, fw_snat);
+ fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
return 0;
-
err:
- __connman_firewall_destroy(fw);
-
+ __connman_firewall_destroy(fw_snat->fw);
+ g_free(fw_snat);
return err;
}
- static void cleanup_firewall(void)
+ static void fw_snat_ref(struct connman_session *session,
+ struct fw_snat *fw_snat)
{
- if (!global_firewall)
+ if (g_slist_find(fw_snat->sessions, session))
return;
+ fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
+ }
- __connman_firewall_disable(global_firewall);
- __connman_firewall_destroy(global_firewall);
+ static void fw_snat_unref(struct connman_session *session,
+ struct fw_snat *fw_snat)
+ {
+ fw_snat->sessions = g_slist_remove(fw_snat->sessions, session);
+ if (fw_snat->sessions)
+ return;
+
+ fw_snat_list = g_slist_remove(fw_snat_list, fw_snat);
+
+ __connman_firewall_disable_snat(fw_snat->fw);
+ __connman_firewall_destroy(fw_snat->fw);
+ g_free(fw_snat);
}
static int init_firewall_session(struct connman_session *session)
{
struct firewall_context *fw;
int err;
+ struct connman_ipconfig *ipconfig = NULL;
+ const char *addr = NULL;
- if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+ if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+ !session->info->config.source_ip_rule)
return 0;
DBG("");
- err = init_firewall();
- if (err < 0)
- return err;
+ if (session->info->config.source_ip_rule) {
+ ipconfig = __connman_service_get_ip4config(session->service);
+ if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN && !ipconfig)
+ return 0;
+ }
fw = __connman_firewall_create();
if (!fw)
return -ENOMEM;
- switch (session->policy_config->id_type) {
- case CONNMAN_SESSION_ID_TYPE_UID:
- err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
- "-m owner --uid-owner %s -j MARK --set-mark %d",
- session->policy_config->id,
- session->mark);
- break;
- case CONNMAN_SESSION_ID_TYPE_GID:
- err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
- "-m owner --gid-owner %s -j MARK --set-mark %d",
- session->policy_config->id,
- session->mark);
- break;
- case CONNMAN_SESSION_ID_TYPE_LSM:
- default:
- err = -EINVAL;
+ if (session->info->config.source_ip_rule && ipconfig) {
+ addr = __connman_ipconfig_get_local(ipconfig);
}
- if (err < 0)
- goto err;
-
+ err =__connman_firewall_enable_marking(fw,
+ session->policy_config->id_type,
+ session->policy_config->id,
+ addr, session->mark);
+ if (err < 0) {
+ __connman_firewall_destroy(fw);
+ return err;
+ }
session->id_type = session->policy_config->id_type;
-
- err = __connman_firewall_enable(fw);
- if (err)
- goto err;
-
session->fw = fw;
return 0;
-
- err:
- __connman_firewall_destroy(fw);
-
- return err;
}
static void cleanup_firewall_session(struct connman_session *session)
if (!session->fw)
return;
- __connman_firewall_disable(session->fw);
+ __connman_firewall_disable_marking(session->fw);
+ __connman_firewall_disable_snat(session->fw);
__connman_firewall_destroy(session->fw);
session->fw = NULL;
{
int err;
- if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+ if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+ !session->info->config.source_ip_rule)
+ return 0;
+
+ if (!session->service)
return 0;
DBG("");
{
struct connman_ipconfig *ipconfig;
int err;
+ struct in_addr addr = { INADDR_ANY };
if (!session->service)
return;
session->index = __connman_ipconfig_get_index(ipconfig);
session->gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
+ if (!session->gateway)
+ session->gateway = g_strdup(inet_ntoa(addr));
+
DBG("index %d routing table %d default gateway %s",
session->index, session->mark, session->gateway);
DBG("session %p %s", session, strerror(-err));
}
+ static void del_nat_rules(struct connman_session *session)
+ {
+ struct fw_snat *fw_snat;
+
+ if (!session->snat_enabled)
+ return;
+
+ session->snat_enabled = false;
+ fw_snat = fw_snat_lookup(session->index);
+
+ if (!fw_snat)
+ return;
+
+ fw_snat_unref(session, fw_snat);
+ }
+
+ static void add_nat_rules(struct connman_session *session)
+ {
+ struct connman_ipconfig *ipconfig;
+ struct fw_snat *fw_snat;
+ const char *addr;
+ int index, err;
+ char *ifname;
+
+ if (!session->service)
+ return;
+
+ ipconfig = __connman_service_get_ip4config(session->service);
+ index = __connman_ipconfig_get_index(ipconfig);
+ ifname = connman_inet_ifname(index);
+ addr = __connman_ipconfig_get_local(ipconfig);
+
+ if (!addr)
+ return;
+
+ session->snat_enabled = true;
+ fw_snat = fw_snat_lookup(index);
+ if (fw_snat) {
+ fw_snat_ref(session, fw_snat);
+ return;
+ }
+
+ err = fw_snat_create(session, index, ifname, addr);
+ if (err < 0) {
+ DBG("failed to add SNAT rule");
+ session->snat_enabled = false;
+ }
+
+ g_free(ifname);
+ }
+
+ uint32_t connman_session_firewall_get_fwmark(struct connman_session *session)
+ {
+ return session->mark;
+ }
+
static void cleanup_routing_table(struct connman_session *session)
{
DBG("");
del_default_route(session);
}
+ static void update_firewall(struct connman_session *session)
+ {
+ cleanup_firewall_session(session);
+ init_firewall_session(session);
+ }
+
static void update_routing_table(struct connman_session *session)
{
- del_default_route(session);
+ cleanup_routing_table(session);
+ init_routing_table(session);
add_default_route(session);
}
+ static void cleanup_nat_rules(struct connman_session *session)
+ {
+ del_nat_rules(session);
+ }
+
static void destroy_policy_config(struct connman_session *session)
{
if (!policy) {
destroy_policy_config(session);
g_slist_free(session->info->config.allowed_bearers);
+ g_free(session->info->config.allowed_interface);
g_free(session->owner);
g_free(session->session_path);
g_free(session->notify_path);
DBG("remove %s", session->session_path);
+ cleanup_nat_rules(session);
cleanup_routing_table(session);
cleanup_firewall_session(session);
update_session_state(session);
g_slist_free(session->user_allowed_bearers);
+ g_free(session->user_allowed_interface);
free_session(session);
}
/* user config */
enum connman_session_type type;
GSList *allowed_bearers;
+ char *allowed_interface;
+ bool source_ip_rule;
};
static void cleanup_creation_data(struct creation_data *creation_data)
dbus_message_unref(creation_data->pending);
g_slist_free(creation_data->allowed_bearers);
+ g_free(creation_data->allowed_interface);
g_free(creation_data);
}
config->ecall = FALSE;
g_slist_free(config->allowed_bearers);
+ config->allowed_bearers = NULL;
add_default_bearer_types(&config->allowed_bearers);
}
return 0;
}
- static void filter_bearer(GSList *policy_bearers,
- enum connman_service_type bearer,
+ static void filter_bearer(GSList *bearers,
+ enum connman_service_type policy,
GSList **list)
{
- enum connman_service_type policy;
+ enum connman_service_type bearer;
GSList *it;
- if (!policy_bearers)
+ if (!bearers)
return;
- for (it = policy_bearers; it; it = it->next) {
- policy = GPOINTER_TO_INT(it->data);
+ for (it = bearers; it; it = it->next) {
+ bearer = GPOINTER_TO_INT(it->data);
if (policy != bearer)
continue;
static void apply_policy_on_bearers(GSList *policy_bearers, GSList *bearers,
GSList **list)
{
- enum connman_service_type bearer;
+ enum connman_service_type policy_bearer;
GSList *it;
*list = NULL;
- for (it = bearers; it; it = it->next) {
- bearer = GPOINTER_TO_INT(it->data);
+ for (it = policy_bearers; it; it = it->next) {
+ policy_bearer = GPOINTER_TO_INT(it->data);
- filter_bearer(policy_bearers, bearer, list);
+ filter_bearer(bearers, policy_bearer, list);
}
}
+ static char * apply_policy_on_interface(const char *policy_interface,
+ const char *user_interface)
+ {
+ if (policy_interface)
+ return g_strdup(policy_interface);
+ else if (user_interface)
+ return g_strdup(user_interface);
+ else
+ return NULL;
+ }
+
const char *connman_session_get_owner(struct connman_session *session)
{
return session->owner;
info_last->config.allowed_bearers = info->config.allowed_bearers;
}
+ if (session->append_all ||
+ info->config.allowed_interface != info_last->config.allowed_interface) {
+ char *ifname = info->config.allowed_interface;
+ if (!ifname)
+ ifname = "*";
+ connman_dbus_dict_append_basic(dict, "AllowedInterface",
+ DBUS_TYPE_STRING,
+ &ifname);
+ info_last->config.allowed_interface = info->config.allowed_interface;
+ }
+
+ if (session->append_all ||
+ info->config.source_ip_rule != info_last->config.source_ip_rule) {
+ dbus_bool_t source_ip_rule = FALSE;
+ if (info->config.source_ip_rule)
+ source_ip_rule = TRUE;
+ connman_dbus_dict_append_basic(dict, "SourceIPRule",
+ DBUS_TYPE_BOOLEAN,
+ &source_ip_rule);
+ info_last->config.source_ip_rule = info->config.source_ip_rule;
+ }
+
session->append_all = false;
}
return true;
if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
- info->config.type != info_last->config.type)
+ info->config.type != info_last->config.type ||
+ info->config.allowed_interface != info_last->config.allowed_interface ||
+ info->config.source_ip_rule != info_last->config.source_ip_rule)
return true;
return false;
{
struct session_info *info = session->info;
GSList *allowed_bearers;
+ char *allowed_interface;
int err;
DBG("session %p", session);
session->user_allowed_bearers,
&allowed_bearers);
+ allowed_interface = apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
if (session->active)
set_active_session(session, false);
g_slist_free(info->config.allowed_bearers);
info->config.allowed_bearers = allowed_bearers;
+ g_free(info->config.allowed_interface);
+ info->config.allowed_interface = allowed_interface;
+
session_activate(session);
info->config.type = apply_policy_on_type(
session->active = false;
session_deactivate(session);
+ update_session_state(session);
g_slist_free(info->config.allowed_bearers);
session->user_allowed_bearers = allowed_bearers;
info->config.type = apply_policy_on_type(
session->policy_config->type,
connman_session_parse_connection_type(val));
+ } else if (g_str_equal(name, "AllowedInterface")) {
+ dbus_message_iter_get_basic(&value, &val);
+ if (session->active)
+ set_active_session(session, false);
+
+ session->active = false;
+ session_deactivate(session);
+ update_session_state(session);
+
+ g_free(session->user_allowed_interface);
+ /* empty string means allow any interface */
+ if (!g_strcmp0(val, ""))
+ session->user_allowed_interface = NULL;
+ else
+ session->user_allowed_interface = g_strdup(val);
+
+ info->config.allowed_interface = apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
+ session_activate(session);
+ } else {
+ goto err;
+ }
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ if (g_str_equal(name, "SourceIPRule")) {
+ dbus_bool_t source_ip_rule;
+ dbus_message_iter_get_basic(&value, &source_ip_rule);
+
+ info->config.source_ip_rule = source_ip_rule;
+ update_session_state(session);
} else {
goto err;
}
goto err;
session->policy_config = config;
+ session->info->config.source_ip_rule = creation_data->source_ip_rule;
session->mark = session_mark++;
session->index = -1;
session->user_allowed_bearers = creation_data->allowed_bearers;
creation_data->allowed_bearers = NULL;
+ session->user_allowed_interface = creation_data->allowed_interface;
+ creation_data->allowed_interface = NULL;
+
apply_policy_on_bearers(
session->policy_config->allowed_bearers,
session->user_allowed_bearers,
&info->config.allowed_bearers);
+ info->config.allowed_interface = apply_policy_on_interface(
+ session->policy_config->allowed_interface,
+ session->user_allowed_interface);
+
g_hash_table_replace(session_hash, session->session_path, session);
DBG("add %s", session->session_path);
info_last->config.priority = info->config.priority;
info_last->config.roaming_policy = info->config.roaming_policy;
info_last->config.allowed_bearers = info->config.allowed_bearers;
+ info_last->config.allowed_interface = info->config.allowed_interface;
+ info_last->config.source_ip_rule = info->config.source_ip_rule;
session->append_all = true;
connman_session_parse_connection_type(val);
user_connection_type = true;
+ } else if (g_str_equal(key, "AllowedInterface")) {
+ dbus_message_iter_get_basic(&value, &val);
+ creation_data->allowed_interface = g_strdup(val);
} else {
err = -EINVAL;
goto err;
}
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ if (g_str_equal(key, "SourceIPRule")) {
+ dbus_bool_t source_ip_rule;
+ dbus_message_iter_get_basic(&value, &source_ip_rule);
+ creation_data->source_ip_rule = source_ip_rule;
+ } else {
+ err = -EINVAL;
+ goto err;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ goto err;
}
+
dbus_message_iter_next(&array);
}
DBG("session %p state %s", session, state2string(state));
+ update_firewall(session);
+ del_nat_rules(session);
update_routing_table(session);
+ add_nat_rules(session);
+
+ if (policy && policy->update_session_state)
+ policy->update_session_state(session, state);
+
session_notify(session);
}
{
enum connman_service_type bearer_type;
enum connman_service_type service_type;
+ enum connman_service_type current_service_type;
GSList *list;
+ char *ifname;
if (policy && policy->allowed)
return policy->allowed(session, service);
+ current_service_type = connman_service_get_type(session->service);
+
for (list = session->info->config.allowed_bearers; list; list = list->next) {
bearer_type = GPOINTER_TO_INT(list->data);
service_type = connman_service_get_type(service);
+ ifname = connman_service_get_interface(service);
- if (bearer_type == service_type)
- return true;
+ if (bearer_type == current_service_type)
+ return false;
+
+ if (bearer_type == service_type &&
+ (session->info->config.allowed_interface == NULL ||
+ !g_strcmp0(session->info->config.allowed_interface, "*") ||
+ !g_strcmp0(session->info->config.allowed_interface, ifname))) {
+ g_free(ifname);
+ return true;
+ }
+ g_free(ifname);
}
return false;
case CONNMAN_SERVICE_STATE_READY:
if (session->info->config.type == CONNMAN_SESSION_TYPE_INTERNET)
return false;
+ /* fall through */
case CONNMAN_SERVICE_STATE_ONLINE:
return true;
}
if (!service_hash)
return;
+ if (policy && policy->get_service_for_session) {
+ struct connman_service *service;
+ struct connman_service_info *info;
+ GSList *service_list = NULL;
+ enum connman_service_state state = CONNMAN_SESSION_STATE_DISCONNECTED;
+
+ g_hash_table_iter_init(&iter, service_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_service_info *info = value;
+ state = __connman_service_get_state(info->service);
+
+ if (is_session_connected(session, state))
+ service_list = g_slist_prepend(service_list,
+ info->service);
+ }
+
+ service_list = g_slist_reverse(service_list);
+ service = policy->get_service_for_session(session, service_list);
+
+ if (service) {
+ info = g_hash_table_lookup(service_hash, service);
+ DBG("session %p add service %p", session, info->service);
+
+ info->sessions = g_slist_prepend(info->sessions,
+ session);
+ session->service = info->service;
+ update_session_state(session);
+ }
+
+ g_slist_free(service_list);
+ return;
+ }
+
g_hash_table_iter_init(&iter, service_hash);
while (g_hash_table_iter_next(&iter, &key, &value)) {
struct connman_service_info *info = value;
session->service = NULL;
update_session_state(session);
+ session_activate(session);
}
}
-
static void service_state_changed(struct connman_service *service,
enum connman_service_state state)
{
continue;
if (session->service && session->service == service) {
- update_routing_table(session);
+ update_session_state(session);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
ipconfig_ipv4_changed(session);
service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, cleanup_service);
- if (__connman_firewall_is_up()) {
- err = init_firewall();
- if (err < 0)
- return err;
- }
-
return 0;
}
if (!connection)
return;
- cleanup_firewall();
-
connman_notifier_unregister(&session_notifier);
g_hash_table_foreach(session_hash, release_session, NULL);
munmap(file->addr, file->len);
file->addr = NULL;
- TFR(close(file->fd));
+ close(file->fd);
file->fd = -1;
- if (file->history_name) {
- g_free(file->history_name);
- file->history_name = NULL;
- }
+ g_free(file->history_name);
+ file->history_name = NULL;
- if (file->name) {
- g_free(file->name);
- file->name = NULL;
- }
+ g_free(file->name);
+ file->name = NULL;
g_free(file);
}
connman_error("fstat error %s for %s\n",
strerror(errno), file->name);
- TFR(close(file->fd));
+ close(file->fd);
+ file->fd = -1;
g_free(file->name);
file->name = NULL;
err = stats_file_remap(file, size);
if (err < 0) {
- TFR(close(file->fd));
+ close(file->fd);
+ file->fd = -1;
g_free(file->name);
file->name = NULL;
stats_file_unmap(history_file);
stats_file_unmap(temp_file);
- TFR(close(temp_file->fd));
+ close(temp_file->fd);
unlink(history_file->name);
unlink(temp_file->name);
- TFR(close(history_file->fd));
+ close(history_file->fd);
stats_file_cleanup(history_file);
stats_file_cleanup(temp_file);
bzero(history_file, sizeof(struct stats_file));
bzero(temp_file, sizeof(struct stats_file));
+ history_file->fd = -1;
+ temp_file->fd = -1;
+
err = stats_open(history_file, data_file->history_name);
if (err < 0)
return err;
DBG("service %p", service);
- file = g_hash_table_lookup(stats_hash, service);
- if (!file) {
- file = g_try_new0(struct stats_file, 1);
- if (!file)
- return -ENOMEM;
-
- g_hash_table_insert(stats_hash, service, file);
- } else {
- return -EALREADY;
- }
-
dir = g_strdup_printf("%s/%s", STORAGEDIR,
__connman_service_get_ident(service));
}
g_free(dir);
+ file = g_hash_table_lookup(stats_hash, service);
+ if (!file) {
+ file = g_try_new0(struct stats_file, 1);
+ if (!file)
+ return -ENOMEM;
+
+ file->fd = -1;
+
+ g_hash_table_insert(stats_hash, service, file);
+ } else {
+ return -EALREADY;
+ }
name = g_strdup_printf("%s/%s/data", STORAGEDIR,
__connman_service_get_ident(service));
#include <config.h>
#endif
+#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
{
GKeyFile *keyfile = NULL;
GError *error = NULL;
-
- DBG("Loading %s", pathname);
keyfile = g_key_file_new();
ret = -EIO;
}
+#if defined TIZEN_EXT
+ {
+ FILE *fp = NULL;
+ fp = fopen(pathname, "a+");
+ if(fp){
+ fflush(fp);
+ fsync(fp->_fileno);
+ fclose(fp);
+ DBG("sync the file to disk");
+ }
+ }
+#endif
+
g_free(data);
return ret;
if (task->pid > 0) {
kill(task->pid, SIGTERM);
- g_timeout_add_seconds(0, check_kill,
- GINT_TO_POINTER(task->pid));
+ g_idle_add(check_kill, GINT_TO_POINTER(task->pid));
}
return 0;
static bool global_offlinemode;
+#if defined TIZEN_EXT
+typedef enum {
+ CONNMAN_SCAN_TYPE_FULL_CHANNEL = 0x00,
+ CONNMAN_SCAN_TYPE_SPECIFIC_AP,
+ CONNMAN_SCAN_TYPE_MULTI_AP,
+} connman_scan_type_e;
+
+static connman_scan_type_e g_scan_type = -1;
+#endif
+
struct connman_rfkill {
unsigned int index;
enum connman_service_type type;
*/
char *tethering_ident;
char *tethering_passphrase;
+ bool tethering_hidden;
bool enable_persistent; /* Save the tech state */
g_key_file_set_boolean(keyfile, identifier, "Tethering",
technology->tethering_persistent);
+ g_key_file_set_boolean(keyfile, identifier, "Hidden",
+ technology->tethering_hidden);
+
if (technology->tethering_ident)
g_key_file_set_string(keyfile, identifier,
"Tethering.Identifier",
technology_save(technology);
}
- void connman_technology_tethering_notify(struct connman_technology *technology,
+ int connman_technology_tethering_notify(struct connman_technology *technology,
bool enabled)
{
+ int err;
+
DBG("technology %p enabled %u", technology, enabled);
if (technology->tethering == enabled)
- return;
+ return -EALREADY;
- technology->tethering = enabled;
+ if (enabled) {
+ err = __connman_tethering_set_enabled();
+ if (err < 0)
+ return err;
+ } else
+ __connman_tethering_set_disabled();
+ technology->tethering = enabled;
tethering_changed(technology);
- if (enabled)
- __connman_tethering_set_enabled();
- else
- __connman_tethering_set_disabled();
+ return 0;
}
static int set_tethering(struct connman_technology *technology,
int err;
const char *ident, *passphrase, *bridge;
GSList *tech_drivers;
- bool hidden;
ident = technology->tethering_ident;
passphrase = technology->tethering_passphrase;
- hidden = technology->tethering_hidden;
__sync_synchronize();
if (!technology->enabled)
if (!bridge)
return -EOPNOTSUPP;
- if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
- (!ident || !passphrase))
+ if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident))
return -EINVAL;
for (tech_drivers = technology->driver_list; tech_drivers;
continue;
err = driver->set_tethering(technology, ident, passphrase,
- bridge, enabled, hidden);
+ bridge, enabled);
if (result == -EINPROGRESS)
continue;
- if (err == -EINPROGRESS || err == 0) {
+ if (err == -EINPROGRESS || err == 0)
result = err;
- continue;
- }
}
return result;
static void connman_technology_save_offlinemode(void)
{
GKeyFile *keyfile;
+ GError *error = NULL;
+ bool offlinemode;
keyfile = __connman_storage_load_global();
- if (!keyfile)
+
+ if (!keyfile) {
keyfile = g_key_file_new();
+ g_key_file_set_boolean(keyfile, "global",
+ "OfflineMode", global_offlinemode);
- g_key_file_set_boolean(keyfile, "global",
+ __connman_storage_save_global(keyfile);
+ }
+ else {
+ offlinemode = g_key_file_get_boolean(keyfile, "global",
+ "OfflineMode", &error);
+
+ if (error || offlinemode != global_offlinemode) {
+ g_key_file_set_boolean(keyfile, "global",
"OfflineMode", global_offlinemode);
+ if (error)
+ g_clear_error(&error);
- __connman_storage_save_global(keyfile);
+ __connman_storage_save_global(keyfile);
+ }
+ }
g_key_file_free(keyfile);
DBUS_TYPE_STRING,
&technology->tethering_passphrase);
+ val = technology->tethering_hidden;
+ connman_dbus_dict_append_basic(&dict, "Hidden",
+ DBUS_TYPE_BOOLEAN,
+ &val);
+
connman_dbus_dict_close(iter, &dict);
}
__sync_synchronize();
enabled = technology->enabled;
+#if defined TIZEN_EXT
+ DBG("ConnMan, Powered : %s, %s",
+ enabled ? "TRUE" : "FALSE",technology->path);
+#endif
connman_dbus_property_changed_basic(technology->path,
CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
DBUS_TYPE_BOOLEAN, &enabled);
struct connman_technology *technology = data;
DBusMessageIter iter, value;
const char *name;
- int type;
+ int type, err;
DBG("conn %p", conn);
DBG("property %s", name);
+ if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
+ DBG("Not allow this user to operate wifi technology now!");
+ return __connman_error_permission_denied(msg);
+ }
+ }
+
if (g_str_equal(name, "Tethering")) {
dbus_bool_t tethering;
int err;
if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
return __connman_error_not_supported(msg);
- if (strlen(str) < 8 || strlen(str) > 63) {
- if (g_str_equal(str, "")) {
- technology->tethering_passphrase = NULL;
+ err = __connman_service_check_passphrase(CONNMAN_SERVICE_SECURITY_PSK,
+ str);
+ if (err < 0)
+ return __connman_error_passphrase_required(msg);
- connman_dbus_property_changed_basic(technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE,
- "TetheringPassphrase",
- DBUS_TYPE_STRING,
- &str);
- }
- else
- return __connman_error_passphrase_required(msg);
- } else {
- if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
- g_free(technology->tethering_passphrase);
- technology->tethering_passphrase = g_strdup(str);
- technology_save(technology);
-
- connman_dbus_property_changed_basic(technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE,
- "TetheringPassphrase",
- DBUS_TYPE_STRING,
- &technology->tethering_passphrase);
- }
+ if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
+ g_free(technology->tethering_passphrase);
+ technology->tethering_passphrase = g_strdup(str);
+ technology_save(technology);
+
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE,
+ "TetheringPassphrase",
+ DBUS_TYPE_STRING,
+ &technology->tethering_passphrase);
}
+ } else if (g_str_equal(name, "Hidden")) {
+ dbus_bool_t hidden;
+
+ if (type != DBUS_TYPE_BOOLEAN)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&value, &hidden);
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ technology->tethering_hidden = hidden;
+ technology_save(technology);
+
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE,
+ "Hidden",
+ DBUS_TYPE_BOOLEAN,
+ &hidden);
} else if (g_str_equal(name, "Powered")) {
dbus_bool_t enable;
}
}
+#if defined TIZEN_EXT
+dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
+{
+ DBG("key %s", key);
+ DBusMessage *signal;
+ DBusMessageIter iter;
+ dbus_bool_t result = FALSE;
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "ScanChanged");
+ if (!signal)
+ return result;
+
+ dbus_message_iter_init_append(signal, &iter);
+ connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
+
+ result = dbus_connection_send(connection, signal, NULL);
+ dbus_message_unref(signal);
+
+ DBG("Successfuly sent signal");
+
+ return result;
+}
+#endif
+
void __connman_technology_scan_started(struct connman_device *device)
{
DBG("device %p", device);
+#if defined TIZEN_EXT
+ dbus_bool_t status = 1;
+ __connman_technology_notify_scan_changed("scan_started", &status);
+#endif
}
void __connman_technology_scan_stopped(struct connman_device *device,
count += 1;
}
+#if defined TIZEN_EXT
+ if (count == 0) {
+ DBusMessage *signal;
+ DBusMessageIter iter;
+ dbus_bool_t status = 0;
+ __connman_technology_notify_scan_changed("scan_done", &status);
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "ScanDone");
+ if (!signal)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+ connman_dbus_property_append_basic(&iter, "Scantype",
+ DBUS_TYPE_INT32, &g_scan_type);
+
+ dbus_connection_send(connection, signal, NULL);
+ dbus_message_unref(signal);
+ reply_scan_pending(technology, 0);
+
+ DBG("Successfuly sent ScanDone signal");
+ }
+#else
if (count == 0)
reply_scan_pending(technology, 0);
+#endif
}
void __connman_technology_notify_regdom_by_device(struct connman_device *device,
DBG("technology %p request from %s", technology,
dbus_message_get_sender(msg));
+ if (technology->type == CONNMAN_SERVICE_TYPE_P2P &&
+ !technology->enabled)
+ return __connman_error_permission_denied(msg);
+
dbus_message_ref(msg);
+#if !defined TIZEN_EXT
technology->scan_pending =
g_slist_prepend(technology->scan_pending, msg);
+#endif
err = __connman_device_request_scan(technology->type);
+#if defined TIZEN_EXT
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+#else
if (err < 0)
reply_scan_pending(technology, err);
+#endif
+#if defined TIZEN_EXT
+ if (err == 0) {
+ g_scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
+ DBG("g_scan_type %d", g_scan_type);
+ }
+ technology->scan_pending =
+ g_slist_prepend(technology->scan_pending, msg);
+#endif
return NULL;
}
+#if defined TIZEN_EXT
+static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ struct connman_technology *technology = data;
+ GSList *specific_scan_list = NULL;
+ int scan_type = 0;
+ const char *name = NULL;
+ unsigned int freq = 0;
+ DBusMessageIter iter, dict;
+ int err;
+
+ DBG("technology %p request from %s", technology,
+ dbus_message_get_sender(msg));
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return __connman_error_invalid_arguments(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_recurse(&iter, &dict);
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value2;
+ const char *key;
+ int type;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
+ g_slist_free_full(specific_scan_list, g_free);
+ return __connman_error_invalid_arguments(msg);
+ }
+
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
+ g_slist_free_full(specific_scan_list, g_free);
+ return __connman_error_invalid_arguments(msg);
+ }
+
+ dbus_message_iter_recurse(&entry, &value2);
+ type = dbus_message_iter_get_arg_type(&value2);
+ if (g_str_equal(key, "SSID")) {
+ if (type != DBUS_TYPE_STRING) {
+ g_slist_free_full(specific_scan_list, g_free);
+ return __connman_error_invalid_arguments(msg);
+ }
+
+ scan_type = 1; /* SSID based scan */
+ dbus_message_iter_get_basic(&value2, &name);
+ DBG("name %s", name);
+ specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
+ } else if (g_str_equal(key, "Frequency")) {
+ if (type != DBUS_TYPE_UINT16) {
+ g_slist_free_full(specific_scan_list, g_free);
+ return __connman_error_invalid_arguments(msg);
+ }
+
+ scan_type = 2; /* Frequency based scan */
+ dbus_message_iter_get_basic(&value2, &freq);
+ DBG("freq %d", freq);
+ specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
+ }
+ dbus_message_iter_next(&dict);
+ }
+
+ dbus_message_ref(msg);
+
+ err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ if (err == 0) {
+ guint list_size = g_slist_length(specific_scan_list);
+ if (list_size == 1)
+ g_scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP;
+ else
+ g_scan_type = CONNMAN_SCAN_TYPE_MULTI_AP;
+ DBG("list_size %u g_scan_type %d", list_size, g_scan_type);
+ }
+ technology->scan_pending =
+ g_slist_prepend(technology->scan_pending, msg);
+
+ if (scan_type == 1) {
+ g_slist_free_full(specific_scan_list, g_free);
+ scan_type = 0;
+ }
+ return NULL;
+}
+
+static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter, dict;
+ GSList *list;
+ struct connman_technology *technology = data;
+ dbus_bool_t scanning = false;
+
+ DBG("technology %p", technology);
+
+ for (list = technology->device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ scanning = connman_device_get_scanning(device);
+ if(scanning)
+ break;
+ }
+
+ DBG("scanning : %d", scanning);
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ connman_dbus_dict_open(&iter, &dict);
+ connman_dbus_dict_append_basic(&dict, "Scanstate",
+ DBUS_TYPE_BOOLEAN,
+ &scanning);
+
+ connman_dbus_dict_close(&iter, &dict);
+
+ return reply;
+}
+#endif
+
static const GDBusMethodTable technology_methods[] = {
{ GDBUS_DEPRECATED_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
NULL, set_property) },
{ GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+#if defined TIZEN_EXT
+ { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
+ NULL, specific_scan) },
+ { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
+ get_scan_state) },
+#endif
{ },
};
static const GDBusSignalTable technology_signals[] = {
{ GDBUS_SIGNAL("PropertyChanged",
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+ { GDBUS_SIGNAL("DhcpConnected",
+ GDBUS_ARGS({ "aptype", "s" },
+ { "ipaddr", "s" },
+ { "macaddr", "s" },
+ { "hostname", "s" })) },
+ { GDBUS_SIGNAL("DhcpLeaseDeleted",
+ GDBUS_ARGS({ "aptype", "s" },
+ { "ipaddr", "s" },
+ { "macaddr", "s" },
+ { "hostname", "s" })) },
{ },
};
g_slist_free(technology->device_list);
+ if (technology->pending_reply) {
+ dbus_message_unref(technology->pending_reply);
+ technology->pending_reply = NULL;
+ g_source_remove(technology->pending_timeout);
+ technology->pending_timeout = 0;
+ }
+
g_free(technology->path);
g_free(technology->regdom);
g_free(technology->tethering_ident);
technology->refcount = 1;
technology->type = type;
+ technology->tethering_hidden = FALSE;
technology->path = g_strdup_printf("%s/technology/%s",
CONNMAN_PATH, str);
DBG("technology %p type %s rfkill %d enabled %d", technology,
get_name(type), technology->rfkill_driven,
technology->enabled);
-
+#if !defined TIZEN_EXT
if (technology->rfkill_driven) {
if (technology->tethering_persistent)
enable_tethering(technology);
return 0;
}
+#endif
return technology_enabled(technology);
}
technology = technology_find(type);
if (!technology)
return -ENXIO;
-
+#if !defined TIZEN_EXT
if (technology->rfkill_driven)
return 0;
-
+#endif
for (list = technology->device_list; list; list = list->next) {
struct connman_device *device = list->data;
g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
done:
+#if defined TIZEN_EXT
+ /* Fix Svace Issue [WGID: 1348]. */
+ g_free(rfkill);
+#endif
technology = technology_get(type);
/* If there is no driver for this type, ignore it. */
if (!technology)
technology->rfkill_driven = true;
+#if !defined TIZEN_EXT
/* If hardblocked, there is no need to handle softblocked state */
if (technology_apply_rfkill_change(technology,
softblock, hardblock, true))
return 0;
-
+#endif
if (global_offlinemode)
return 0;
#define DEFAULT_MTU 1500
+#define CONNMAN_STATION_STR_INFO_LEN 64
+#define CONNMAN_STATION_MAC_INFO_LEN 32
+
static char *private_network_primary_dns = NULL;
static char *private_network_secondary_dns = NULL;
static struct connman_ippool *dhcp_ippool = NULL;
static DBusConnection *connection;
static GHashTable *pn_hash;
+static GHashTable *sta_hash;
struct connman_private_network {
char *owner;
char *secondary_dns;
};
+struct connman_station_info {
+ bool is_connected;
+ char *path;
+ char *type;
+ char ip[CONNMAN_STATION_STR_INFO_LEN];
+ char mac[CONNMAN_STATION_MAC_INFO_LEN];
+ char hostname[CONNMAN_STATION_STR_INFO_LEN];
+};
+
+static void emit_station_signal(char *action_str,
+ const struct connman_station_info *station_info)
+{
+ char *ip, *mac, *hostname;
+
+ if (station_info->path == NULL || station_info->type == NULL
+ || station_info->ip == NULL || station_info->mac == NULL
+ || station_info->hostname == NULL)
+ return;
+
+ ip = g_strdup(station_info->ip);
+ mac = g_strdup(station_info->mac);
+ hostname = g_strdup(station_info->hostname);
+
+ g_dbus_emit_signal(connection, station_info->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, action_str,
+ DBUS_TYPE_STRING, &station_info->type,
+ DBUS_TYPE_STRING, &ip,
+ DBUS_TYPE_STRING, &mac,
+ DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_INVALID);
+
+ g_free(ip);
+ g_free(mac);
+ g_free(hostname);
+}
+static void destroy_station(gpointer key, gpointer value, gpointer user_data)
+{
+ struct connman_station_info *station_info;
+
+ __sync_synchronize();
+
+ station_info = value;
+
+ if (station_info->is_connected) {
+ station_info->is_connected = FALSE;
+ emit_station_signal("DhcpLeaseDeleted", station_info);
+ }
+
+ g_free(station_info->path);
+ g_free(station_info->type);
+ g_free(station_info);
+}
+
+static void save_dhcp_ack_lease_info(char *hostname,
+ unsigned char *mac, unsigned int nip)
+{
+ char *lower_mac;
+ const char *ip;
+ char sta_mac[CONNMAN_STATION_MAC_INFO_LEN];
+ struct connman_station_info *info_found;
+ struct in_addr addr;
+ int str_len;
+
+ __sync_synchronize();
+
+ snprintf(sta_mac, CONNMAN_STATION_MAC_INFO_LEN,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ lower_mac = g_ascii_strdown(sta_mac, -1);
+
+ info_found = g_hash_table_lookup(sta_hash, lower_mac);
+ if (info_found == NULL) {
+ g_free(lower_mac);
+ return;
+ }
+
+ /* get the ip */
+ addr.s_addr = nip;
+ ip = inet_ntoa(addr);
+ str_len = strlen(ip) + 1;
+ if (str_len > CONNMAN_STATION_STR_INFO_LEN)
+ str_len = CONNMAN_STATION_STR_INFO_LEN - 1;
+ memcpy(info_found->ip, ip, str_len);
+
+ /* get hostname */
+ str_len = strlen(hostname) + 1;
+ if (str_len > CONNMAN_STATION_STR_INFO_LEN)
+ str_len = CONNMAN_STATION_STR_INFO_LEN - 1;
+ memcpy(info_found->hostname, hostname, str_len);
+
+ /* emit a signal */
+ info_found->is_connected = TRUE;
+ emit_station_signal("DhcpConnected", info_found);
+ g_free(lower_mac);
+}
+
+int connman_technology_tethering_add_station(enum connman_service_type type,
+ const char *mac)
+{
+ const char *str_type;
+ char *lower_mac;
+ char *path;
+ struct connman_station_info *station_info;
+
+ __sync_synchronize();
+
+ DBG("type %d", type);
+
+ str_type = __connman_service_type2string(type);
+ if (str_type == NULL)
+ return 0;
+
+ path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str_type);
+
+ station_info = g_try_new0(struct connman_station_info, 1);
+ if (station_info == NULL)
+ return -ENOMEM;
+
+ lower_mac = g_ascii_strdown(mac, -1);
+
+ memcpy(station_info->mac, lower_mac, strlen(lower_mac) + 1);
+ station_info->path = path;
+ station_info->type = g_strdup(str_type);
+
+ g_hash_table_insert(sta_hash, station_info->mac, station_info);
+
+ g_free(lower_mac);
+ return 0;
+}
+
+int connman_technology_tethering_remove_station(const char *mac)
+{
+ char *lower_mac;
+ struct connman_station_info *info_found;
+
+ __sync_synchronize();
+
+ lower_mac = g_ascii_strdown(mac, -1);
+
+ info_found = g_hash_table_lookup(sta_hash, lower_mac);
+ if (info_found == NULL) {
+ g_free(lower_mac);
+ return -EACCES;
+ }
+
+ if (info_found->is_connected) {
+ info_found->is_connected = FALSE;
+ emit_station_signal("DhcpLeaseDeleted", info_found);
+ }
+ g_free(lower_mac);
+ g_hash_table_remove(sta_hash, info_found->mac);
+ g_free(info_found->path);
+ g_free(info_found->type);
+ g_free(info_found);
+
+ return 0;
+}
+
const char *__connman_tethering_get_bridge(void)
{
int sk, err;
g_dhcp_server_set_option(dhcp_server, G_DHCP_DNS_SERVER, dns);
g_dhcp_server_set_ip_range(dhcp_server, start_ip, end_ip);
+ g_dhcp_server_set_save_ack_lease(dhcp_server,
+ save_dhcp_ack_lease_info, NULL);
+
g_dhcp_server_start(dhcp_server);
return dhcp_server;
__connman_tethering_set_enabled();
}
- void __connman_tethering_set_enabled(void)
+ int __connman_tethering_set_enabled(void)
{
int index;
int err;
DBG("enabled %d", tethering_enabled + 1);
if (__sync_fetch_and_add(&tethering_enabled, 1) != 0)
- return;
+ return 0;
err = __connman_bridge_create(BRIDGE_NAME);
if (err < 0) {
__sync_fetch_and_sub(&tethering_enabled, 1);
- return;
+ return -EOPNOTSUPP;
}
index = connman_inet_ifindex(BRIDGE_NAME);
connman_error("Fail to create IP pool");
__connman_bridge_remove(BRIDGE_NAME);
__sync_fetch_and_sub(&tethering_enabled, 1);
- return;
+ return -EADDRNOTAVAIL;
}
gateway = __connman_ippool_get_gateway(dhcp_ippool);
__connman_ippool_unref(dhcp_ippool);
__connman_bridge_remove(BRIDGE_NAME);
__sync_fetch_and_sub(&tethering_enabled, 1);
- return;
+ return -EADDRNOTAVAIL;
}
ns = connman_setting_get_string_list("FallbackNameservers");
__connman_ippool_unref(dhcp_ippool);
__connman_bridge_remove(BRIDGE_NAME);
__sync_fetch_and_sub(&tethering_enabled, 1);
- return;
+ return -EOPNOTSUPP;
}
prefixlen = connman_ipaddress_calc_netmask_len(subnet_mask);
__connman_ippool_unref(dhcp_ippool);
__connman_bridge_remove(BRIDGE_NAME);
__sync_fetch_and_sub(&tethering_enabled, 1);
- return;
+ return -EOPNOTSUPP;
}
err = __connman_ipv6pd_setup(BRIDGE_NAME);
strerror(-err));
DBG("tethering started");
+
+ return 0;
}
void __connman_tethering_set_disabled(void)
close(fd);
g_free(iface);
g_free(path);
+ if (pn)
+ g_free(pn->owner);
g_free(pn);
return err;
}
pn_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, remove_private_network);
+ sta_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, NULL, NULL);
+
return 0;
}
return;
g_hash_table_destroy(pn_hash);
+ g_hash_table_foreach(sta_hash, destroy_station, NULL);
+ g_hash_table_destroy(sta_hash);
dbus_connection_unref(connection);
}
{
int i;
+#if defined TIZEN_EXT
+ gchar *server = NULL;
+
+ server = g_strdup((gchar *)user_data);
+ ts_list = g_slist_append(ts_list, server);
+
+ DBG("added server %s", server);
+#endif
+
DBG("status %d", status);
if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
DBG("Resolving timeserver %s", ts_current);
+#if defined TIZEN_EXT
+ resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
+ resolv_result, ts_current);
+#else
resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
resolv_result, NULL);
+#endif
return;
}
int __connman_timeserver_sync(struct connman_service *default_service)
{
struct connman_service *service;
+ char **nameservers;
+ int i;
if (default_service)
service = default_service;
if (resolv_id > 0)
g_resolv_cancel_lookup(resolv, resolv_id);
+ g_resolv_flush_nameservers(resolv);
+
+ nameservers = connman_service_get_nameservers(service);
+ if (!nameservers)
+ return -EINVAL;
+
+ for (i = 0; nameservers[i]; i++)
+ g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
+
+ g_strfreev(nameservers);
+
g_slist_free_full(ts_list, g_free);
ts_list = __connman_timeserver_get_all(service);
#define URANDOM "/dev/urandom"
- int f = -1;
+ static int f = -1;
int __connman_util_get_random(uint64_t *val)
{
- int r = 0;
+ int r;
if (!val)
return -EINVAL;
- if (read(f, val, sizeof(uint64_t)) < 0) {
+ r = read(f, val, sizeof(uint64_t));
+ if (r < 0) {
r = -errno;
connman_warn_once("Could not read from "URANDOM);
*val = random();
+ } else if (r != sizeof(uint64_t)) {
+ r = -EIO;
+ connman_warn_once("Short read from "URANDOM);
+ *val = random();
}
return r;
{
int r = 0;
- if (f > 0)
+ if (f >= 0)
return 0;
f = open(URANDOM, O_RDONLY);
void __connman_util_cleanup(void)
{
- if (f > 0)
+ if (f >= 0)
close(f);
f = -1;
int err = 0;
int i;
- DBG("wispr/portal context %p", wp_context);
- DBG("service %p", wp_context->service);
+ DBG("wispr/portal context %p service %p", wp_context,
+ wp_context->service);
service_type = connman_service_get_type(wp_context->service);
goto done;
}
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_WEB_DEBUG"))
+#endif
g_web_set_debug(wp_context->web, web_debug, "WEB");
if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
free_connman_wispr_portal_context(wp_context);
}
} else if (wp_context->timeout == 0) {
- wp_context->timeout =
- g_timeout_add_seconds(0, no_proxy_callback, wp_context);
+ wp_context->timeout = g_idle_add(no_proxy_callback, wp_context);
}
done:
DBG("service %p", service);
+#if defined TIZEN_EXT
+ if (connman_service_get_type(service) == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return -EPERM;
+#endif
+
if (!wispr_portal_list)
return -EINVAL;
{
struct connman_wpad *wpad = data;
+ connman_service_unref(wpad->service);
+
g_resolv_unref(wpad->resolv);
g_strfreev(wpad->addrlist);
return -ENOMEM;
}
- wpad->service = service;
wpad->resolv = g_resolv_new(index);
if (!wpad->resolv) {
g_strfreev(nameservers);
return -ENOMEM;
}
+#if !defined TIZEN_EXT
if (getenv("CONNMAN_RESOLV_DEBUG"))
+#endif
g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV");
for (i = 0; nameservers[i]; i++)
DBG("hostname %s", wpad->hostname);
+ wpad->service = connman_service_ref(service);
+
g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
wpad_result, wpad);
- connman_service_ref(service);
g_hash_table_replace(wpad_list, GINT_TO_POINTER(index), wpad);
return 0;
if (index < 0)
return;
- if (g_hash_table_remove(wpad_list, GINT_TO_POINTER(index)))
- connman_service_unref(service);
+ g_hash_table_remove(wpad_list, GINT_TO_POINTER(index));
}
int __connman_wpad_init(void)
#endif
#include <glib.h>
+ #include <errno.h>
#include "../src/connman.h"
char *cmd, *output, **lines;
GError **error = NULL;
int i;
+ bool ret = true;
cmd = g_strdup_printf(IPTABLES_SAVE " -t %s", table_name);
g_spawn_command_line_sync(cmd, &output, NULL, NULL, error);
lines = g_strsplit(output, "\n", 0);
g_free(output);
+ if (!lines)
+ return false;
for (i = 0; lines[i]; i++) {
DBG("lines[%02d]: %s\n", i, lines[i]);
if (g_strcmp0(lines[i], rule) == 0)
break;
}
- g_strfreev(lines);
if (!lines[i])
- return false;
+ ret = false;
- return true;
+ g_strfreev(lines);
+ return ret;
}
static void assert_rule_exists(const char *table_name, const char *rule)
g_free(service);
}
- static void test_firewall_basic0(void)
- {
- struct firewall_context *ctx;
- int err;
-
- ctx = __connman_firewall_create();
- g_assert(ctx);
-
- err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
- "-m mark --mark 999 -j LOG");
- g_assert(err == 0);
-
- err = __connman_firewall_enable(ctx);
- g_assert(err == 0);
-
- assert_rule_exists("filter", ":connman-INPUT - [0:0]");
- assert_rule_exists("filter", "-A INPUT -j connman-INPUT");
- assert_rule_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
-
- err = __connman_firewall_disable(ctx);
- g_assert(err == 0);
-
- assert_rule_not_exists("filter", ":connman-INPUT - [0:0]");
- assert_rule_not_exists("filter", "-A INPUT -j connman-INPUT");
- assert_rule_not_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
-
- __connman_firewall_destroy(ctx);
- }
-
- static void test_firewall_basic1(void)
- {
- struct firewall_context *ctx;
- int err;
-
- ctx = __connman_firewall_create();
- g_assert(ctx);
-
- err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
- "-m mark --mark 999 -j LOG");
- g_assert(err == 0);
-
- err = __connman_firewall_add_rule(ctx, "filter", "OUTPUT",
- "-m mark --mark 999 -j LOG");
- g_assert(err == 0);
-
- err = __connman_firewall_enable(ctx);
- g_assert(err == 0);
-
- err = __connman_firewall_disable(ctx);
- g_assert(err == 0);
-
- __connman_firewall_destroy(ctx);
- }
-
- static void test_firewall_basic2(void)
- {
- struct firewall_context *ctx;
- int err;
-
- ctx = __connman_firewall_create();
- g_assert(ctx);
-
- err = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
- "-j CONNMARK --restore-mark");
- g_assert(err == 0);
-
- err = __connman_firewall_add_rule(ctx, "mangle", "POSTROUTING",
- "-j CONNMARK --save-mark");
- g_assert(err == 0);
-
- err = __connman_firewall_enable(ctx);
- g_assert(err == 0);
-
- err = __connman_firewall_disable(ctx);
- g_assert(err == 0);
-
- __connman_firewall_destroy(ctx);
- }
-
static gchar *option_debug = NULL;
static bool parse_debug(const char *key, const char *value,
"Unit Tests Connection Manager", VERSION);
__connman_iptables_init();
- __connman_firewall_init();
__connman_nat_init();
g_test_add_func("/iptables/chain0", test_iptables_chain0);
g_test_add_func("/iptables/target0", test_iptables_target0);
g_test_add_func("/nat/basic0", test_nat_basic0);
g_test_add_func("/nat/basic1", test_nat_basic1);
- g_test_add_func("/firewall/basic0", test_firewall_basic0);
- g_test_add_func("/firewall/basic1", test_firewall_basic1);
- g_test_add_func("/firewall/basic2", test_firewall_basic2);
err = g_test_run();
__connman_nat_cleanup();
- __connman_firewall_cleanup();
__connman_iptables_cleanup();
g_free(option_debug);
typedef void (* notify_func_t) (struct test_session *session);
- enum connman_session_state {
- CONNMAN_SESSION_STATE_DISCONNECTED = 0,
- CONNMAN_SESSION_STATE_CONNECTED = 1,
- CONNMAN_SESSION_STATE_ONLINE = 2,
- };
-
struct test_session_info {
enum connman_session_state state;
char *name;
munmap(history_file->addr, history_file->len);
munmap(temp_file->addr, temp_file->len);
- TFR(close(temp_file->fd));
+ close(temp_file->fd);
unlink(history_file->name);
return;
unlink(temp_file->name);
- TFR(close(history_file->fd));
+ close(history_file->fd);
}
static void history_file_update(struct stats_file *data_file,
else
start_ts = option_start_ts;
+ if (option_interval == 0) {
+ printf("interval cannot be zero, using the default value\n");
+ option_interval = 3;
+ }
+
if (option_create > 0)
stats_create(data_file, option_create, option_interval,
start_ts, rec);
static void test_case_5(void)
{
- struct connman_ippool *pool;
+ struct connman_ippool *pool1, *pool2;
const char *gateway;
const char *broadcast;
const char *subnet_mask;
g_assert(flag == 0);
/* pool should return 192.168.0.1 now */
- pool = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
- g_assert(pool);
+ pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+ g_assert(pool1);
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
+ gateway = __connman_ippool_get_gateway(pool1);
+ broadcast = __connman_ippool_get_broadcast(pool1);
+ subnet_mask = __connman_ippool_get_subnet_mask(pool1);
+ start_ip = __connman_ippool_get_start_ip(pool1);
+ end_ip = __connman_ippool_get_end_ip(pool1);
g_assert(gateway);
g_assert(broadcast);
"\tgateway %s broadcast %s mask %s", start_ip, end_ip,
gateway, broadcast, subnet_mask);
- __connman_ippool_unref(pool);
-
/*
* Now create the pool again, we should not get collision
* with existing allocated address.
/* pool should return 192.168.2.1 now */
flag = 0;
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
- g_assert(pool);
+ pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ g_assert(pool2);
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
+ gateway = __connman_ippool_get_gateway(pool2);
+ broadcast = __connman_ippool_get_broadcast(pool2);
+ subnet_mask = __connman_ippool_get_subnet_mask(pool2);
+ start_ip = __connman_ippool_get_start_ip(pool2);
+ end_ip = __connman_ippool_get_end_ip(pool2);
g_assert(gateway);
g_assert(broadcast);
g_assert(flag == 0);
- __connman_ippool_unref(pool);
+ __connman_ippool_unref(pool1);
+ __connman_ippool_unref(pool2);
__connman_ippool_cleanup();
}
static void test_case_6(void)
{
- struct connman_ippool *pool;
+ struct connman_ippool *pool1, *pool2;
const char *gateway;
const char *broadcast;
const char *subnet_mask;
g_assert(flag == 0);
/* pool should return 192.168.2.1 now */
- pool = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
- g_assert(pool);
+ pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+ g_assert(pool1);
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
+ gateway = __connman_ippool_get_gateway(pool1);
+ broadcast = __connman_ippool_get_broadcast(pool1);
+ subnet_mask = __connman_ippool_get_subnet_mask(pool1);
+ start_ip = __connman_ippool_get_start_ip(pool1);
+ end_ip = __connman_ippool_get_end_ip(pool1);
g_assert(gateway);
g_assert(broadcast);
"\tgateway %s broadcast %s mask %s", start_ip, end_ip,
gateway, broadcast, subnet_mask);
- __connman_ippool_unref(pool);
-
/*
* Now create the pool again, we should not get collision
* with existing allocated address.
/* pool should return 192.168.3.1 now */
flag = 0;
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
- g_assert(pool);
+ pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ g_assert(pool2);
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
+ gateway = __connman_ippool_get_gateway(pool2);
+ broadcast = __connman_ippool_get_broadcast(pool2);
+ subnet_mask = __connman_ippool_get_subnet_mask(pool2);
+ start_ip = __connman_ippool_get_start_ip(pool2);
+ end_ip = __connman_ippool_get_end_ip(pool2);
g_assert(gateway);
g_assert(broadcast);
__connman_ippool_newaddr(25, start_ip, 24);
g_assert(flag == 1);
- __connman_ippool_unref(pool);
+ __connman_ippool_unref(pool1);
+ __connman_ippool_unref(pool2);
__connman_ippool_cleanup();
}
[Unit]
Description=ConnMan VPN service
+Requires=dbus.socket
+After=dbus.socket
[Service]
Type=dbus
+User=network_fw
+Group=network_fw
BusName=net.connman.vpn
-ExecStart=@sbindir@/connman-vpnd -n
+SmackProcessLabel=System
+ExecStart=@bindir@/connman-vpnd -n
StandardOutput=null
- Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
-CapabilityBoundingSet=CAP_KILL CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
++Capabilities=cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
+SecureBits=keep-caps
+ ProtectHome=read-only
+ ProtectSystem=full
[Install]
WantedBy=multi-user.target
#define CONFIGMAINFILE CONFIGDIR "/connman-vpn.conf"
#define DEFAULT_INPUT_REQUEST_TIMEOUT 300 * 1000
+#define DEFAULT_BROWSER_LAUNCH_TIMEOUT 300 * 1000
static GMainLoop *main_loop = NULL;
static struct {
unsigned int timeout_inputreq;
+ unsigned int timeout_browserlaunch;
} connman_vpn_settings = {
.timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
+ .timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
};
static GKeyFile *load_config(const char *file)
{ NULL },
};
+bool connman_setting_get_bool(const char *key)
+{
+ return false;
+}
+
+char **connman_setting_get_string_list(const char *key)
+{
+ return NULL;
+}
+
+unsigned int *connman_setting_get_uint_list(const char *key)
+{
+ return NULL;
+}
+
/*
* This function will be called from generic src/agent.c code so we have
* to use connman_ prefix instead of vpn_ one.
return connman_vpn_settings.timeout_inputreq;
}
+unsigned int connman_timeout_browser_launch(void)
+{
+ return connman_vpn_settings.timeout_browserlaunch;
+}
+
++const char *connman_option_get_string(const char *key)
++{
++ return NULL;
++}
++
int main(int argc, char *argv[])
{
GOptionContext *context;
{ "PPPD.RefuseMSCHAP2", "refuse-mschapv2", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoBSDComp", "nobsdcomp", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoPcomp", "nopcomp", OPT_PPPD, NULL, OPT_BOOL },
- { "PPPD.UseAccomp", "accomp", OPT_PPPD, NULL, OPT_BOOL },
+ { "PPPD.UseAccomp", "noaccomp", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.NoDeflate", "nodeflate", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE", "require-mppe", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE40", "require-mppe-40", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPE128", "require-mppe-128", OPT_PPPD, NULL, OPT_BOOL },
{ "PPPD.ReqMPPEStateful", "mppe-stateful", OPT_PPPD, NULL, OPT_BOOL },
- { "PPPD.NoVJ", "no-vj-comp", OPT_PPPD, NULL, OPT_BOOL },
+ { "PPPD.NoVJ", "novj", OPT_PPPD, NULL, OPT_BOOL },
};
static DBusConnection *connection;
DBG("provider %p", l2tp_reply->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ if (reply)
+ error = dbus_message_get_error_name(reply);
goto done;
}
DBG("provider %p", data->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
goto err;
if (!vpn_agent_check_reply_has_dict(reply))
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
+ #include <linux/if_tun.h>
#include <glib.h>
{ "OpenVPN.CompLZO", "--comp-lzo", 0 },
{ "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
{ "OpenVPN.ConfigFile", "--config", 1 },
+ { "OpenVPN.DeviceType", NULL, 1 },
+ { "OpenVPN.Verb", "--verb", 1 },
};
struct nameserver_entry {
{
DBusMessageIter iter, dict;
const char *reason, *key, *value;
- char *address = NULL, *gateway = NULL, *peer = NULL;
+ char *address = NULL, *gateway = NULL, *peer = NULL, *netmask = NULL;
struct connman_ipaddress *ipaddress;
GSList *nameserver_list = NULL;
if (!strcmp(key, "ifconfig_local"))
address = g_strdup(value);
+ if (!strcmp(key, "ifconfig_netmask"))
+ netmask = g_strdup(value);
+
if (!strcmp(key, "ifconfig_remote"))
peer = g_strdup(value);
g_free(address);
g_free(gateway);
g_free(peer);
+ g_free(netmask);
return VPN_STATE_FAILURE;
}
- connman_ipaddress_set_ipv4(ipaddress, address, NULL, gateway);
+ connman_ipaddress_set_ipv4(ipaddress, address, netmask, gateway);
connman_ipaddress_set_peer(ipaddress, peer);
vpn_provider_set_ipaddress(provider, ipaddress);
g_free(address);
g_free(gateway);
g_free(peer);
+ g_free(netmask);
connman_ipaddress_free(ipaddress);
return VPN_STATE_CONNECT;
return 0;
}
+ static gboolean can_read_data(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
+ {
+ void (*cbf)(const char *format, ...) = data;
+ gchar *str;
+ gsize size;
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+ return FALSE;
+
+ g_io_channel_read_line(chan, &str, &size, NULL, NULL);
+ cbf(str);
+ g_free(str);
+
+ return TRUE;
+ }
+
+ static int setup_log_read(int stdout_fd, int stderr_fd)
+ {
+ GIOChannel *chan;
+ int watch;
+
+ chan = g_io_channel_unix_new(stdout_fd);
+ g_io_channel_set_close_on_unref(chan, TRUE);
+ watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+ can_read_data, connman_debug);
+ g_io_channel_unref(chan);
+
+ if (watch == 0)
+ return -EIO;
+
+ chan = g_io_channel_unix_new(stderr_fd);
+ g_io_channel_set_close_on_unref(chan, TRUE);
+ watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+ can_read_data, connman_error);
+ g_io_channel_unref(chan);
+
+ return watch == 0? -EIO : 0;
+ }
+
static int ov_connect(struct vpn_provider *provider,
struct connman_task *task, const char *if_name,
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data)
{
const char *option;
- int err = 0, fd;
+ int stdout_fd, stderr_fd;
+ int err = 0;
option = vpn_provider_get_string(provider, "Host");
if (!option) {
connman_task_add_argument(task, "--client", NULL);
}
- connman_task_add_argument(task, "--syslog", NULL);
-
connman_task_add_argument(task, "--script-security", "2");
connman_task_add_argument(task, "--up",
connman_task_get_path(task));
connman_task_add_argument(task, "--dev", if_name);
- connman_task_add_argument(task, "--dev-type", "tun");
+ option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+ if (option) {
+ connman_task_add_argument(task, "--dev-type", option);
+ } else {
+ /*
+ * Default to tun for backwards compatibility.
+ */
+ connman_task_add_argument(task, "--dev-type", "tun");
+ }
connman_task_add_argument(task, "--persist-tun", NULL);
+#if !defined TIZEN_EXT
connman_task_add_argument(task, "--route-noexec", NULL);
connman_task_add_argument(task, "--ifconfig-noexec", NULL);
+#endif
/*
* Disable client restarts because we can't handle this at the
*/
connman_task_add_argument(task, "--ping-restart", "0");
- fd = fileno(stderr);
err = connman_task_run(task, vpn_died, provider,
- NULL, &fd, &fd);
+ NULL, &stdout_fd, &stderr_fd);
if (err < 0) {
connman_error("openvpn failed to start");
err = -EIO;
goto done;
}
+ err = setup_log_read(stdout_fd, stderr_fd);
done:
if (cb)
cb(provider, user_data, err);
return err;
}
+ static int ov_device_flags(struct vpn_provider *provider)
+ {
+ const char *option;
+
+ option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+ if (!option) {
+ return IFF_TUN;
+ }
+
+ if (g_str_equal(option, "tap")) {
+ return IFF_TAP;
+ }
+
+ if (!g_str_equal(option, "tun")) {
+ connman_warn("bad OpenVPN.DeviceType value, falling back to tun");
+ }
+
+ return IFF_TUN;
+ }
+
static struct vpn_driver vpn_driver = {
.notify = ov_notify,
.connect = ov_connect,
.save = ov_save,
+ .device_flags = ov_device_flags,
};
static int openvpn_init(void)
{ "PPPD.RequirMPPE40", "require-mppe-40", NULL, OPT_BOOL },
{ "PPPD.RequirMPPE128", "require-mppe-128", NULL, OPT_BOOL },
{ "PPPD.RequirMPPEStateful", "mppe-stateful", NULL, OPT_BOOL },
- { "PPPD.NoVJ", "no-vj-comp", NULL, OPT_BOOL },
+ { "PPPD.NoVJ", "novj", NULL, OPT_BOOL },
};
static DBusConnection *connection;
DBG("provider %p", pptp_reply->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
+ if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ if (reply)
+ error = dbus_message_get_error_name(reply);
goto done;
}
unsigned int watch;
enum vpn_state state;
struct connman_task *task;
+ int tun_flags;
};
struct vpn_driver_data {
return 0;
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
sprintf(ifr.ifr_name, "%s", data->if_name);
fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
return 0;
}
+ static int vpn_set_state(struct vpn_provider *provider,
+ enum vpn_provider_state state)
+ {
+ struct vpn_data *data = vpn_provider_get_data(provider);
+ if (!data)
+ return -EINVAL;
+
+ switch (state) {
+ case VPN_PROVIDER_STATE_UNKNOWN:
+ return -EINVAL;
+ case VPN_PROVIDER_STATE_IDLE:
+ data->state = VPN_STATE_IDLE;
+ break;
+ case VPN_PROVIDER_STATE_CONNECT:
+ case VPN_PROVIDER_STATE_READY:
+ data->state = VPN_STATE_CONNECT;
+ break;
+ case VPN_PROVIDER_STATE_DISCONNECT:
+ data->state = VPN_STATE_DISCONNECT;
+ break;
+ case VPN_PROVIDER_STATE_FAILURE:
+ data->state = VPN_STATE_FAILURE;
+ break;
+ }
+
+ return 0;
+ }
+
static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
{
struct vpn_provider *provider = user_data;
return NULL;
}
- static int vpn_create_tun(struct vpn_provider *provider)
+#if defined TIZEN_EXT
+static void vpn_event(struct vpn_provider *provider, int state)
+{
+ struct vpn_driver_data *vpn_driver_data;
+ const char *name;
+
+ name = vpn_provider_get_driver_name(provider);
+ if (!name) {
+ DBG("Cannot find VPN driver for provider %p", provider);
+ vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
+ return;
+ }
+
+ vpn_driver_data = g_hash_table_lookup(driver_hash, name);
+ if (!vpn_driver_data) {
+ DBG("Cannot find VPN driver data for name %s", name);
+ vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
+ return;
+ }
+
+ DBG("provider %p driver %s state %d", provider, name, state);
+
+ switch (state) {
+ case VPN_STATE_CONNECT:
+ vpn_provider_set_state(provider,
+ VPN_PROVIDER_STATE_CONNECT);
+ break;
+ case VPN_STATE_READY:
+ vpn_provider_set_state(provider,
+ VPN_PROVIDER_STATE_READY);
+ break;
+
+ case VPN_STATE_UNKNOWN:
+ case VPN_STATE_IDLE:
+ case VPN_STATE_DISCONNECT:
+ case VPN_STATE_FAILURE:
+ vpn_provider_set_state(provider,
+ VPN_PROVIDER_STATE_DISCONNECT);
+ break;
+
+ case VPN_STATE_AUTH_FAILURE:
+ vpn_provider_indicate_error(provider,
+ VPN_PROVIDER_ERROR_AUTH_FAILED);
+ break;
+ }
+
+ return;
+}
+#endif
+
+ static int vpn_create_tun(struct vpn_provider *provider, int flags)
{
struct vpn_data *data = vpn_provider_get_data(provider);
struct ifreq ifr;
}
memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ ifr.ifr_flags = flags | IFF_NO_PI;
for (i = 0; i < 256; i++) {
sprintf(ifr.ifr_name, "vpn%d", i);
goto exist_err;
}
+ data->tun_flags = flags;
data->if_name = (char *)g_strdup(ifr.ifr_name);
if (!data->if_name) {
connman_error("Failed to allocate memory");
struct vpn_data *data = vpn_provider_get_data(provider);
struct vpn_driver_data *vpn_driver_data;
const char *name;
- int ret = 0;
+ int ret = 0, tun_flags = IFF_TUN;
enum vpn_state state = VPN_STATE_UNKNOWN;
if (data)
}
if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
- ret = vpn_create_tun(provider);
+ if (vpn_driver_data->vpn_driver->device_flags) {
+ tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
+ }
+ ret = vpn_create_tun(provider, tun_flags);
if (ret < 0)
goto exist_err;
}
goto exist_err;
}
+
+#if defined TIZEN_EXT
+ if(vpn_driver_data->vpn_driver->set_event_cb)
+ vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
+#endif
+
ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
data->if_name, cb, dbus_sender,
user_data);
data->provider_driver.probe = vpn_probe;
data->provider_driver.remove = vpn_remove;
data->provider_driver.save = vpn_save;
+ data->provider_driver.set_state = vpn_set_state;
if (!driver_hash)
driver_hash = g_hash_table_new_full(g_str_hash,
VPN_STATE_AUTH_FAILURE = 6,
};
+#if defined TIZEN_EXT
+typedef void (*vpn_event_callback)(struct vpn_provider *provider, int state);
+#endif
+
struct vpn_driver {
int flags;
int (*notify) (DBusMessage *msg, struct vpn_provider *provider);
+#if defined TIZEN_EXT
+ void (*set_event_cb) (vpn_event_callback event_cb, struct vpn_provider *provider);
+#endif
int (*connect) (struct vpn_provider *provider,
struct connman_task *task, const char *if_name,
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void (*disconnect) (struct vpn_provider *provider);
int (*error_code) (struct vpn_provider *provider, int exit_code);
int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
+ int (*device_flags) (struct vpn_provider *provider);
};
int vpn_register(const char *name, struct vpn_driver *driver,
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>
+ #include <linux/if_tun.h>
#include <glib.h>
{ "VPNC.LocalPort", "Local Port", "0", OPT_STRING, true, },
{ "VPNC.CiscoPort", "Cisco UDP Encapsulation Port", "0", OPT_STRING,
true },
- { "VPNC.AppVersion", "Application Version", NULL, OPT_STRING, true },
+ { "VPNC.AppVersion", "Application version", NULL, OPT_STRING, true },
{ "VPNC.NATTMode", "NAT Traversal Mode", "cisco-udp", OPT_STRING,
true },
{ "VPNC.DPDTimeout", "DPD idle timeout (our side)", NULL, OPT_STRING,
connman_task_add_argument(task, "--no-detach", NULL);
connman_task_add_argument(task, "--ifname", if_name);
- connman_task_add_argument(task, "--ifmode", "tun");
+ option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+ if (option) {
+ connman_task_add_argument(task, "--ifmode", option);
+ } else {
+ /*
+ * Default to tun for backwards compatibility.
+ */
+ connman_task_add_argument(task, "--ifmode", "tun");
+ }
connman_task_add_argument(task, "--script",
SCRIPTDIR "/openconnect-script");
}
}
+ static int vc_device_flags(struct vpn_provider *provider)
+ {
+ const char *option;
+
+ option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+ if (!option) {
+ return IFF_TUN;
+ }
+
+ if (g_str_equal(option, "tap")) {
+ return IFF_TAP;
+ }
+
+ if (!g_str_equal(option, "tun")) {
+ connman_warn("bad VPNC.DeviceType value, falling back to tun");
+ }
+
+ return IFF_TUN;
+ }
+
static struct vpn_driver vpn_driver = {
.notify = vc_notify,
.connect = vc_connect,
.error_code = vc_error_code,
.save = vc_save,
+ .device_flags = vc_device_flags,
};
static int vpnc_init(void)
struct vpn_config *config, enum what action)
{
struct vpn_config_provider *config_provider;
+#if !defined TIZEN_EXT
const char *ident, *host, *domain;
+#else
+ const char *ident, *host, *domain, *name;
+#endif
int err;
/* Strip off "provider_" prefix */
host = get_string(config_provider, "Host");
domain = get_string(config_provider, "Domain");
+#if !defined TIZEN_EXT
if (host && domain) {
char *id = __vpn_provider_create_identifier(host, domain);
+#else
+ name = get_string(config_provider, "Name");
+ if (host && domain && name) {
+ char *id = __vpn_provider_create_identifier(host, domain, name);
+#endif
struct vpn_provider *provider;
provider = __vpn_provider_lookup(id);
DBG("provider identifier %s", id);
} else {
+#if !defined TIZEN_EXT
DBG("invalid values host %s domain %s", host, domain);
+#else
+ DBG("invalid values host %s domain %s name %s", host, domain, name);
+#endif
err = -EINVAL;
goto err;
}
if (event->mask & IN_CREATE)
return;
- if (event->mask & IN_DELETE) {
+ if (event->mask & (IN_DELETE | IN_MOVED_FROM)) {
g_hash_table_remove(config_table, ident);
return;
}
- if (event->mask & IN_MODIFY) {
+ if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
struct vpn_config *config;
char *path = get_dir();
return NULL;
}
+ static DBusMessage *do_connect2(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+ {
+ return do_connect(conn, msg, data);
+ }
+
static DBusMessage *do_disconnect(DBusConnection *conn, DBusMessage *msg,
void *data)
{
GDBUS_ARGS({ "name", "s" }), NULL,
clear_property) },
{ GDBUS_ASYNC_METHOD("Connect", NULL, NULL, do_connect) },
+ { GDBUS_ASYNC_METHOD("Connect2",
+ GDBUS_ARGS({ "dbus_sender", "s" }),
+ NULL, do_connect2) },
{ GDBUS_METHOD("Disconnect", NULL, NULL, do_disconnect) },
{ },
};
provider->host_ip = g_strdupv(results);
vpn_provider_unref(provider);
+
+ /* Remove the resolver here so that it will not be left
+ * hanging around and cause double free in unregister_provider()
+ */
+ g_resolv_unref(provider->resolv);
+ provider->resolv = NULL;
}
static void provider_resolv_host_addr(struct vpn_provider *provider)
in_addr_t addr;
struct in_addr netmask_in;
unsigned char prefix_len = 32;
+ char *ptr;
+ long int value = strtol(netmask, &ptr, 10);
- if (netmask) {
- char *ptr;
- long int value = strtol(netmask, &ptr, 10);
- if (ptr != netmask && *ptr == '\0' &&
- value <= 32)
- prefix_len = value;
- }
+ if (ptr != netmask && *ptr == '\0' && value <= 32)
+ prefix_len = value;
addr = 0xffffffff << (32 - prefix_len);
netmask_in.s_addr = htonl(addr);
{
GSList *list;
gchar **result = NULL;
+ gchar **prev_result;
unsigned int num_elems = 0;
for (list = networks; list; list = g_slist_next(list)) {
struct vpn_route *route = list->data;
int family;
+ prev_result = result;
result = g_try_realloc(result,
(num_elems + 1) * sizeof(gchar *));
- if (!result)
+ if (!result) {
+ g_free(prev_result);
return NULL;
+ }
switch (route->family) {
case AF_INET:
num_elems++;
}
+ prev_result = result;
result = g_try_realloc(result, (num_elems + 1) * sizeof(gchar *));
- if (!result)
+ if (!result) {
+ g_free(prev_result);
return NULL;
+ }
result[num_elems] = NULL;
*count = num_elems;
DBG("provider %p", provider);
if (provider->driver && provider->driver->connect) {
+ const char *dbus_sender = dbus_message_get_sender(msg);
+
dbus_message_ref(msg);
+
+ if (dbus_message_has_signature(msg,
+ DBUS_TYPE_STRING_AS_STRING)) {
+ const char *sender = NULL;
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,
+ &sender, DBUS_TYPE_INVALID);
+ if (sender && sender[0])
+ dbus_sender = sender;
+ }
+
err = provider->driver->connect(provider, connect_cb,
- dbus_message_get_sender(msg),
- msg);
+ dbus_sender, msg);
} else
return -EOPNOTSUPP;
break;
}
+ if (provider->driver && provider->driver->set_state)
+ provider->driver->set_state(provider, provider->state);
+
return 0;
}
connection_unregister(provider);
+ /* If the provider has any DNS resolver queries pending,
+ * they need to be cleared here because the unref will not
+ * be able to do that (because the provider_resolv_host_addr()
+ * has increased the ref count by 1). This is quite rare as
+ * normally the resolving either returns a value or has a
+ * timeout which clears the memory. Typically resolv_result() will
+ * unref the provider but in this case that call has not yet
+ * happened.
+ */
+ if (provider->resolv)
+ vpn_provider_unref(provider);
+
vpn_provider_unref(provider);
}
g_strfreev(providers);
}
+#if !defined TIZEN_EXT
char *__vpn_provider_create_identifier(const char *host, const char *domain)
{
char *ident;
return ident;
}
+#else
+char *__vpn_provider_create_identifier(const char *host, const char *domain, const char *name)
+{
+ char *ident;
+
+ ident = g_strdup_printf("%s_%s_%s", host, domain, name);
+ if (!ident)
+ return NULL;
+
+ provider_dbus_ident(ident);
+
+ return ident;
+}
+#endif
int __vpn_provider_create(DBusMessage *msg)
{
if (!type || !name)
return -EOPNOTSUPP;
+#if !defined TIZEN_EXT
ident = __vpn_provider_create_identifier(host, domain);
+#else
+ ident = __vpn_provider_create_identifier(host, domain, name);
+#endif
DBG("ident %s", ident);
provider = __vpn_provider_lookup(ident);
goto fail;
}
+#if !defined TIZEN_EXT
ident = __vpn_provider_create_identifier(host, domain);
+#else
+ ident = __vpn_provider_create_identifier(host, domain, name);
+#endif
DBG("ident %s", ident);
provider = __vpn_provider_lookup(ident);
void *user_data);
int (*disconnect) (struct vpn_provider *provider);
int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
+ int (*set_state)(struct vpn_provider *provider,
+ enum vpn_provider_state state);
};
int vpn_provider_driver_register(struct vpn_provider_driver *driver);